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
The library uses colord internally because it’s the lightest color conversion library on the market at the time and supports a11y contrasts and svelte-awesome-slider to display sliders.
Install
npm i -D svelte-awesome-color-picker
Links
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!
- 🛫 Documentation
- 🌟 Github repository
- 🌴 Npm repository
- đź‘Ś Changelog
Examples
Default layout
Source code
<script>
import ColorPicker from 'svelte-awesome-color-picker';
</script>
<ColorPicker
bind:hex
bind:rgb
bind:hsv
bind:color
open
/>
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
background
contrast: 1.14
AAtitle
contrast: 1.14
AAtext
contrast: 1.14
AAbutton
contrast: 1.01
AALearn more at WebAIM contrast guide
Source code
<script>
import ColorPicker, { A11yVariant } from 'svelte-awesome-color-picker';
</script>
<ColorPicker
components={A11yVariant}
bind:hex
bind:rgb
bind:hsv
isAlpha
a11yColors={[
{ hex: '#FFF', reverse: true, placeholder: 'background' },
{ hex: '#FFF', placeholder: 'title', size: 'large' },
{ hex: '#FFF', placeholder: 'text' },
{ hex: '#EEE', placeholder: 'button' }
]}
/>
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}
/>
on:input
’
Bind event ’
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"
/>
Api
The library exports 4 different things:
- The color picker as a default export
ChromeVariant
: the Chrome variantA11yVariant
: the accessibility variant (to display a panel which shows the WCAG grades)HsvaColor
andRgbaColor
: the two types defining HSV and RGB colors
Color picker
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 |
rgb | RgbaColor |
{ r: 255, g: 0, b: 0, a: 1 } |
rgb color |
hsv | HsvaColor |
{ h: 0, s: 100, v: 100, a: 1 } |
hsv color |
hex | string |
'#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 |
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> |
[{ hex: '#ffffff' }] |
used with the A11yVariant. Define the accessibility examples in the color picker |
a11yLevel | 'AA' | 'AAA' |
'AA' |
required WCAG contrast level |
isA11yClosable | boolean |
true |
used with the A11yVariant. If set to false, the accessibility panel will always be shown |
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 |
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 |
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 |
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 | |
color | Colord | undefined |
Colord color | |
a11yColors | Array<A11yColor> |
define the accessibility examples in the color picker | |
a11yLevel | 'AA' | 'AAA' |
required WCAG contrast level | |
isA11yClosable | boolean |
if set to false, the accessibility panel will always be shown | |
a11yTexts | A11yTextsPartial | undefined |
undefined |
all a11y translation tokens used in the library; override with translations if necessary; see full object type |
Type A11yColor:
Attribute | Type | Usage |
---|---|---|
hex | string |
The reference color |
reverse | boolean |
if set to true, use the hex color as the text color instead of the background |
placeholder | string |
placeholder text, default to Lorem Ipsum |
size | normal, large |
used to check the contrast guidelines |
contrast | string |
color contrast between the current color and the hex reference color |
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
In progress
Accessibility notice
The component can display an accessibility notice that updates the WCAG contrast grades by using the a11yVariant
component override and the isA11y
props.
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
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.
Migration
update from v2 to v3
The major version 3 has been released to remove accessibility issues (see issue #43). The library has also been made simpler and lighter. This comes with some breaking changes:
sliderIndicator
,alphaIndicator
,pickerWrapper
,sliderWrapper
,alphaWrapper
anda11ySummary
were removed, you can use css variables in thewrapper
component and texts in thetexts
anda11yTexts
props instead.- 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
andisPopup
have been merged and renamed asisDialog
. - props
isRight
has been replaced bysliderDirection="horizontal"
. - props
isA11yOpen
has been removed.