feat(ivy): provide support for map-based host bindings for [style] and [class] (#28246)
Up until now, `[style]` and `[class]` bindings (the map-based ones) have only worked as template bindings and have not been supported at all inside of host bindings. This patch ensures that multiple host binding sources (components and directives) all properly assign style values and merge them correctly in terms of priority. Jira: FW-882 PR Close #28246
This commit is contained in:

committed by
Miško Hevery

parent
e5861e1c79
commit
fe8301c462
@ -1062,6 +1062,84 @@ describe('compiler compliance: styling', () => {
|
||||
expectEmit(result.source, template, 'Incorrect template');
|
||||
});
|
||||
|
||||
it('should generate override instructions for only single-level styling bindings when !important is present',
|
||||
() => {
|
||||
const files = {
|
||||
app: {
|
||||
'spec.ts': `
|
||||
import {Component, NgModule, HostBinding} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'my-component',
|
||||
template: \`
|
||||
<div [style!important]="myStyleExp"
|
||||
[class!important]="myClassExp"
|
||||
[style.height!important]="myHeightExp"
|
||||
[class.bar!important]="myBarClassExp"></div>
|
||||
\`,
|
||||
host: {
|
||||
'[style!important]': 'myStyleExp',
|
||||
'[class!important]': 'myClassExp'
|
||||
}
|
||||
})
|
||||
export class MyComponent {
|
||||
@HostBinding('class.foo!important')
|
||||
myFooClassExp = true;
|
||||
|
||||
@HostBinding('style.width!important')
|
||||
myWidthExp = '100px';
|
||||
|
||||
myBarClassExp = true;
|
||||
myHeightExp = '200px';
|
||||
}
|
||||
|
||||
@NgModule({declarations: [MyComponent]})
|
||||
export class MyModule {}
|
||||
`
|
||||
}
|
||||
};
|
||||
|
||||
const template = `
|
||||
const _c2 = ["bar"];
|
||||
const _c3 = ["height"];
|
||||
…
|
||||
function MyComponent_Template(rf, ctx) {
|
||||
if (rf & 1) {
|
||||
$r3$.ɵelementStart(0, "div");
|
||||
$r3$.ɵelementStyling(_c2, _c3, $r3$.ɵdefaultStyleSanitizer);
|
||||
$r3$.ɵelementEnd();
|
||||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵelementStylingMap(0, ctx.myClassExp, ctx.myStyleExp);
|
||||
$r3$.ɵelementStyleProp(0, 0, ctx.myHeightExp, null, true);
|
||||
$r3$.ɵelementClassProp(0, 0, ctx.myBarClassExp, null, true);
|
||||
$r3$.ɵelementStylingApply(0);
|
||||
}
|
||||
},
|
||||
`;
|
||||
|
||||
const hostBindings = `
|
||||
const _c0 = ["foo"];
|
||||
const _c1 = ["width"];
|
||||
…
|
||||
hostBindings: function MyComponent_HostBindings(rf, ctx, elIndex) {
|
||||
if (rf & 1) {
|
||||
$r3$.ɵelementStyling(_c0, _c1, $r3$.ɵdefaultStyleSanitizer, ctx);
|
||||
}
|
||||
if (rf & 2) {
|
||||
$r3$.ɵelementStylingMap(elIndex, ctx.myClassExp, ctx.myStyleExp, ctx);
|
||||
$r3$.ɵelementStyleProp(elIndex, 0, ctx.myWidthExp, null, ctx, true);
|
||||
$r3$.ɵelementClassProp(elIndex, 0, ctx.myFooClassExp, ctx, true);
|
||||
$r3$.ɵelementStylingApply(elIndex, ctx);
|
||||
}
|
||||
},
|
||||
`;
|
||||
|
||||
const result = compile(files, angularFiles);
|
||||
expectEmit(result.source, hostBindings, 'Incorrect template');
|
||||
expectEmit(result.source, template, 'Incorrect template');
|
||||
});
|
||||
|
||||
it('should generate styling instructions for multiple directives that contain host binding definitions',
|
||||
() => {
|
||||
const files = {
|
||||
|
Reference in New Issue
Block a user