DEV Community

Cover image for Let's Build a Colour Picker Web Component

Let's Build a Colour Picker Web Component

Benny Powers 🇮🇱🇨🇦 on June 25, 2021

Let's build a colour picker web component using HTML, CSS, and a little bit of JavaScript. In the end, we'll have a custom element that: Displays...
Collapse
 
dannyengelman profile image
Danny Engelman

Cool... but I am the laziest developer ever... drop the this in this:

super()
    this
      .attachShadow({ mode: 'open' })
      .append(template.content.cloneNode(true));
Enter fullscreen mode Exit fullscreen mode
super() // sets and returns this
      .attachShadow({ mode: 'open' })
      .append(template.content.cloneNode(true));
Enter fullscreen mode Exit fullscreen mode
Collapse
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

fine, but if you copy that into a typescript file, it will break everything.

That's not a criticism of your change as much as it's a criticism of typescript, though. Still, it bears saying.

Collapse
 
dannyengelman profile image
Danny Engelman • Edited

LOL, that is the drawback of me not using TypeScript (any more). I don't learn where it fails.
Even more LOL to consider I worked in the Microsoft world for 15 years;
and "nudged" my Typescript colleagues unlearn ES3 patterns they applied to cool new TypeScript:
Clark Kents' TypeScript Adventures

Collapse
 
dbatiste profile image
Dave Batiste

Native color pikers are all different and impossible to customize, so if cross-browser consistency is a requirement, then rolling with the native color picker is a "no-go". It may also be a requirement to align with other aspects of the consumer's design system. They also don't provide much in terms of a11y. In short, there may be many design requirements that lead to a custom color picker since native picker are (unfortunately) quite inflexible.

Collapse
 
westbrook profile image
Westbrook Johnson

Very cool Benny! Thanks for sharing. Wondering if you might have a clever way to make this sort of experience accessible to screen readers?

Collapse
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

Good idea! As the focus of the post was custom elements and reactive controllers, I didn't cover all the bases, I'd love to see a remixed glitch that builds in accessibility code down here in the comments though. I'll add that idea to the "next steps" section

For production needs, check out <vanilla-colorful>

Collapse
 
dbatiste profile image
Dave Batiste

A nice a11y related feature is to include the ability to specify a background or foreground reference color, and show the color contrast along with WCAG AA/AAA compliance. In some contexts, this is an important (yet rarely implemented) feature as it goes beyond standard a11y to include authoring accessible content. I know your sample component wasn't meant to include all the bells & whistles though. Thanks for sharing this Benny!

Thread Thread
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

I'd love to see a remix that includes this

Collapse
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦 • Edited

Good point! if the native widget fulfills your needs, it would be irresponsible to use JavaScript of any flavour to deliver the feature.

There could be lots of reasons to want a custom element for this, though. Off the top of my head I can think of two:

  1. design system integration
  2. colour controls that native doesn't provide (like colour spaces)

To answer the question "Why write a blog post about making a colour picker?" - The specific content here isn't as important as the concepts of

  • How Reactive Controllers work with Custom Elements
  • That you can use Controllers without using LitElement, via the mixin
Collapse
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

@codingsafari do you have another idea for how to use a MouseController? I'd love to see how you remix the glitch

Collapse
 
cristoferk profile image
CristoferK

cool! This is very usefull!

Collapse
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

I wrote a version of this example but using Haunted instead of extending HTMLElement directly:

hauntedhooks.netlify.app/docs/hook...

Collapse
 
bennypowers profile image
Benny Powers 🇮🇱🇨🇦

I added an a11y section, which I should have done in the first place. Thanks @westbrook and @thepassle