# Component

Table of Contents
Constructor
Requirements
Attributes
Properties
Methods

### Description

`Component` is an Web Component (JS Class) from which all Kempo components are created, it handles the creation of the Shadow DOM from the shadowTemplate and shadowStyles, along with creating utility methods for creating attributes and methods.

### Requirements

- getCase Utility Function

### Constructor

###### Extends HTMLElement

##### `super()`
`super(Object shadowOptions)`

This class can not be instatiated directly, but rather should be extended, optionally passing in the shadowOptions.

    import Component from 'kempo';
    class MyComponent extends Component {
      constructor(){
        super();
        // Your Constructor
      }
    }
    window.customElements.define('my-component', MyComponent);

### Attributes

##### `rendered` Boolean

A READ ONLY boolean that indicates if this element has been rendered.

### Properties

##### `shadowTemplate` String

A string of HTML that is used to render the markup of the component. This should be overwritten in your component with your own markup, but make sure to use the `super.shadowTemplate` to get the default slot.

    import Component from 'kempo';
    class MyComponent extends Component {
      /* Other things */
      get shadowTemplate(){
        return /*html*/`
          ${super.shadowTemplate}
          <p>This is my component</p>
        `;
      }
    }
    window.customElements.define('my-component', MyComponent);

##### `shadowStyles` String

A string of CSS that styles the Shadow DOM (from the `shadowTemplate`).

    import Component from 'kempo';
    class MyComponent extends Component {
      /* Other things */
      get shadowStyles(){
        return /*css*/`
          :host {
            /* Style this element */
          }
          p {
            /* Style Shadow DOM Elements */
          }
        `;
      }
    }
    window.customElements.define('my-component', MyComponent);

### Methods

##### `async render(Boolean force = false)`

This method renders the Shadow DOM if it has not already been rendered, and sets the `rendered` attribute to `true`.

This should be overwritten in your component with your own function, but make sure to use the `super.render(force)` to render the Shadow DOM.

    import Component from 'kempo';
    class MyComponent extends Component {
      async render(force){
        if(await super.render(force)){
          /* The Shadow DOM is ready, do your stuff here
            This is often attaching event handlers to Shadow DOM elements
          */
          return true;
        }
        return false;
      }
    }
    window.customElements.define('my-component', MyComponent);

##### `registerAttribute(String name, Any defaultValue = '')`

This method creates an attribute (dash case), that can also be accessed as a member with camel case. This is typically done in the constructor.

    import Component from 'kempo';
    class MyComponent extends Component {
      constructor(){
        super();
        this.registerAttribute('my-att', 'hello');
        // this can now be accessed by using this.myAtt
      }
    }
    window.customElements.define('my-component', MyComponent);

##### `registerAttributes(Object attributes)`

This is the same as `registerAttribute`, except it takes the attributes as key-value-pairs allowing you to register multiple attributes at once.

    import Component from 'kempo';
    class MyComponent extends Component {
      constructor(){
        super();
        this.registerAttributes({
          'myAttr1': 'value1',
          'myAttr2': 'value2'
        });
        // this can now be accessed by using this.myAttr1 and this.myAttr2
      }
    }
    window.customElements.define('my-component', MyComponent);

##### `registerProp(String name, Any defaultValue)`

This method creates a property. This is typically done in the constructor.

    import Component from 'kempo';
    class MyComponent extends Component {
      constructor(){
        super();
        this.registerProp('myProp', ['foo', 'bar']);
        // this can now be accessed by using this.myProp
      }
    }
    window.customElements.define('my-component', MyComponent);

##### `registerProps(Object properties)`

This is the same as `registerProp`, except it takes the props as key-value-pairs allowing you to register multiple props at once.

    import Component from 'kempo';
    class MyComponent extends Component {
      constructor(){
        super();
        this.registerProps({
          myProp1: ['foo', 'bar'],
          myProp2: 5
        });
        // these props can now be accessed by using this.myProp1 and this.myProp2
      }
    }
    window.customElements.define('my-component', MyComponent);