ractivejs / ractive-load

Import templates and components using AJAX
ractivejs.github.io/ractive-load
MIT License
55 stars 10 forks source link

`style` elements don't work with decorators #26

Closed Crisfole closed 9 years ago

Crisfole commented 9 years ago

So I'm not using it exactly like a decorator, but the following component doesn't get the CodeMirror portion correctly styled (it's significantly dumbed down, fyi, many many edge cases not covered):

<textarea value='val'></textarea>
<style>
  .CodeMirror {
    border: 1px solid #ddd;
    border-width: 1px 0;
  }
</style>
<script>
  var CodeMirror = require('CodeMirror');
  component.exports = {
    onrender: function() {
      var mirror = CodeMirror.fromTextArea(this.find('textarea'), this.get('config'));
      mirror.on('change', function() { this.set('val', mirror.getValue(); });
      this.observe('val', function(newVal) { mirror.setValue(newVal); });
    }
  };
</script>

The data attributes aren't correctly applied to the dynamically added pieces. I imagine this would work the same w/ decorators.

My suggestion would be to allow components to define a 'styleTag'. If it's defined the component gets wrapped by a tag with the data-ractive-css='{{x}}' attribute instead of adding the data-ractive to all the tags in the component.

It could look like this:

<textarea value="{{val}}"></textarea>
...
<script>
  component.exports = {
    styleTag: "div",
    onrender: ...
  };
</script>

When rendered this would show up on your page:

<div data-ractive-css='{{1}}'><textarea></textarea></div>

and

[data-ractive-css='{{1}}'] .CodeMirror {
  border: 1px solid #ddd;
  border-width: 1px 0;
}

in the appended style element.

This would mean that the styles would be correctly applied. It would also be backward compatible since it's opt-in. It would also make processing the html faster in this case (no iterating over the template's nodes. Just wrap the whole thing and keep going).

MartinKolarik commented 9 years ago

data-ractive-css is added only to top-level elements, which means you can just wrap the textarea yourself. See http://jsfiddle.net/wbk6u3wn/

martypdx commented 9 years ago

I think @MartinKolarik has a good point that it's better to add the actual wrapper tag to the template then to set an option about adding a wrapper tag to the template.

Crisfole commented 9 years ago

That makes a lot more sense. Thanks.