GithubHelp home page GithubHelp logo

bwalker8038 / ember-render-modifiers Goto Github PK

View Code? Open in Web Editor NEW

This project forked from emberjs/ember-render-modifiers

0.0 2.0 0.0 291 KB

Implements did-insert / did-update / will-destroy modifiers for emberjs/rfcs#415

License: MIT License

JavaScript 90.30% HTML 9.70%

ember-render-modifiers's Introduction

@ember/render-modifiers

Provides element modifiers that can be used to hook into specific portions of the rendering lifecycle.

Compatibility

  • Ember.js v2.18 or above
  • Ember CLI v2.13 or above

Installation

ember install @ember/render-modifiers

Usage Examples

Example: Scrolling an element to a position

This sets the scroll position of an element, and updates it whenever the scroll position changes.

Before:

{{yield}}
export default Component.extend({
  classNames: ['scroll-container'],

  didRender() {
    this.element.scrollTop = this.scrollPosition;
  }
});

After:

<div
  {{did-insert this.setScrollPosition @scrollPosition}}
  {{did-update this.setScrollPosition @scrollPosition}}

  class="scroll-container"
>
  {{yield}}
</div>
export default class Component.extend({
  setScrollPosition(element, [scrollPosition]) {
    element.scrollTop = scrollPosition;
  }
})

Example: Adding a class to an element after render for CSS animations

This adds a CSS class to an alert element in a conditional whenever it renders to fade it in, which is a bit of an extra hoop. For CSS transitions to work, we need to append the element without the class, then add the class after it has been appended.

Before:

{{#if this.shouldShow}}
  <div class="alert">
    {{yield}}
  </div>
{{/if}}
export default Component.extend({
  didRender() {
    let alert = this.element.querySelector('.alert');

    if (alert) {
      alert.classList.add('fade-in');
    }
  }
});

After:

{{#if this.shouldShow}}
  <div {{did-insert this.fadeIn}} class="alert">
    {{yield}}
  </div>
{{/if}}
export default Component.extend({
  fadeIn(element) {
    element.classList.add('fade-in');
  }
});

Example: Resizing text area

One key thing to know about {{did-update}} is it will not rerun whenever the contents or attributes on the element change. For instance, {{did-update}} will not rerun when @type changes here:

<div {{did-update this.setupType}} class="{{@type}}"></div>

If {{did-update}} should rerun whenever a value changes, the value should be passed as a parameter to the modifier. For instance, a textarea which wants to resize itself to fit text whenever the text is modified could be setup like this:

<textarea {{did-update this.resizeArea @text}}>
  {{@text}}
</textarea>
export default Component.extend({
  resizeArea(element) {
    element.style.height = `${element.scrollHeight}px`;
  }
});

Example: ember-composability-tools style rendering

This is the type of rendering done by libraries like ember-leaflet, which use components to control the rendering of the library, but without any templates themselves. The underlying library for this is here. This is a simplified example of how you could accomplish this with Glimmer components and element modifiers.

Node component:

// components/node.js
export default Component.extend({
  init() {
    super(...arguments);
    this.children = new Set();

    this.parent.registerChild(this);
  }

  willDestroy() {
    super(...arguments);

    this.parent.unregisterChild(this);
  }

  registerChild(child) {
    this.children.add(child);
  }

  unregisterChild(child) {
    this.children.delete(child);
  }

  didInsertNode(element) {
    // library setup code goes here

    this.children.forEach(c => c.didInsertNode(element));
  }

  willDestroyNode(element) {
    // library teardown code goes here

    this.children.forEach(c => c.willDestroyNode(element));
  }
}
<!-- components/node.hbs -->
{{yield (component "node" parent=this)}}

Root component:

// components/root.js
import NodeComponent from './node.js';

export default NodeComponent.extend();
<!-- components/root.hbs -->
<div
  {{did-insert (action this.didInsertNode)}}
  {{will-destroy (action this.willDestroyNode)}}
>
  {{yield (component "node" parent=this)}}
</div>

Usage:

<Root as |node|>
  <node as |node|>
    <node />
  </node>
</Root>

License

This project is licensed under the MIT License.

ember-render-modifiers's People

Contributors

ember-tomster avatar gavinjoyce avatar knownasilya avatar rwjblue avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.