# ShoutUI

ShoutUI is a very light weight webcomponent library. It developed as part of a project to develop a new Chat interface engine for Nuance Chat framework. ShoutUI is tailored to the needs of a Chat Application, with resuable components and directives

### Custom Elements

Custom Element creates reusable element by specifying a tagName.

Custom Elements can be reused in injecting to dom.

                      const template = `
                        Testing {this.index}
                      `;

                      const TitleBar = {
                        tagName: "messaging-top-bar",
                        template: template,
                        created() {
                      }
                      data: {
                        index:1
                      }
                    }
                    ShoutUI(TitleBar);

### Inline Elements

Allows to turn a existing element in the dom to reactive.

Inline elements cannot be reused

                      const TitleBar = {
                        el: `#root`,
                        data: {
                          name: ''
                        }
                      }

                    <div id="root">
                      <div>Name: {this.name}</div>

                      <div>Enter name: <input type="text" @bind="name"></div>
                    </div>

                    ShoutUI(TitleBar);

### Data Binding

Exressions are place within {...} and are updated when changed. Making custom elements reactive

                      const template = `
                        Testing {this.index}
                      `;
                      const TitleBar = {
                        tagName: "messaging-top-bar",
                        template: template,
                        created() {
                          setInterval(_=> {
                            this.data.index++;
                          }, 1000)
                        },

                        data: {
                           index:1
                        }
                    }
                    ShoutUI(TitleBar);

### If/Else Conditional

:If and :else directives are used to do condionals in templates

                         const template = `
                          <span :if="this.index % 2 === 0">This Even</span>
                          <span :else>This Odd</span>
                        `;
                      const TitleBar = {
                        tagName: "messaging-top-bar",
                        template: template,
                        created() {
                          setInterval(_=> {
                            this.data.index++;
                          }, 1000)
                        },

                        data: {
                           index:1
                        }
                    }
                    ShoutUI(TitleBar);

### For loop

:for directive can loop through the given array. each item in the array will be available in the loop context

                         const template = `
                         <span :for="item in this.items">{item.text}</span>
                        `;
                      const TitleBar = {
                        tagName: "messaging-top-bar",
                        template: template,
                        created() {
                          setInterval(_=> {
                            this.data.index++;
                          }, 1000)
                        },

                        data: {
                           items:[
                              "one",
                              "two"
                              "three"
                           ]
                        }
                    }
                    ShoutUI(TitleBar);

### Event Listeners

To create an event listener, use @$event-name as an attribute in the element

                         const template = `
                         <input type="text" placeholder="{this.placeholder || 'Type your messsage...'}" :style="this.inputStyles" @focus="onInputFocus" @blur="onInputBlurred"  @keypress="onKeyPress"
                   @keyup="onKeyUp"
                   @input="onInput"
                   @paste="onPaste"/>
                        `;

                      const TitleBar = {
                        tagName: "messaging-top-bar",
                        template: template,
                        created() {
                          setInterval(_=> {
                            this.data.index++;
                          }, 1000)
                        },
                        onInputFocus() {

                        },
                        onKeyUp() {

                        },
                        onInput() {

                        },
                        onPaste() {

                        },
                        data: {
                           placeholder:""
                        }
                    }

                    ShoutUI(TitleBar);

### Two Way Data Binding

Allows to register input that are reflective from either side

                      const TitleBar = {
                        el: `#root`,
                        data: {
                          name: ''
                        }
                      }

                    <div id="root">
                      <div>Name: {this.name}</div>

                      <div>Enter name: <input type="text" @bind="name"></div>
                    </div>

                    ShoutUI(TitleBar);

### Lifecycle

Lifecycle gives some hooks on the custom element

                     const TitleBar =  {
                    template,
                    tagName: `my-counter`,
                    created() {
                      // runs once, when the element is added
                    },
                    updated() {
                      // run each time the dom is updated from the data
                    },
                    removed() {
                      // when the element is removed from the page
                    }

                    ShoutUI(TitleBar);

### Configuring Components

Following properties can be used to configure the components

- ##### el

  Used mainly for inline elements, Dom element identified with the el property is queried and innerHTML of this element is used as template. ShoutUI turns this element and its childrens to reactive

- ##### tagName

  Name of the reusable custom element.

- ##### data

  Data object holds the component state also the model for this component, all the properties in the data object are watched for changes. When the data changes component react and rerender.

- ##### template

  HTML string that will be rendered within a custom element, template can have other custom element within it.

### Context Properties

Following properties are available in life cycle methods or custom methods

- ##### this.el

  Root element of the component

- ##### this.data

  Access to component reactive model data. you can set ,update or delete, component will do the re rendering

- ##### this.prop

  Attribute properties that are set during initialization

### Directives

Following properties are available in life cycle methods or custom methods

- ##### :if and :else

  Can be used to conditionally add or remove the elements. :else directive can be used as else block for :if directive

- ##### :for

  Can be used to iterate over a list of items.

- ##### :class

  Allows to conditionally toggle class names. Seperate each class condition with a semi-colon.
  :class="classA: this.x === y; classB: this.z > 5"

- ##### :style

  Allows to set inline style dynamically, <div :style="this.myStyle"></div>

### Template

Template allows you bind rendered Dom to the instance data

- ##### Interpolation

  Single brace {...} interpolation code dynamically bind to the data object properties and attribute properties of the custom element

                  {
                    el: '#root',
                    data: {
                      name: 'Litedom'
                    },
                    created() {
                      // Dynamically added
                      this.data.todaysDate = new Date().toLocaleString();
                    }
                  }

                  <div id="root">
                    <p>Hello {this.name}</p>
                    <p>Date: {this.todaysDate}</p>
                  </div>

- ##### :for

  Can be used to iterate over a list of items.

- ##### this

  'this' in template indicate the root context of the component

### Data

Its the object that holds component state. All data properties are reactive. when ever property is added,updated or removed it will trigger the update of DOM.
It is accessible in template and methods.
Its is dynamic , you don't have to pre define propeties during the instance setup

### Props

Props are simply attributes that were passed in the Custom Element.

                const template = `counting: {this.count}`;

                {
                  template,
                  tagName: 'my-counter',
                  data: {
                    count: 0
                  },
                  created() {
                    this.data.count = this.prop.start || 0;
                    setInterval(() => {
                      this.data.count++;
                    }, 1000)
                  }
                }

                <my-counter start=5></my-counter>

### Computed Properties

Computed state are data that will be created based on some other input, usually from the reactive data.Whenever the state is updated, the computed data will also be updated.

                 data: {
                    firstName: 'Mardix',
                    lastName: 'M.',
                    fullName: (state) => `${state.firstName} ${state.lastName}`,
                    totalChars: (state) => state.fullName.length
                  }