mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-04-16 22:24:49 +00:00
AAE-40703 Add support for content projection (#11462)
This commit is contained in:
@@ -84,6 +84,20 @@ using the `adf:` namespace.
|
||||
|
||||
The Icon Alias Mapping feature allows you to provide custom icon value mappings at runtime using the `ICON_ALIAS_MAP_TOKEN` injection token. When an icon value matches a key in the alias map, the component automatically replaces it with the mapped value. This is useful for creating consistent icon conventions across your application without modifying component code.
|
||||
|
||||
**How icon name replacement works:**
|
||||
|
||||
When you provide an alias map, the component checks if the icon value matches any key in the map. If a match is found, the icon name is replaced with the corresponding mapped value. This happens automatically and transparently:
|
||||
|
||||
- Original icon name: `icon-mock`
|
||||
- Alias map entry: `'icon-mock': 'alias-mock'`
|
||||
- Result: Icon renders as `alias-mock` instead of `icon-mock`
|
||||
|
||||
This allows you to:
|
||||
- **Rename icons** without changing component code
|
||||
- **Support legacy icon names** by mapping them to new ones
|
||||
- **Centralize icon naming conventions** in your application
|
||||
- **Create icon aliases** for shorter or more descriptive names
|
||||
|
||||
**Example alias map:**
|
||||
|
||||
```ts
|
||||
@@ -102,13 +116,36 @@ function getProviders() {
|
||||
}
|
||||
```
|
||||
|
||||
**Usage in your template:**
|
||||
### Template usage
|
||||
|
||||
The Icon Component supports two ways to provide the icon value:
|
||||
|
||||
**1. Using the `value` input property:**
|
||||
|
||||
```html
|
||||
<adf-icon value="icon-mock"></adf-icon>
|
||||
<adf-icon value="home"></adf-icon>
|
||||
<adf-icon value="alert"></adf-icon>
|
||||
<adf-icon value="adf:custom-icon"></adf-icon>
|
||||
```
|
||||
|
||||
The component will replace `icon-mock` with `alias-mock`. If the icon value doesn't match any key in the alias map, the original value is used.
|
||||
**2. Using content projection (slot):**
|
||||
|
||||
Similar to Angular Material's `mat-icon`, you can provide the icon value as text content:
|
||||
|
||||
```html
|
||||
<adf-icon>home</adf-icon>
|
||||
<adf-icon>alert</adf-icon>
|
||||
<adf-icon>adf:custom-icon</adf-icon>
|
||||
```
|
||||
|
||||
**Priority:** If both are provided, the slot content takes priority over the `value` input property:
|
||||
|
||||
```html
|
||||
<!-- Uses "home" from slot, ignores value input -->
|
||||
<adf-icon value="alert">home</adf-icon>
|
||||
```
|
||||
|
||||
This approach provides flexibility and familiarity for developers accustomed to Angular Material's icon component API.
|
||||
|
||||
## See also
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<ng-content />
|
||||
|
||||
@if (isSvg) {
|
||||
<mat-icon [color]="color" [svgIcon]="value" aria-hidden="true" />
|
||||
} @else {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Input, ViewEncapsulation, ChangeDetectionStrategy, inject } from '@angular/core';
|
||||
import { Component, Input, ViewEncapsulation, ChangeDetectionStrategy, inject, ElementRef, AfterContentInit } from '@angular/core';
|
||||
import { ThemePalette } from '@angular/material/core';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { ICON_ALIAS_MAP_TOKEN } from './icon-alias-map.token';
|
||||
@@ -30,8 +30,9 @@ export const DEFAULT_ICON_VALUE = 'settings';
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
host: { class: 'adf-icon' }
|
||||
})
|
||||
export class IconComponent {
|
||||
export class IconComponent implements AfterContentInit {
|
||||
private readonly ALIAS_MAP = inject(ICON_ALIAS_MAP_TOKEN, { optional: true });
|
||||
private readonly elementRef = inject(ElementRef);
|
||||
|
||||
private _value = DEFAULT_ICON_VALUE;
|
||||
private _isSvg = false;
|
||||
@@ -65,6 +66,15 @@ export class IconComponent {
|
||||
this._isSvg = isSvg;
|
||||
}
|
||||
|
||||
ngAfterContentInit(): void {
|
||||
const textNode = this.getTextNode();
|
||||
|
||||
if (textNode) {
|
||||
this.value = textNode.textContent.trim();
|
||||
textNode.remove();
|
||||
}
|
||||
}
|
||||
|
||||
private hasMappedAlias(value: string): boolean {
|
||||
return !!this.ALIAS_MAP?.[value];
|
||||
}
|
||||
@@ -72,4 +82,10 @@ export class IconComponent {
|
||||
private isCustom(value: string): boolean {
|
||||
return value.includes(':');
|
||||
}
|
||||
|
||||
private getTextNode(): Text | undefined {
|
||||
return Array.from(this.elementRef.nativeElement.childNodes).find(
|
||||
(node: Node) => node.nodeType === Node.TEXT_NODE && node.textContent?.trim()
|
||||
) as Text | undefined;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user