<!-- ColorPicker definition -->
<template id="color-picker-template">
<div class="preview"></div>
<div class="palette"></div>
<button class="reset-button">Reset</button>
<style>
/* <color-picker> element */
:host {
--preview-width: 300px;
--swatch-height: calc(var(--preview-width) / 5);
display: flex;
flex-direction: column;
width: var(--preview-width);
margin: 0 auto;
}
:host .preview {
width: var(--preview-width);
height: var(--preview-width);
background-color: #111111;
}
:host .palette {
display: flex;
width: 100%;
}
:host .palette > .swatch {
flex: 1;
height: var(--swatch-height);
}
:host .reset-button {
margin-top: 10px;
}
</style>
</template>
<!-- ColorPicker usage -->
<h1>Click within a <code>ColorPicker</code>'s palette to preview a color.</h1>
<div class="grid">
<div>
<h2>Default palette</h2>
<color-picker></color-picker>
<p>The <code>ColorPicker</code> uses a bright 5-color palette if you don't specify one.</p>
</div>
<div>
<h2>Palette from <a href="https://coolors.co/355070-6d597a-b56576-e56b6f-eaac8b-e5dcc5" target="_blank" rel="noreferrer noopener">Coolors</a></h2>
<color-picker data-palette='["#355070", "#6d597a", "#b56576", "#e56b6f", "#eaac8b", "#e5dcc5"]'></color-picker>
<p>You can pass any number of colors to use as a palette using the <code>data-palette</code> attribute.</p>
</div>
<div>
<h2>Define colors any way</h2>
<color-picker data-palette='["#1b7141", "seagreen", "rgb(71, 160, 110)", "hsl(146deg, 33%, 55%)"]'></color-picker>
<p>Hexadecimal, named colors, <code>rgb()</code>, and <code>hsl()</code> are fair game.</p>
</div>
</div>
body {
text-align: center;
line-height: 1.5;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 1.5rem;
}
class ColorPicker extends HTMLElement {
constructor() {
super();
// Attach a shadow root to the element
const template = document.getElementById('color-picker-template');
const shadowRoot = this.attachShadow({ mode: 'open' });
shadowRoot.appendChild(template.content.cloneNode(true));
// Preserve method context
this.setPreviewColor = this.setPreviewColor.bind(this);
this.resetPreview = this.resetPreview.bind(this);
// Get element references
this.previewElement = shadowRoot.querySelector('.preview');
this.paletteElement = shadowRoot.querySelector('.palette');
this.resetButton = shadowRoot.querySelector('.reset-button');
// Initialize palette based on data attributes, if possible
const dataPalette = this.dataset.palette;
const defaultPalette = [
'#e62e25',
'#68f312',
'#35a3fa',
'#f29f27',
'#e140fe',
];
const palette = dataPalette ? JSON.parse(dataPalette) : defaultPalette;
// Attach palette colors
palette.forEach(color => {
const swatchElement = document.createElement('div');
swatchElement.className = 'swatch';
swatchElement.dataset.color = color;
swatchElement.style.backgroundColor = color;
this.paletteElement.appendChild(swatchElement);
});
// Add event listeners
this.paletteElement.addEventListener('click', this.setPreviewColor);
this.resetButton.addEventListener('click', this.resetPreview);
}
disconnectedCallback() {
// Remove event listeners
this.paletteElement.removeEventListener('click', this.setPreviewColor);
this.resetButton.removeEventListener('click', this.resetPreview);
}
setPreviewColor(event) {
const color = event.target.dataset.color;
this.previewElement.style.backgroundColor = color;
}
resetPreview() {
this.previewElement.style.removeProperty('background-color');
}
}
window.customElements.define('color-picker', ColorPicker);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.