svelte-awesome-color-picker

highly customizable color picker component library

  • 🎹 built-in keyboard navigation
  • 📱 mobile support
  • 🤸‍♂️ accessibility information
  • 🤯 works without javascript (fallback to the browser default color picker)
  • 🏇 it’s compatible with form libraries
  • 🧩 fully customizable
  • 🔨 full typescript support
  • 🖤 dark theme support

The library uses 2 libraries:

  • colord: lightest color conversion library on the market at the time and supports a11y contrasts
  • svelte-awesome-slider: another library I crafted and is higlhy customizable.

This documentation is the documentation of svelte-awesome-color-picker v3. If you are looking to upgrate to v3, see the section upgrade from v2 to v3. If you are looking for the v2 documentation, see the v2 documentation.

Install

npm i -D svelte-awesome-color-picker

The same documentation can be seen on Github, on the npm registry or on the documentation site. I would suggest to visite the documentation site since it has interactive examples!

Examples

Default layout

Source code

<script>
	import ColorPicker from 'svelte-awesome-color-picker';
</script>

<ColorPicker
	bind:hex
	bind:rgb
	bind:hsv
	bind:color
  position="responsive"
/>

Color props

let hex = "#f6f0dc"

let rgb = {
  "r": 255,
  "g": 0,
  "b": 0,
  "a": 1
}

let hsv = {
  "h": 0,
  "s": 100,
  "v": 100,
  "a": 1
}

let color = "// instance of Colord"

Chrome variant

Source code

<script>
	import ColorPicker, { ChromeVariant } from 'svelte-awesome-color-picker';
</script>

<ColorPicker bind:rgb bind:hsv bind:hex components={ChromeVariant} sliderDirection="horizontal" />

Accessibility notice variant

Source code

<script>
	import ColorPicker, { A11yVariant } from 'svelte-awesome-color-picker';
</script>

<ColorPicker
	components={A11yVariant}
	bind:hex
	bind:rgb
	bind:hsv
	isAlpha
	a11yColors={[
		{ textHex: '#FFF', reverse: true, placeholder: 'background' },
		{ textHex: '#FFF', bgHex: '#FF0000', reverse: true, placeholder: 'background' },
		{ bgHex: '#FFF', placeholder: 'title', size: 'large' },
		{ bgHex: '#7F7F7F', placeholder: 'button' }
	]}
/>

Note: set both attributes resverse and bgHex when you are chosing a transparency background color over a non white background.

Nullable version

Source code

<script>
	import ColorPicker from 'svelte-awesome-color-picker';
</script>

<ColorPicker
	bind:hex
	bind:rgb
	bind:hsv
	bind:color
	nullable
/>

Always open version

Source code

<script>
	import ColorPicker, { ChromeVariant } from 'svelte-awesome-color-picker';
</script>

<ColorPicker
	bind:rgb
	bind:hsv
	bind:hex
	components={ChromeVariant}
	sliderDirection="horizontal"
	isDialog={false}
/>

Bind event ’on:input

In this example, the color is appended to the history at each event.

Source code

<ColorPicker
	{rgb}
	on:input={(event) => {
		historyHex = [...historyHex, event.detail.hex];
	}}
/>

history variable

let history = []

Override the css variables

Source code

<ColorPicker
	bind:rgb
	bind:hsv
	bind:hex
	--picker-height="100px"
	--picker-width="100px"
	--slider-width="25px"
	--picker-indicator-size="25px"
	--picker-z-index="10"
	--input-size="100px"
	--focus-color="green"
/>

Dark theme

Source code

<script>
	import ColorPicker from 'svelte-awesome-color-picker';
</script>

<div class="dark">
	<ColorPicker />
</div>

<style>
	.dark {
		--cp-bg-color: #333;
		--cp-border-color: white;
		--cp-text-color: white;
		--cp-input-color: #555;
		--cp-button-hover-color: #777;
	}</style>

Translate the color picker

Note: the texts props can be partially overridden. It’s mostly used to translate the component. Most texts are used for accessibility aria-labels.

Source code

<ColorPicker
	bind:rgb
	bind:hsv
	bind:hex
	label="Choisir une couleur"
	texts={{
		label: {
			h: 'teinte',
			s: 'saturation',
			v: 'luminosité',
			r: 'rouge',
			g: 'vert',
			b: 'bleu',
			a: 'transparence',
			hex: 'couleur hexadécimale',
			withoutColor: 'sans couleur'
		},
		color: {
			rgb: 'rgb',
			hsv: 'hsv',
			hex: 'hex'
		},
		changeTo: 'changer à '
	}}
/>

Api

The library exports 4 different things:

  • The color picker as a default export
  • ChromeVariant: the Chrome variant
  • A11yVariant: the accessibility variant (to display a panel which shows the WCAG grades)
  • HsvaColor and RgbaColor: the two types defining HSV and RGB colors

Color picker

props

