Day 93: Web components
Tags: webdev, frontend, 100daysofcode, webcomponents
Published: 2023-11-22 17:00:00

Web development has evolved significantly over the years, with a constant quest for more modular, reusable, and maintainable code. Web Components provides a set of web platform APIs that enable the creation of custom, reusable, and encapsulated HTML elements. 

### HTML Templates 🎨

HTML Templates are the foundation of Web Components, providing a way to declare fragments of markup that can be cloned and inserted into the document later. This helps in creating modular and reusable pieces of UI.

```html
<template id="my-template">
  <style>
    /* Styles specific to this template */
  </style>
  <div class="component">
    <p>Hello, <slot></slot>!</p>
  </div>
</template>
```

Here, we've defined a template with a placeholder (`<slot></slot>`) that can be filled with content when the template is used. 

```html
<script>
  const template = document.getElementById('my-template');
  const clone = document.importNode(template.content, true);
  clone.querySelector('slot').textContent = 'World';
  document.body.appendChild(clone);
</script>
```

### Custom Elements 🚀

Custom Elements allow developers to create their own HTML elements with custom behavior. They encapsulate functionality, making it easy to reuse and share across different projects. 

```javascript
class MyComponent extends HTMLElement {
  constructor() {
    super();

    const shadowRoot = this.attachShadow({ mode: 'open' });

    // Use the template directly within the class
    shadowRoot.innerHTML = `
      <style>
        p {
          color: #3498db;
        }
      </style>
      <p>Hello, <slot></slot>!</p>
    `;
  }
}

customElements.define('my-component', MyComponent);
```

Now, you can use `<my-component>` in your HTML:

```html
<my-component></my-component>
```

### Shadow DOM 🔍

Shadow DOM provides encapsulation for your web components, shielding their styles and structure from the rest of the document. This ensures that styles and scripts in your component do not interfere with the rest of the page. 

```javascript
class MyComponent extends HTMLElement {
  constructor() {
    super();

    // Attach a shadow DOM to encapsulate styles and structure
    const shadowRoot = this.attachShadow({ mode: 'open' });

    shadowRoot.innerHTML = `
      <style>
        p {
          color: #3498db;
        }
      </style>
      <p>Hello, <slot></slot>!</p>
    `;
  }
}

customElements.define('my-component', MyComponent);
```

### Tips  💡

1. **Keep it modular:** Break down complex UIs into smaller, manageable components to maximize reusability.
2. **Use Shadow DOM judiciously:** Leverage Shadow DOM to encapsulate styles and scripts, preventing unintended interference.
3. **Explore component libraries:** Many libraries, such as LitElement and Stencil, simplify the creation and management of Web Components.
4. **Events**: Use Custom Events to establish communication between Web Components, enabling a more modular architecture.
5. **Lifecycle Hooks**: Implement lifecycle hooks (e.g., `connectedCallback`, `disconnectedCallback`) to perform actions when a component is added or removed from the DOM.


### Usage 🌐

Web Components find extensive use in various scenarios, from UI libraries to large-scale applications. 

- **UI Libraries:** Build modular UI components that can be easily shared and reused across projects.
- **Micro-frontends:** Use Web Components to create self-contained, independently deployable parts of a larger application.
- **Third-Party Integration:** Develop widgets or components that can be embedded seamlessly into other websites.