I'm encountering an issue with Angular's hostDirectives
API, specifically when trying to pass values through @Input
in composed directives.
I have a standalone directive PgcTypoDirective
that applies a CSS class based on a @Input
value:
import { Directive, HostBinding, Input } from '@angular/core';
@Directive({
selector: '[pgc-typo]',
standalone: true,
})
export class PgcTypoDirective {
@Input('pgc-typo')
typography = '';
@HostBinding('class')
get className() {
return `pgc-typo--${this.typography}`;
}
}
Then, I created another directive Heading1Directive
that composes PgcTypoDirective
using the hostDirectives
API and attempts to pass a value to the pgc-typo input:
import { Directive } from '@angular/core';
@Directive({
selector: '[heading-1]',
standalone: true,
hostDirectives: [
{
directive: PgcTypoDirective,
inputs: ['pgc-typo: heading-1'],
},
],
})
export class Heading1Directive {}
Finally, I use Heading1Directive
in a component:
<h1 heading-1>
This is a Heading 1 styled text.
</h1>
Expected Behavior
I expect the PgcTypoDirective
to receive the value 'heading-1' and apply the class 'pgc-typo--heading-1' to the element.
Actual Behavior
Instead of applying the correct class, I see that the resulting class is just 'pgc-typo--', which suggests that the value 'heading-1' was not correctly passed to PgcTypoDirective.
Is this expected behavior for Angular's hostDirectives
API? Shouldn't the inputs array in hostDirectives correctly map and pass these values from Heading1Directive
to PgcTypoDirective
? Or is there a different recommended approach to ensure the correct @Input
value is passed when using directive composition?
EDIT: WORKAROUND
@Directive({
selector: '[heading-1]',
standalone: true,
hostDirectives: [PgcTypoDirective],
})
export class RtlsHeading1Directive {
readonly #pgcTypoDirective = inject(PgcTypoDirective);
constructor() {
this.#pgcTypoDirective.typography = 'heading-1';
}
}
This workaround helped me to achieve the desired outcome. 'pgc-typo--heading-1' class is applied.
<h1 heading-1>
This is a Heading 1 styled text.
</h1>
You are not providing any value to pgc-typo
.
According to the documentation and sample, "pgc-typo: heading-1" in your inputs
with "heading-1" is an alias/variable that passes the value to the pgc-typo
input variable, but not passing the "heading-1" text as value.
With alias: Make sure that you are giving value to the heading-1
attribute as below:
<h1 heading-1="heading-1">
This is a Heading 1 styled text.
</h1>
Or
Without alias: You should remove the alias to avoid confusion.
heading-1.directive.ts
@Directive({
selector: '[heading-1]',
standalone: true,
hostDirectives: [
{
directive: PgcTypoDirective,
inputs: ['pgc-typo'],
},
],
})
export class Heading1Directive {}
<h1 pgc-typo="heading-1">
This is a Heading 1 styled text.
</h1>