name type default value usage
components Partial<Components> {} customize the ColorPicker component parts. Can be used to display a Chrome variant or an Accessibility Notice
label string 'Choose a color' input label, hidden when the ColorPicker is always shown (prop isDialog={false})
name string | undefined undefined input name, useful in a native form
nullable boolean false if set to true, the color picker becomes nullable (rgb, hsv and hex set to undefined)
rgb RgbaColor | undefined nullable ? undefined : { r: 255, g: 0, b: 0, a: 1 } rgb color
hsv HsvaColor | undefined nullable ? undefined : { h: 0, s: 100, v: 100, a: 1 } hsv color
hex string | undefined nullable ? undefined : '#ff0000' hex color
color Colord | undefined undefined Colord color
isDark boolean false indicator whether the selected color is light or dark
isAlpha boolean true if set to false, disables the alpha channel
isDialog boolean true if set to false, the input and the label will not be displayed and the ColorPicker will always be visible
isOpen boolean !isDialog indicator of the popup state
position 'fixed' | 'responsive' | 'responsive-x' | 'responsive-y' 'fixed' if set to “responsive”, the popup will adjust its x and y position depending on the available window space, “responsive-x” and “responsive-y” limit the behavior to either the x or y axis. The value ‘responsive’ will become the default in the next major release
isTextInput boolean true if set to false, hide the hex, rgb and hsv text inputs
textInputModes Array<'hex' | 'rgb' | 'hsv'> ['hex', 'rgb', 'hsv'] configure which hex, rgb and hsv inputs will be visible and in which order. If overridden, it is necessary to provide at least one value
sliderDirection 'horizontal' | 'vertical' 'vertical' If set to “horizontal”, the hue and alpha sliders will be displayed horizontally. It is necessary to set this props to “horizontal” for the ChromeVariant
disableCloseClickOutside boolean false If set to true, it will not be possible to close the color picker by clicking outside
a11yColors Array<A11yColor> [{ bgHex: '#ffffff' }] used with the A11yVariant. Define the accessibility examples in the color picker
a11yLevel 'AA' | 'AAA' 'AA' required WCAG contrast level
texts TextsPartial | undefined undefined all translation tokens used in the library; can be partially overridden; see full object type
a11yTexts A11yTextsPartial | undefined undefined all a11y translation tokens used in the library; override with translations if necessary; see full object type

events

Event Type Usage
input { color, hsv, rgb, hex } Event fired on every color change (click & drag & mouse, touch)

See the example Bind event ’on:input.

css variables

Props Default Value Usage
--picker-height 200px picker & sliders height
--picker-width 200px (260px for the Chrome variant) picker width
--slider-width 30px sliders width
--picker-indicator-size 10px picker indicator size
--picker-z-index 2 popup picker z-index
--input-size 25px color circle size
--focus-color red focus color
--cp-bg-color white background color
--cp-border-color black border color
--cp-text-color --cp-border-color text color
--cp-input-color #eee background color of the inputs
--cp-button-hover-color #ccc background color of the hovered button

See the example Override the css variables’.

components

The color picker can be customized with components. The details and props are detailed below. It is easier to copy the library components and tweak them to your needs.

A Chrome variant and an accessibility variant are available. To use the Chrome variant you need to set the props sliderDirection to horizontal. You can also partially overwrite the components:

<script>
	import ColorPicker, { ChromeVariant } from 'svelte-awesome-color-picker';
	import CustomInput from '$lib/path/to/my/awesome/variant/Input.svelte';
	import CustomWrapper from '$lib/path/to/my/awesome/variant/Wrapper.svelte';

	let rgb;
</script>

<!-- example with the default display and a custom Input component -->
<ColorPicker bind:rgb components={{ input: CustomInput }} />

<!-- example with the Chrome variant and a custom Wrapper component -->
<ColorPicker bind:rgb components={{ ...ChromeVariant, wrapper: CustomWrapper }} />

<!-- example with the ChromeVariant -->
<ColorPicker bind:rgb components={ChromeVariant} sliderDirection="horizontal" />

The components that can be overridden are:

The 3 components a11yNotice, a11ySummary and a11ySingleNotice are no longer included by default but can still be defined or passed through the a11yVariant object. This change was made in version 3.0.0 to lighten the library for those who do not use it.

Some components are no longer customizable in version 3.0.0: pickerWrapper, sliderWrapper, alphaWrapper, sliderIndicator and alphaIndicator. Instead you can either use the css variables or you can style them from the wrapper component.

pickerIndicator

Component representing the picker indicator.

  • The component should be positioned with position: absolute;.
  • It should also have the css property pointer-events: none;.

Props:

