machty / emblem.js

Emblem.js - Ember-friendly, indented syntax alternative for Handlebars.js
http://emblemjs.com
MIT License
1.04k stars 81 forks source link

Allow component tags to take chained classes and id #228

Open ahnbizcad opened 9 years ago

ahnbizcad commented 9 years ago

TL;DR: This is a feature suggestion: Allow this syntax my-component.class#id


A vanilla html tag can take classes and id with this syntax

div.class#id

But components, which require a - in the "custom tag" name can't

my-component.class#id

throws an error.


Currently, you have to / can do something like this

my-component class="class" id="id"

What would be the challenges, conflicts, or issues around allowing the more intuitive, uniform syntax?


Currently, this (a component with a class, id, an action string to be sent to the heirarchy, and a variable passed in):

theory-button class="clickable" id="clickable" isGeneral=isGeneral action="toggleGeneral"

results in:

<div id="clickable" class="ember-view clickable"></div>


And this (a vanilla HTML tag with the same additions):

div class="clickable" id="clickable" isGeneral=isGeneral action="toggleGeneral"

results in:

<div id="clickable" action="toggleGeneral" class="clickable" isgeneral="false"></div>

In short, the same syntax behaves vastly differently when the tag is a component, rather than a vanilla HTML tag. As a component, none of the "attribute definition" shows up in the rendered HTML, unles made to do so under the hood. As a vanilla HTML tag, "attribute definition" is treated as HTML attributes, and thus shows up in the rendered HTML. And that's all fine and understandable, since we pass things into components when using ember, while vanilla HTML elements do not/cannot take any parameters or attributes.

But this, to my understanding, shouldn't necessitate of conflict with the convenient component-or-element.class#id style of syntax.

One reason I can think of for disallowing the convenient syntax on components would be to allow for component names with . or # as the tag name. but including those characters in component names seems to be quite bad naming practice anyway.

Any "attribute definitions" such as action="myAction" or randomString=someControllerVariable following a component call is detected, and has code to process it under the hood anyway (that may be an ember thing rather than an emblem or hbs thing). So wouldn't implementing a simple string parse operation to detect any . or # characters, if any, after a component call work just fine to enable the convenient syntax, and eliminate having to do the inconsistent and more verbose class="my-class"?

alexparker commented 5 years ago

This has been on my mind lately as well. Would love this. Great issue write-up

thec0keman commented 5 years ago

:+1: This is a cool idea

kjhangiani commented 5 years ago

How would this work with contextual components? A yielded hash that contains components are accessed via the . operator.

For example

= x-select as |xs| 
  each options as |option|
    = xs.option value=option

Would that cause issues confusing the contextual component with a class?

I do wish this existed though, the ergonomics would be great. The contextual case is where it might get tricky.

alexparker commented 5 years ago

@kjhangiani i'm not sure how the underlying parsing works or might work for your example, but from a dev experience i imagine that a harder distinction would need to be drawn so that angle brackets are default for this type

x-select.this-would-be-a-css-class as |xs|
  = each options as |option|
    = xs.option value=option

where = thing represents rendering a helper or value and part-part would represent a custom component.

I dunno though, just brainstorming

thec0keman commented 5 years ago

While doing some work on the docs I discovered this already exists!

= my-component .foo#bar

output

There are a couple of limitations: