ember-polyfills / ember-angle-bracket-invocation-polyfill

MIT License
76 stars 33 forks source link

Single word components, path components #27

Closed samselikoff closed 6 years ago

samselikoff commented 6 years ago

Amazing work! 🎉

We use a lot of "presenter" components, and they look like this:

{{#ui-title}}Hello, world!{{/ui-title}}

{{ui-spacer}}

{{#ui-container}}
  <h1>Welcome to our page.</h1>
{{/ui-container}}

I'm trying to experiment and figure out the best API for these kind of components in an angle-bracket world.

Same name

Keeping the same name makes the above template

<UiTitle>Hello, world!</UiTitle>

<UiSpacer>

<UiContainer>
  <h1>Welcome to our page.</h1>
</UiContainer>

which is ok, but the Ui prefix feels really noisy, and not sufficiently separated from the name of the component. Makes the template a bit hard to read.

Single word components

I think if we had single word components, we'd use those for presenters:

<Title>Hello, world!</Title>

<Spacer>

<Container>
  <h1>Welcome to our page.</h1>
</Container>

Looks gorg 😍

Path components

Is there an alternative using paths? I'm not sure how path components work in angle-bracket world.

<UI/Title>Hello, world!<UI/Title>

<UI/Spacer>

<UI/Container>
  <h1>Welcome to our page.</h1>
<UI/Container>

What about dot-paths, are those only supported inside of a contextual component?

<UI.Title>Hello, world!<UI.Title>

<UI.Spacer>

<UI.Container>
  <h1>Welcome to our page.</h1>
<UI.Container>

or with a lower-cased ui:

<ui.Title>Hello, world!<ui.Title>

<ui.Spacer>

<ui.Container>
  <h1>Welcome to our page.</h1>
<ui.Container>

What do you think? We're keen to try this out and start experimenting with good patterns for future Ember!

rwjblue commented 6 years ago

Is there an alternative using paths? I'm not sure how path components work in angle-bracket world.

Paths are not an option, the RFC states this:

Second, while Handlebars technically allows {{foo/bar}} as an equivilant alternative to the {{foo.bar}} path lookup (and therefore foo/bar is technically a valid Handlebars path expression), it will not be supported in angle bracket invocation. This is both because the / conflicts with the HTML closing tag syntax, and the fact that Ember overrides that syntax with a different semantic.

In today's semantics, {{foo/bar}} does not try to lookup this.foo.bar and invoke it as a component. Instead, it is used as a filesystem scoping syntax. Since this feature will be rendered unnecessary with Module Unification, we recommend apps using "slash components" to migrate to alternatives provided by Module Unification (or, alternatively, keep using curly invocations for this purpose).

rwjblue commented 6 years ago

I think if we had single word components, we'd use those for presenters:

<Title>Hello, world!</Title>

<Spacer />

<Container>
  <h1>Welcome to our page.</h1>
</Container>

Yep, I agree that this is really nice. This works already when using canary versions of ember-source, but I haven't figured out how the polyfill could work around the assertion in Ember's prior to 3.4.

rwjblue commented 6 years ago

I don't think you should do this (I like the one word version better), but another option is:

<Ui-Title>Hello, world!</Ui-Title>

<Ui-Spacer />

<Ui-Container>
  <h1>Welcome to our page.</h1>
</Ui-Container>
samselikoff commented 6 years ago

How would <Ui-Title> look on disk?

If one-word is the future and it just doesn't work pre-3.4, it's probably not worth spending too much effort discussing here. That's definitely what we'll use.

rwjblue commented 6 years ago

If one-word is the future and it just doesn't work pre-3.4, it's probably not worth spending too much effort discussing here.

Well, this addon is all about making the future available now 😉...

rwjblue commented 6 years ago

How would look on disk?

Same place you are likely using now for {{ui-title}}: app/components/ui-title.js

samselikoff commented 6 years ago

Interesting, so the - in the name doesn't affect the lookup?

samselikoff commented 6 years ago

Well, this addon is all about making the future available now 😉...

Aye, good point. Any ideas for hacking around the assertion, or ways I could help figure that out? Maybe someone to reach out to?

rwjblue commented 6 years ago

The dasherization that is used here is slightly different than Ember.String.dasherize, it is basically:

https://github.com/rwjblue/ember-angle-bracket-invocation-polyfill/blob/60db162aa6463cc6f734128cd6e0dec99db1b9a4/lib/ast-transform.js#L20-L28

Some tests (from Ember's test suite) for this show expected inputs/outputs:

  function equals(input, expected) {
    QUnit.test(`${input} -> ${expected}`, function(assert) {
      assert.equal(COMPONENT_NAME_SIMPLE_DASHERIZE_CACHE.get(input), expected);
    });
  }

  equals('Foo', 'foo');
  equals('foo-bar', 'foo-bar');
  equals('FooBar', 'foo-bar');
  equals('XBlah', 'x-blah');
  equals('X-Blah', 'x-blah');
  equals('Foo::BarBaz', 'foo::bar-baz');
  equals('Foo::Bar-Baz', 'foo::bar-baz');
  equals('Foo@BarBaz', 'foo@bar-baz');
  equals('Foo@Bar-Baz', 'foo@bar-baz');
rwjblue commented 6 years ago

Aye, good point. Any ideas for hacking around the assertion, or ways I could help figure that out? Maybe someone to reach out to?

I think a good first step is to get together a failing test PR. Something like this test (but using a one word component) should do the trick:

https://github.com/rwjblue/ember-angle-bracket-invocation-polyfill/blob/60db162aa6463cc6f734128cd6e0dec99db1b9a4/tests/integration/components/angle-bracket-invocation-test.js#L22-L28

From there we need to track down which assertion in Ember is actually being fired, and figure out how to hack it off 👿

knownasilya commented 6 years ago

In the MU world I'd go with

{{use Title, Spacer, Container from 'ui'}}

<Title>
  Title
</Title>

<Spacer />

<Container>
  content
</Container>

Where 'ui' is in packages/ui.

rwjblue commented 6 years ago

In the MU world I'd go with

FWIW, this is still wildly in flux (the RFC update is not completed, and the WIP is somewhat incoherent still).

knownasilya commented 6 years ago

Yeah, just thought since we are talking about the future 😉

rwjblue commented 6 years ago

Totally, but I can't reason about the MU changes yet (I've tried a lot and failed miserably), I need more details (e.g. the actual RFC update to be completed).

rwjblue commented 6 years ago

34 should address this