name type default value usage
pos { x: number indicator position in %
isDark boolean indicator whether the selected color is light or dark

textInput

Component representing the rgb / hex / hsv textual input below the picker

Props:

name type default value usage
isAlpha boolean if set to false, disables the alpha channel
rgb RgbaColor rgb color
hsv HsvaColor hsv color
hex string hex color
textInputModes Array<'hex' | 'rgb' | 'hsv'> configure which hex, rgb and hsv inputs will be visible and in which order. If overridden, it is necessary to provide at least one value
texts Texts all translation tokens used in the library; can be partially overridden; see full object type

Input

Component representing the button to open the color picker and a hidden input with the hex value selected by the user

Props:

name type default value usage
labelElement HTMLLabelElement DOM element of the label wrapper
hex string | undefined hex color
label string input label
name string | undefined undefined input name, useful in a native form
isOpen boolean indicator of the popup state

wrapper

Encapsulates the whole color picker

Props:

name type default value usage
wrapper HTMLElement DOM element of the wrapper element
isOpen boolean indicator of the popup state
isDialog boolean if set to true, the wrapper should have a dialog role and be absolute. It should be relative otherwise

nullabilityCheckbox

Displays the checkbox to toggle an undefined value

Props:

name type default value usage
isUndefined boolean whether the color picker is undefined
texts Texts all translation tokens used in the library; can be partially overridden; see full object type

a11yNotice

Component displaying accessible contrast issues with the color chosen.

Props:

name type default value usage
components Components customize the ColorPicker component parts. Can be used to display a Chrome variant or an Accessibility Notice
hex string hex color
a11yColors Array<A11yColor> define the accessibility examples in the color picker
a11yLevel 'AA' | 'AAA' required WCAG contrast level
a11yTexts A11yTextsPartial | undefined undefined all a11y translation tokens used in the library; override with translations if necessary; see full object type

Type A11yColor:

type A11yColor = {
	placeholder?: string;
	size?: 'normal' | 'large';
} & (
	| {
			textHex: string;
			bgHex: string;
			reverse: true;
	  }
	| {
			bgHex: string;
			reverse?: false;
	  }
);
Attribute Type Usage
placeholder string placeholder text, default to Lorem Ipsum
size normal, large used to check the contrast guidelines
reverse boolean set to true if the color picker is used to chose a background color
textHex string when choosing the background color, defines the text color
bgHex string when choosing the text color, defines the background color ; hen choosing th background color, defines the color behind (in case of transparency)

read more about this component accessibility in the #a11y section.

a11ySingleNotice

component display the accessibility result of the color over a single item of the a11yColors props.

Props:

name type default value usage
placeholder string | undefined undefined placeholder, falls back to Lorem Ipsum
size 'normal' | 'large' | undefined undefined size of the text
a11yLevel 'AA' | 'AAA' required WCAG contrast level
textColor string placeholder text color
bgColor string placeholder background color
contrast number 1 RGAA contrast between the text and its background. Between 1 and 21
contrastText string define the accessibility “contrast” text

Accessibility

The component itself

The svelte-awesome-color-picker uses svelte-awesome-slider (also made by me) to display the sliders. This library follows the W3c slider component accessibility guidelines.

The color picker follows the W3c component dialog combobox accessibility guidelines.

Accessibility notice

The component can display an accessibility notice that updates the WCAG contrast grades by using the a11yVariant component override.

The contrast between 2 colors is a value between 1 and 21. It is computed with the colord a11y plugin library based on WCAG 2.0 guidelines for contrast accessibility.

A contrast between 2 colors succeed if it follows the WCAG contrast guidelines:

Text size AA AAA
small text (18.5px) contrast > 4.5 contrast > 7
big text (24px) contrast > 3 contrast > 4.5

In the default A11ySingleNotice component that renders the AA and AAA tags, the small text values are used (can be configured for each reference color with the color props).

See and the accessibility notice variant example and the definition of the A11yColor type for more information.

How to

Fix overflow issues inside a container

If you use the ColorPicker component inside a container that is set with overflow: auto or overflow: hidden, the picker will be hidden outside of the wrapper.

To fix this, you can override the Wrapper component and use the svelte-portal library to render the picker outside of your container. An example of how to do that is presented in this svelte-awesome-color-picker portal REPL.

Fix overflow issues in the window

Please set the position props to responsive as stated in the props section.

Use the color of the document

Override the css variable --cp-border-color:

body {
	--cp-border-color: currentColor;
}

If you have a dark theme, make sure to handles it correctly.

Migration

upgrade from v2 to v3

The major version 3 has been released to remove accessibility issues (see issue #43). The library now comes with the possibility to deselect a color and it is also possible to theme the picker for dark themes. The library has also been made simpler and lighter. This comes with some breaking changes:

  • sliderIndicator, alphaIndicator, pickerWrapper, sliderWrapper, alphaWrapper and a11ySummary were removed, you can use css variables in the wrapper component for design customization and texts in the texts and a11yTexts props instead for translating the library.
  • props isA11y has been removed. The accessibility display is now a variant: <ColorPicker components={A11yVariant} />. This change has been made to reduce the library bundle size.
  • props isInput and isPopup have been merged and renamed as isDialog.
  • props isRight has been replaced by sliderDirection="horizontal".
  • props isA11yOpen and isA11yClosable have been removed.