Getting Started with Web Components: Building a Color Palette Generator

What are Web Components?

photos.map(photo => {
return (
<div className="photo">
<img src={photo.url} alt={photo.altText}/>
<h1>{photo.title}</h1>
</div>
)
})
<photo-list />

What You Should Know

Constructing the Component

create-react-app web-components
cd web-components
yarn start
import React, { Component } from "react";
import "./App.css";
class App extends Component {
render() {
return (
<div className="App">
</div>
);
}
}
export default App;
# 1
class ColorPaletteGenerator extends HTMLElement {
# 2
constructor() {
super();
}
}
# 3
window.customElements.define("palette-generator", ColorPaletteGenerator);
export default ColorPaletteGenerator;
  1. To start, we will define our new class and make it extend the HTMLElement object. This line will allow the window to render our component just like a regular div, span, or table element.
  2. The constructor of the class is where we will open up our shadow DOM, create and style our elements, and add those elements to our newly created shadow DOM to be displayed to the user.
  3. These last two lines tell the window what to call our new component and what class will be responsible for rendering the component.
import ColorScheme from "color-scheme";
generateColors() {
const scheme = new ColorScheme();
scheme
.from_hue(Math.random() * 360)
.scheme("contrast")
.variation("soft");
const colors = scheme.colors();
return colors;
}
let shadowDOM = this.attachShadow({ mode: "open" });
let paletteContainer = document.createElement("div");paletteContainer.classList.add("colorsContainer");
let paletteStyle = document.createElement("style");
const colors = this.generateColors();
// You can change this constant to however many colors you'd like
let numberOfColorsToGenerate = 5;
colors.splice(0, numberOfColorsToGenerate).forEach((color, index) => {
// # 1
let swatchDiv = document.createElement("div");
// # 2
swatchDiv.id = "colorSwatch" + index;
// # 3
swatchDiv.classList.add("colorSwatch");
// # 4
swatchDiv.innerText = `#${color}`;
// # 5
shadowDOMStyle.innerHTML += `
#${swatchDiv.id} {
background-color: #${color};
color: ${contrastingColor(color, true)};
}
`;
// # 6
paletteContainer.appendChild(swatchDiv);
});
  1. Create a div element to house our color swatch and the name of our color.
  2. Set the id of the newly created div to a custom name so we can set the background color and color of text later.
  3. Add a class to style each color the same regarding size, layout, padding, etc.
  4. Set the inner text of the div to the name of the color to display.
  5. Next, we have to add the style to our divs so the background color and text color match our color object.
  6. Finally, we need to add our newly created color div to the container so it can be displayed.
contrastingColor(hex) {
var r = parseInt(hex.slice(0, 2), 16),
g = parseInt(hex.slice(2, 4), 16),
b = parseInt(hex.slice(4, 6), 16);
return r * 0.299 + g * 0.587 + b * 0.114 > 186 ? "#000000" : "#FFFFFF";
}
paletteStyle.innerHTML += `
.colorSwatch {
height: 375px;
width: ${(1 / numberOfColorsToGenerate) * 100}%;
justify-content: center;
align-items: flex-end;
padding-bottom: 30px;
display: flex;
flex-direction: vertical;
font-size: 30px;
font-weight: bold;
}
.colorPaletteContainer {
display: flex;
flex-direction: row;
background-color: red;
width: 100%;
}
`;
shadowDOM.appendChild(paletteStyle);shadowDOM.appendChild(paletteContainer);
import "./ColorPaletteGenerator";
<div className="App">
<palette-generator />
</div>
palette-generator {
width: 100%;
}

--

--

I am a student and software developer from Texas, studying SE at UTD. I read, create websites, apps, and drone videos. Check out my projects at liam.mcmains.net

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Liam McMains

I am a student and software developer from Texas, studying SE at UTD. I read, create websites, apps, and drone videos. Check out my projects at liam.mcmains.net