Project Red Pill
Tags: javascript, github
Published: 2021-05-01 16:54:20

For the final project in IST 402, I created my very own web component. I took an issue ELMNSln and got to work. 

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zyr1351w0rcga34jtmmi.png)
 
 
###Step I: Assess the task
So the goal was to create a reusable web comment to promote a product. This web component needed to support [Lazy Loading](https://developer.mozilla.org/en-US/docs/Web/Performance/Lazy_loading), [Slots](https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_templates_and_slots), and user customization using props. Originally I tried to use [wcfactory](https://github.com/elmsln/WCFactory) to create the skeleton for my web component but the tooling is currently not compatible with windows. So I had to use the backup.... open w-c. 

###Step II: Building the Skeleton 
I used open w-c to start my web component. Open w-c can be used to create a boilerplate template that developers can start building on. Features you can add to your scaffolding include Linting, Testing, Demoing, and Building. I choose to add all of these upgrades to my web component. 

When I actually started coding my goal was to create something that looked like the inspiration and work backward from there. 


###Step III: Realize you are doing everything wrong
Originally I had a grid inside my web components and 4 of everything... title, picture, description, etc. 

Repitiion = Bad 

###Step IV: Finish 
To finish my web component I implemented the underlining of the first word, set the description to a slot, and change icon and color sources to more acceptable places for this particular project. 

During class, my professor was able to help me figure out how to underline only the first word in the title. We used the updated method and passed changed properties. The algorithm checks to see if the prop name is the title. Then if it is title it checks to see if when the title is split by spaces there is more than 1 output. Finally using temp variables and the split, shift, and join functions split the title into the first word and the rest of the words. 

To support the design pattern lazy loading I extended the IntersectionObserverMixin class from ELMNS. [(Check it out here).](https://github.com/elmsln/lrnwebcomponents/tree/master/elements/intersection-element) Within my own code, all I had to do was make sure I import it, extend it, and conditionally render my HTML based on if the element is visible using a property from the IntersectionObserverMixin called `elementVisable`.

In the final product, the user is able to update the title, image, accent color, icon, and description for their product offering. The description can be an actual HTML element because the description is a slot in the actual .js file.  

This was an awesome learning experience for me to build something from start to finish, and problem solve along the way. 

Here is an example of what my web components look like in the browser and a few snippets of code. 
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/43skplq94s0pl0xcq11d.png)

###The webcomponet 

```javascript 
static get properties() {
    let props = {};
    if (super.properties) {
      props = super.properties;
    }
    return {
      ...props,
      title: { type: String },
      description: { type: String },
      source: { type: String },
      icon: { type: String },
      _titleOne: { type: String },
      _titleTwo: { type: String },
    };
  }

  constructor() {
    super();
    this.alt = '';
    this.accentColor = 'pink';
    this.dark = false;
  }

  updated(changedProperties) {
    if (super.updated) {
      super.updated(changedProperties);
    }
    changedProperties.forEach((oldValue, propName) => {
      if (propName === 'title') {
        if (this.title.split(' ').length > 1) {
          const tmp = this.title.split(' ');
          this._titleOne = tmp.shift();
          this._titleTwo = tmp.join(' ');
        } else {
          this._titleOne = this.title;
        }
      }
    });
  }

  render() {
    return html`
      ${this.elementVisible
        ? html` <!-- Container -->
            <div class="container">
              <img
                class="image"
                src="${this.source}"
                alt="${this.alt}"
                height="150px"
                width="200px"
              />

              <div class="square">
                <!-- Icon, Header -->
                <div class="squareTitle">
                  <!-- icon -->
                  <div class="icon-background">
                    <simple-icon
                      id="simple-icon"
                      accent-color="${this.accentColor}"
                      ?dark="${this.dark}"
                      icon="${this.icon}"
                    ></simple-icon>
                  </div>
                  <!-- header -->
                  <h4>
                    <span class="underline">${this._titleOne}</span>&nbsp;<span
                      >${this._titleTwo}</span
                    >
                  </h4>
                </div>

                <!-- descripton -->
                <div class="sqaureDescription">
                  <slot name="description">${this.description}</slot>
                </div>
              </div>
            </div>`
        : ``}
    `;
  }
}

```

###Demo page

```html 
<div id="grid-container">
    <product-offering 
      source="../assets/Images/placeholder1.jpeg" 
      title="Real-world projects from industry experts" 
      accent-color = "cyan"
      description="With real world projects and immersive content built in partnership with top tier companies, you’ll master the tech skills companies want."
      icon="communication:business"
      >
      <div slot="description">With real world projects and immersive content <b>built in partnership with top tier companies, </b> you’ll master the tech skills companies want.</div>
    </product-offering>

    <product-offering 
      source="../assets/Images/placeholder2.jpeg" 
      title="Technical mentor support" 
      icon = "social:group" 
      accent-color="pink"
      description="With real world projects and immersive content built in partnership with top tier companies, you’ll master the tech skills companies want."
    >
      <div slot="description">Our knowledgeable mentors guide your learning and are focused on answering your questions, motivating you and keeping you on track.</div>
    </product-offering>

    <product-offering 
      source="../assets/Images/placeholder3.jpeg" 
      title="Career services" 
      icon = "image:wb-incandescent" 
      description="With real world projects and immersive content built in partnership with top tier companies, you’ll master the tech skills companies want."
      accent-color="green"
      >
      <div slot="description">You’ll have access to resume support, Github portfolio review and LinkedIn profile optimization to help you advance your career and land a high-paying role.</div>
    </product-offering>

    <product-offering 
      source="../assets/Images/placeholder4.jpeg" 
      title="Flexible learning program" 
      icon = "timeline"  
      description="With real world projects and immersive content built in partnership with top tier companies, you’ll master the tech skills companies want."
      accent-color= "blue"
      >
      <div slot="description">Get a custom learning plan tailored to fit your busy life. Learn at your own pace and reach your personal goals on the schedule that works best for you.</div>
    </product-offering>
</div>


```