rfcs icon indicating copy to clipboard operation
rfcs copied to clipboard

Loosen restrictions around component argument names

Open bertdeblock opened this issue 2 years ago • 6 comments

At the moment, only argument names starting with a lowercase letter are allowed. I think it would be nice if this restriction could be loosened for the following use cases:

  1. Argument names starting with an uppercase letter (passing along a component via an argument to another component):
<Foo @Bar={{component "bar"}} />
{{! foo.hbs }}
<@Bar />

The PascalCase argument name makes it clearer that we are passing along a component, and is also inline with how the component is normally invoked (<Bar />).

  1. Argument names starting with an underscore (passing along a "private" argument from a parent component to a child component):
{{! parent.hbs }}
{{yield (hash Child=(component "child" _foo="bar"))}}
{{! child.hbs }}
{{@_foo}}

The underscore makes it clearer that this argument can only come from its parent, and is not meant to be used publicly when invoking the child component.

Both cases also work in JS land:

  • this.args.Bar
  • this.args._foo

Mainly opening this issue to see if other people think this is a good idea, and to see if other uses cases are missing.

Totally up for writing the RFC myself if this turns out to be a good idea.

bertdeblock avatar Mar 03 '22 08:03 bertdeblock

The current naming convention is also not fully enforced. You can set an argument starting with an underscore using {{component _foo="bar"}} helper. You can not access it using the {{@_foo}}. But you can access it using {{this.args._foo}}`. 🤯 Using this in production at Ember Bootstrap. 🙈

jelhan avatar Mar 19 '22 22:03 jelhan

Both cases make sense to me, esp. the capital-case component name (@Wrapper={{component 'my-component'}}) is something I've personally ran into multiple times.

mydea avatar Mar 21 '22 07:03 mydea

This is also directly related to the fact that there is no syntactical restriction on component invocation in strict mode templates—basically by definition: if the name from the surrounding JS scope is available to invoke, then any legitimate JS identifier needs to be invokable. That means that <foo /> can be a legal component invocation, and passing @Foo={{bar}} should also.

chriskrycho avatar May 13 '22 13:05 chriskrycho

@chriskrycho what would an RFC for this look like? Are you able to give any pointers to @bertdeblock ?

wagenet avatar Jul 23 '22 03:07 wagenet

Wellllll, actually we might want to go the other direction. @dfreeman discovered some non-trivial issues with allowing div and friends as legal names in the context of what Glint needs to do, and notably Svelte and Vue have restrictions on names for the same reasons. I think Dan was planning to write up a related RFC; I suspect he would also be up for supporting/helping Bert doing the same.

chriskrycho avatar Jul 23 '22 13:07 chriskrycho

@bertdeblock happy to sync with you out-of-band (via Discord or whatever works for you) to work together on figuring out how this relates to the issues Chris mentioned above and whether it makes sense to join forces 🙂

dfreeman avatar Jul 25 '22 14:07 dfreeman