Forms Color Picker

Color Picker

A full-featured HSV color picker built on wf-color-picker.js . Renders as a dropdown panel or an always-visible inline widget. Includes a 2-D saturation/brightness grid, hue and optional opacity sliders, a format-cycling hex/RGB/HSL text input, a copy button, and configurable swatch presets. The hidden input inside the wrapper participates in standard form submission automatically.

Quick Start

Import the module once. All elements with data-wf-color-picker are enhanced automatically on DOMContentLoaded . Place a native <input type="hidden"> (or type="text" ) inside the wrapper — its value stays in sync and is submitted with any parent form.

JS
import './wf-color-picker.js'
HTML
<!-- Dropdown (default) -->
<div class="wf-color-picker" data-wf-color-picker data-wf-value="#5F41FB">
  <input type="hidden" name="themeColor">
</div>

<!-- Manual init -->
<div class="wf-color-picker" id="my-picker">
  <input type="hidden" name="color">
</div>
<script type="module">
  import { WojoColorPicker } from './wf-color-picker.js'
  new WojoColorPicker(document.getElementById('my-picker')).init()
</script>

Formats

Use data-wf-format to control the hidden input output: hex (default), rgb , or hsl . The format-cycling button inside the panel lets users switch formats at runtime — hide it with data-wf-no-format-toggle . Add data-wf-uppercase to uppercase hex strings. data-wf-value accepts any parseable CSS color string.

HEX (default)

RGB format

HSL format

Uppercase, no toggle

HTML
<!-- HEX (default) -->
<div class="wf-color-picker" data-wf-color-picker data-wf-value="#e74c3c">
  <input type="hidden" name="color">
</div>

<!-- RGB output -->
<div class="wf-color-picker" data-wf-color-picker data-wf-value="rgb(46, 204, 113)" data-wf-format="rgb">
  <input type="hidden" name="color">
</div>

<!-- HSL output -->
<div class="wf-color-picker" data-wf-color-picker data-wf-value="hsl(204, 70%, 53%)" data-wf-format="hsl">
  <input type="hidden" name="color">
</div>

<!-- Uppercase hex, no format-cycling button -->
<div class="wf-color-picker" data-wf-color-picker data-wf-uppercase data-wf-no-format-toggle>
  <input type="hidden" name="color">
</div>

Opacity

Add data-wf-opacity to reveal the alpha slider. The output automatically includes the alpha channel — as #rrggbbaa , rgba() , or hsla() depending on the active format. The checkerboard pattern on the swatch preview makes semi-transparent values visually clear.

