DefaultDomRenderer2 overrides custom element's class
See original GitHub issueI’m submitting a … (check one with “x”)
[x] bug report => search github for a similar issue or PR before submitting
[ ] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior Using a custom element that adds a class to itself is incompatible when setting the class in a component template.
Expected behavior Classes set in a component template should be added to the classList, instead of overriding it.
Minimal reproduction of the problem with instructions
- Create a custom element that modifies its classList in
connectedCallback()
- Use the custom element with a class attribute in a component template
View the demo in Chrome (native webcomponent support) http://plnkr.co/edit/4pzXr214xEZyUZ9ftLG7?p=preview
What is the motivation / use case for changing the behavior? Feeling the love between Angular and Polymer 2.
Specifically, the <paper-button>
element adds the .paper-material
class to its classList when attached to the DOM.
Angular first creates and attaches the element (and <paper-button>
adds its class hooray!).
Next, the function asks the renderer to set the attributes from the component markup.
In the browser, the renderer uses setAttribute()
on the element. When calling element.setAttribute('class', 'name');
, existing classes are removed.
Suggested Fix
I think it makes the most sense for DefaultDomRenderer2
to understand that setting the class attribute can have negative consequences.
export class DefaultDomRenderer2 implements Renderer2 {
...
setAttribute(el: any, name: string, value: string, namespace?: string): void {
if (namespace) {
el.setAttributeNS(NAMESPACE_URIS[namespace], namespace + ':' + name, value);
} else if (name === 'class') {
value.split(' ').forEach(className => {
el.classList.add(name, className);
});
} else {
el.setAttribute(name, value);
}
}
}
-
Angular version: 2.4.10+
-
Browser: [all]
-
Language: [TypeScript 2.0.2]
-
Node (for AoT issues):
node --version
= v6.9.5
Issue Analytics
- State:
- Created 6 years ago
- Comments:8 (4 by maintainers)
I spoke with the Polymer team about this today. They said they agreed that an element setting its own class was too easy to get stomped on and they no longer do it. While they used to set
.paper-material
in an earlier version of the 2.0 preview, they’ve switched off of that. I think the one exception is a.keyboard-focus
class left over from an a11y input modality polyfill.I think class is explicitly meant to be used by consumers, and a custom element should not modify its own classes.