Introduction
In previous post, we created simple collapsible card component with 0% javascript. In this post, I'm going to show an alternative way to build the same collapsible card using web components.
Web components allows us to create reusable custom elements — with their functionality encapsulated away from the rest of your code. This makes web components excellent tool build smart custom elements with built-in functionality.
Let's take the collapsible card from previous post. This "component" is missing a lot's of useful features. For example:
Web components allows us to create reusable custom elements — with their functionality encapsulated away from the rest of your code. This makes web components excellent tool build smart custom elements with built-in functionality.
Let's take the collapsible card from previous post. This "component" is missing a lot's of useful features. For example:
- What if I want to use different icons on open/close? (Sure, we can implement different custom css classes, but this this is non-scalable solution)
- What if I want to bind event handlers on various events: mouse click, card open, card close
- What if I want to dynamically load card content?
The proper and easier way to solve these problems is to use existing frameworks / component libraries: Vue.js, Angular, React, swelte. But can we achieve the same goal in plain vanilla javascript, without using any framework? The answer is yes - we should use web components.
Every custom element is a class that derives from HTMLElement interface. We can be more specific in this case and build our custom collapsible card component based on HTMLDetailsElement interface:
Every custom element is a class that derives from HTMLElement interface. We can be more specific in this case and build our custom collapsible card component based on HTMLDetailsElement interface:
class MCard extends HTMLDetailsElement { constructor() { // Always call super first in constructor super(); // Element functionality written in here ... } }
we should always call super() first in constructor()
Next, we need to build HTML structure for our component from scratch:
See the Pen Untitled by mirushaki (@mirushaki) on CodePen.
As you can see, we are using <details> and <summary> tags internally. Also, we are transferring HTML content from <m-card> to <details> tag internally. The header/title is customizable by setting the "title" HTML attribute of <m-card> tag. Finally, we are registering the component using customElements.define() function.
What about styles?
Sure, we can apply styles to our web-component. The proper way is to create <style> tag internally for each component. These styles will be fully encapsulated, because we are using shadow root. So, if we write: .p {font-size: 24px; } inside our component, it will not collide with other styles on page.
Let's expand our component by introducing some styles:
See the Pen Untitled by mirushaki (@mirushaki) on CodePen.
As you can see, now we have some customization: we can apply different icons for closed/opened state, we can apply colors for text/border and set boolean variable "open" if we want to specify "opened" state initially.
This is simple example how to use custom events with our web component. We are implementing custom "toggle" event, the web component itself handles internal "toggle" event coming from <details> tag, then creates a new toggle event with appropriate details: in this case passing "opened" value - true or false. Finally we have an event handler on custom <m-card> element that can receive "toggle" event and display appropriate alert message based on open/close state.
See the Pen Collapsible card - web component - events by mirushaki (@mirushaki) on CodePen.
Web components gives us much flexibility and customization. You can read more about web components here.
No comments:
Post a Comment