Components: Why are some attribute selectors dash-cased?

Created on 30 Aug 2017  路  4Comments  路  Source: angular/components

Bug, feature request, or proposal:

MdButtonDirective should have an [mdButton] select. As of version beta.10, all dash-cased directives are deprecated in favour of their camelCased equivalents.

What is the expected behavior?

This should give us a high-quality material button:

<button [mdButton|mdRaisedButton|mdIconButton]>Look how beautiful I am!</button>

What is the current behavior?

The mdButton selectors aren't supported yet.

Which versions of Angular, Material, OS, TypeScript, browsers are affected?

2.0.0-beta.10

Is there anything else we should know?

Everyone working on this material project is doing an outstanding job.

needs discussion

Most helpful comment

This is actually working as intended. Button, menu items, and tab-nav all use @Component.

We spent a long time discussing this internally. The rationale is that, because only one @Component can live on an element, that component "owns" the element. When assigning properties for an element, those without prefix implicitly belong to the component that owns the element. For example:

<button md-button disableRipple mdTooltip="Settings">...</button>

In this, we see that md-button is dashed, so that you know that disableRipple belongs to the md-button and not mdTooltip.

If we did make the component selector camelCase, we'd also have to prefix all of its properties as well, which gets weird. Would you expect to write mdButtonDisabled instead of just disabled?

The dash-case here also aligns more with the custom element spec, which typically uses dash-case names in the is attribute, e.g.

<button is="plastic-button">Click Me!</button>

We considered changing the selector to use is="md-button", but this would potentially conflict with browsers that do support custom elements. We could do something like md-is or ng-is, but then we're still inventing new patterns that users have to learn, which doesn't seem like any less complexity that the existing distinction.

All 4 comments

As I'm progressing with this, I ran into some more:

This is actually working as intended. Button, menu items, and tab-nav all use @Component.

We spent a long time discussing this internally. The rationale is that, because only one @Component can live on an element, that component "owns" the element. When assigning properties for an element, those without prefix implicitly belong to the component that owns the element. For example:

<button md-button disableRipple mdTooltip="Settings">...</button>

In this, we see that md-button is dashed, so that you know that disableRipple belongs to the md-button and not mdTooltip.

If we did make the component selector camelCase, we'd also have to prefix all of its properties as well, which gets weird. Would you expect to write mdButtonDisabled instead of just disabled?

The dash-case here also aligns more with the custom element spec, which typically uses dash-case names in the is attribute, e.g.

<button is="plastic-button">Click Me!</button>

We considered changing the selector to use is="md-button", but this would potentially conflict with browsers that do support custom elements. We could do something like md-is or ng-is, but then we're still inventing new patterns that users have to learn, which doesn't seem like any less complexity that the existing distinction.

Hey @jelbourn

thank you for the detailed write-up and now it definitely makes sense. I mean I fully get the reasoning behind those decisions, unfortunately it won't change the inconsistencies on the surface. E.g. I actually tried using md-tab-nav as a component (because it is one, right?) but then I actually got a compile error because the component's selector isn't md-tab-nav but [md-tab-nav], which puts it right in between two different types of things.

I think it might be helpful to have a little section/chapter on material.angular.io which discusses these exceptions, otherwise people will keep running into these cases where they try to use components as components which they can't and then file issues, like I did.

Another thing that unfortunately makes it a little more cumbersome: I now have to know the exact implementation to really know if I can use a directive/component as a component or as a directive (md-tab-nav vs [md-tab-nav]. But you're all obviously aware of that....

Documenting this is probably the best thing to do then.

Closing this as answered. Feel free to comment.

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

LoganDupont picture LoganDupont  路  3Comments

michaelb-01 picture michaelb-01  路  3Comments

crutchcorn picture crutchcorn  路  3Comments

vitaly-t picture vitaly-t  路  3Comments

theunreal picture theunreal  路  3Comments