fix(ivy): handling className as an input properly (#33188)
Prior to this commit, all `className` inputs were not set because the runtime code assumed that the `classMap` instruction is only generated for `[class]` bindings. However the `[className]` binding also produces the same `classMap`, thus the code needs to distinguish between `class` and `className`. This commit adds extra logic to select the right input name and also throws an error in case `[class]` and `[className]` bindings are used on the same element simultaneously. PR Close #33188
This commit is contained in:

committed by
Matias Niemelä

parent
08cb2fa80f
commit
6f203c9575
@ -551,6 +551,74 @@ describe('styling', () => {
|
||||
expect(capturedMyClassBindingCount).toEqual(1);
|
||||
});
|
||||
|
||||
it('should write to a `className` input binding', () => {
|
||||
@Component({
|
||||
selector: 'comp',
|
||||
template: `{{className}}`,
|
||||
})
|
||||
class Comp {
|
||||
@Input() className: string = '';
|
||||
}
|
||||
@Component({
|
||||
template: `<comp [className]="'my-className'"></comp>`,
|
||||
})
|
||||
class App {
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [Comp, App]});
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement.firstChild.innerHTML).toBe('my-className');
|
||||
});
|
||||
|
||||
onlyInIvy('only ivy combines static and dynamic class-related attr values')
|
||||
.it('should write to a `className` input binding, when static `class` is present', () => {
|
||||
@Component({
|
||||
selector: 'comp',
|
||||
template: `{{className}}`,
|
||||
})
|
||||
class Comp {
|
||||
@Input() className: string = '';
|
||||
}
|
||||
|
||||
@Component({
|
||||
template: `<comp class="static" [className]="'my-className'"></comp>`,
|
||||
})
|
||||
class App {
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [Comp, App]});
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement.firstChild.innerHTML).toBe('static my-className');
|
||||
});
|
||||
|
||||
onlyInIvy('in Ivy [class] and [className] bindings on the same element are not allowed')
|
||||
.it('should throw an error in case [class] and [className] bindings are used on the same element',
|
||||
() => {
|
||||
@Component({
|
||||
selector: 'comp',
|
||||
template: `{{class}} - {{className}}`,
|
||||
})
|
||||
class Comp {
|
||||
@Input() class: string = '';
|
||||
@Input() className: string = '';
|
||||
}
|
||||
@Component({
|
||||
template: `<comp [class]="'my-class'" [className]="'className'"></comp>`,
|
||||
})
|
||||
class App {
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({declarations: [Comp, App]});
|
||||
expect(() => {
|
||||
const fixture = TestBed.createComponent(App);
|
||||
fixture.detectChanges();
|
||||
})
|
||||
.toThrowError(
|
||||
'[class] and [className] bindings cannot be used on the same element simultaneously');
|
||||
});
|
||||
|
||||
onlyInIvy('only ivy persists static class/style attrs with their binding counterparts')
|
||||
.it('should write to a `class` input binding if there is a static class value and there is a binding value',
|
||||
() => {
|
||||
|
Reference in New Issue
Block a user