HEX + alpha (#rrggbbaa)

RGB + alpha (rgba)

HSL + alpha (hsla)

HTML
<!-- HEX + alpha: outputs #rrggbbaa -->
<div class="wf-color-picker" data-wf-color-picker
     data-wf-value="rgba(95, 65, 251, 0.6)"
     data-wf-opacity>
  <input type="hidden" name="color">
</div>

<!-- RGBA output -->
<div class="wf-color-picker" data-wf-color-picker
     data-wf-value="#e74c3c80"
     data-wf-opacity
     data-wf-format="rgb">
  <input type="hidden" name="color">
</div>

<!-- HSLA output -->
<div class="wf-color-picker" data-wf-color-picker
     data-wf-value="hsla(145, 63%, 49%, 0.75)"
     data-wf-opacity
     data-wf-format="hsl">
  <input type="hidden" name="color">
</div>

Swatches

Pass a semicolon-separated list of CSS colors to data-wf-swatches to show preset swatches at the bottom of the panel. Any parseable CSS color is accepted — hex, rgb() , named colors, etc. The active swatch gets an outline ring when the current color matches. Pass an empty string to disable the swatch row entirely; omit the attribute to use the built-in 12-color default palette.

Flat UI palette

Named colors

With opacity

HTML
<!-- Custom swatch palette -->
<div class="wf-color-picker" data-wf-color-picker
     data-wf-swatches="#e74c3c;#e67e22;#f1c40f;#2ecc71;#3498db;#9b59b6">
  <input type="hidden" name="color">
</div>

<!-- Named CSS colors -->
<div class="wf-color-picker" data-wf-color-picker
     data-wf-swatches="tomato;orange;gold;limegreen;steelblue;mediumpurple">
  <input type="hidden" name="color">
</div>

<!-- Disable swatch row entirely -->
<div class="wf-color-picker" data-wf-color-picker data-wf-swatches="">
  <input type="hidden" name="color">
</div>

Swatches Only

Add data-wf-swatches-only to strip the gradient grid, sliders, and text input from the panel — only the swatch row remains. Selecting a swatch commits the color and closes the dropdown immediately. Pair with data-wf-no-label to reduce the trigger to the color swatch alone.

Swatches only

No label

HTML
<!-- Swatches-only panel -->
<div class="wf-color-picker" data-wf-color-picker
     data-wf-swatches-only
     data-wf-swatches="#e74c3c;#e67e22;#f1c40f;#2ecc71;#3498db;#9b59b6">
  <input type="hidden" name="color">
</div>

<!-- Swatches-only + no trigger label -->
<div class="wf-color-picker" data-wf-color-picker
     data-wf-swatches-only
     data-wf-no-label
     data-wf-swatches="#e74c3c;#e67e22;#f1c40f;#2ecc71;#3498db;#9b59b6">
  <input type="hidden" name="color">
</div>

Inline

Add data-wf-inline to embed the picker panel permanently in the page — no trigger button, always visible. Ideal for settings screens and dedicated color editors. Constrain the width by setting --wf-cp-panel-w or adding a max-width on the wrapper.

Basic inline

Inline + opacity + swatches

HTML
<!-- Inline panel — always visible -->
<div class="wf-color-picker" data-wf-color-picker
     data-wf-value="#5F41FB"
     data-wf-inline>
  <input type="hidden" name="color">
</div>

<!-- Constrain width via CSS custom property -->
<div class="wf-color-picker" data-wf-color-picker
     data-wf-inline
     style="--wf-cp-panel-w: 20rem;">
  <input type="hidden" name="color">
</div>

Sizes

Use data-wf-size="sm" or data-wf-size="lg" to adjust the trigger button size. The panel stays the same width across all sizes. Combine with data-wf-no-label to hide the text label and show only the color swatch in the trigger. Use data-wf-label for a custom trigger label text.

Small

Medium (default)

Large

No label

Custom label

HTML
<!-- Small trigger -->
<div class="wf-color-picker" data-wf-color-picker data-wf-size="sm">
  <input type="hidden" name="color">
</div>

<!-- Large trigger -->
<div class="wf-color-picker" data-wf-color-picker data-wf-size="lg">
  <input type="hidden" name="color">
</div>

<!-- Swatch-only trigger (no label text) -->
<div class="wf-color-picker" data-wf-color-picker data-wf-no-label>
  <input type="hidden" name="color">
</div>

<!-- Custom trigger label -->
<div class="wf-color-picker" data-wf-color-picker data-wf-label="Brand color">
  <input type="hidden" name="color">
</div>

Data Attributes

Attribute Description
data-wf-color-picker Required. Marks the wrapper for auto-init on DOMContentLoaded .
data-wf-value Initial color. Accepts any parseable CSS color string — hex, rgb() , hsl() , named colors. Falls back to the hidden input's value attribute, then #000000 .
data-wf-format Output format for the hidden input. hex (default) · rgb · hsl . The format-cycling button lets users switch at runtime.
data-wf-opacity Boolean. Reveals the alpha slider. Output gains an alpha channel: #rrggbbaa , rgba() , or hsla() .
data-wf-swatches Semicolon-separated CSS colors for the preset swatch row. Pass an empty string to disable swatches. Omit using the built-in 12-color default palette.
data-wf-no-swatches Removes swatched from the panel.
data-wf-swatches-only Boolean. Hides the gradient grid, sliders, and text input — shows only swatches. Selecting a swatch commits the color and closes the dropdown.
data-wf-no-format-toggle Boolean. Hides the format-cycling button inside the panel.
data-wf-inline Boolean. Renders the panel always-visible and embedded in the page. No trigger button is shown.
data-wf-disabled Boolean. Disables all interaction — trigger fades to 55% opacity, pointer events removed. Also, togglable via setDisabled() .
data-wf-size Trigger button size: sm or lg . Omit for medium (default). The panel width is unaffected.

Events & API

Access the instance via el._wfColorPicker after auto-init or manual new WojoColorPicker(el).init() . Events are dispatched on the .wf-color-picker wrapper element.

Methods

Method Description
getValue() Returns the current color string in the active output format.
getFormattedValue(fmt) Returns the color in a specific format regardless of the active display format. fmt : 'hex' · 'hex' · 'rgb' · 'rgba' · 'hsl' · 'hsla'
setValue(str) Set the color from any parseable CSS color string. Updates all visuals immediately.
show() Open the dropdown panel. No-op in inline mode or when disabled.
hide() Close the dropdown panel. No-op in inline mode.
toggle() Toggle the dropdown panel open/closed.
setDisabled(bool) Enable ( false ) or disable ( true ) interaction programmatically.
destroy() Remove all event listeners and clean up the instance.

Events

Event Detail Description
wf:color-input { value } Fires continuously on every interaction — grid drag, slider move, text input keystroke. Use for live preview.
wf:color-change { value } Fires when the color is committed — drag end, slider release, text input blur, or swatch click. Use for persistence.
wf:color-show Fired when the dropdown panel opens.
wf:color-hide Fired when the dropdown panel closes.

CSS Custom Properties

Property Default Description
--wf-cp-panel-w 16rem Width of the dropdown or inline panel.
--wf-cp-grid-h 12rem Height of the HSV saturation/value gradient grid.
--wf-cp-thumb 1rem Diameter of the grid drag handle and slider thumbs.
--wf-cp-track-h 0.75rem Height of the hue and alpha slider tracks.
--wf-cp-swatch-size 1.25rem Width and height of each swatch cell in the swatch row.
JS
const el = document.getElementById('my-picker')
const cp = el._wfColorPicker   // instance attached after auto-init

// Read value
cp.getValue()                    // current format  e.g. "#5f41fb"
cp.getFormattedValue('rgba')     // always RGBA      e.g. "rgba(95, 65, 251, 1)"
cp.getFormattedValue('hsl')      // always HSL       e.g. "hsl(250, 96%, 62%)"

// Write value (any parseable CSS color)
cp.setValue('#e74c3c')
cp.setValue('rgba(52, 152, 219, 0.5)')

// Panel control (dropdown mode only)
cp.show()
cp.hide()
cp.toggle()

// Enable / disable
cp.setDisabled(true)
cp.setDisabled(false)

// Events — dispatched on the .wf-color-picker wrapper
el.addEventListener('wf:color-input',  e => console.log('[live]', e.detail.value))
el.addEventListener('wf:color-change', e => console.log('[commit]', e.detail.value))
el.addEventListener('wf:color-show',   () => console.log('panel opened'))
el.addEventListener('wf:color-hide',   () => console.log('panel closed'))

// Resize the panel/grid via CSS custom properties
el.style.setProperty('--wf-cp-panel-w', '20rem')
el.style.setProperty('--wf-cp-grid-h',  '16rem')