Docs

Everything You Need to Know

Components

Extending

Because components are ES6 classes, you can extend them. You do this just as you would with any other ES6 class, using extends:

const SpecialComponent extends Component {
  // Stuff goes here.
}

In general, you shouldn't need to extend the Component class. However, there is one situation where you would want to: to reuse the same component in multiple places but with different data. For example, say you need to show three or more lists with the exact say internal layout for data, but with different data. You would need to definie a different component with the exact same template for each list -- wasteful.

By extending the Component class, you can create a class that always returns the same template, but uses different data for each instance.

How to Extend Component

To make this work, you need to modify the constructor of the original Component class when you create its extension. You want any options to get passed to the original constructor, but you want to add one new thing. Let's step back a bit and explain how a Component gets set up internally. When you create a new component, the options get assigned to properties on the class constructor. Now, when you define your component, you probably will give it a render function like this:

const comp = new Component({
  element: '#list',
  render: (data) => html`<li>${ data }</li>`
})

Internally, ChocolateChip-UI takes that function and applies it to component's constructor as the method renderFnc:

this.renderFnc = options.render

What this means is that when we extend Component, we need to directly provide a value for this method to create a cookie cutter template for our components. And here is how you might do that:

class List extends Component {
  constructor(options) {
    super(options)
    this.renderFnc = (data) => html`
      <li>
        <h3>${data}</h3>
      </li>`
  }
}

By assign the template directly to the this.renderFnc, every instance of the class will have access to the exact same template. To use it, we can then do the following:

// No need to give these components a render function.
// They will use the default of the class:
const peopleList = new List({
  element: '#peopleList',
  state: peopleState
})
peopleList.render()
const fruitList = new List({
  element: '#fruitList',
  state: fruitState
})
fruitList.render()
const petList = new List({
  element: '#petList',
  state: petState
})
petList.render()
          

In the above example, all three components will use the same template for their data. Of course, if you are going to do this, the data you use needs to match what the template expects. If the data will not match the template, you'll need to create a separate component with its own render function/template.

Below is a working Codepen example of extending Component:

See the Pen Extended Component Example V5 by Robert Biggs (@rbiggs) on CodePen.