• Stars
    star
    4,290
  • Rank 10,001 (Top 0.2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 6 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🎨 Flat, simple, multi-themed, responsive and hackable Color-Picker library. No dependencies, no jQuery. Compatible with all CSS Frameworks e.g. Bootstrap, Materialize. Supports alpha channel, rgba, hsla, hsva and more!

Logo

Flat, Simple, Hackable Color-Picker.


gzip size brotli size Build Status Download count No dependencies JSDelivr download count Current version Support me Gitpod Ready-to-Code



Features

  • Themes
  • Simple usage
  • Zero dependencies
  • Multiple color representations
  • Color comparison
  • Opacity control
  • Detail adjustments via. mouse-wheel
  • Responsive and auto-positioning
  • Supports touch devices
  • Swatches for quick-selection
  • Fully accessible and i18n
  • Shadow-dom support

Status of this project

This project might continue to get important security- and bug-related updates but its feature set is frozen, and it's highly unlikely that it'll get new features or enhancements.

The reason behind this decision is the way this tool has been build (monolithic, the core is one single file, everything is in plain JS etc.) which makes it incredible hard to maintain, tests become impossible at this stage without a complete rewrite, and the fun is gone at such a level of cramped complexity.

Personally I recommend building these UI-Related "widgets" directly into the app with the framework you're using which takes more time but in return gives you full power of how it should work and look like. Frameworks such as (p)react, vue and svelte will make it a breeze to develop such things within a day.

As of 2021, this project is no longer maintained!

Themes

Classic Monolith Nano
Classic theme Monolith Nano

Nano uses css-grid thus it won't work in older browsers.

Getting Started

Node

Note: The readme is always up-to-date with the latest commit. See Releases for installation instructions regarding to the latest version.

Install via npm:

$ npm install @simonwep/pickr

Install via yarn:

$ yarn add @simonwep/pickr

Include code and style:

// One of the following themes
import '@simonwep/pickr/dist/themes/classic.min.css';   // 'classic' theme
import '@simonwep/pickr/dist/themes/monolith.min.css';  // 'monolith' theme
import '@simonwep/pickr/dist/themes/nano.min.css';      // 'nano' theme

// Modern or es5 bundle (pay attention to the note below!)
import Pickr from '@simonwep/pickr';
import Pickr from '@simonwep/pickr/dist/pickr.es5.min';

Attention: The es5-bundle (e.g. legacy version) is quite big (around a triple of the modern bundle). Please take into consideration to use the modern version and add polyfills later to your final bundle! (Or better: give a hint to users that they should use the latest browsers). Browsers such as IE are not supported (at least not officially).

Browser

jsdelivr:

<!-- One of the following themes -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/classic.min.css"/> <!-- 'classic' theme -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/monolith.min.css"/> <!-- 'monolith' theme -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/themes/nano.min.css"/> <!-- 'nano' theme -->

<!-- Modern or es5 bundle -->
<script src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@simonwep/pickr/dist/pickr.es5.min.js"></script>

Be sure to load the pickr.min.js (or the es5 version) after pickr.min.css. Moreover the script tag doesn't work with the defer attribute.

Usage

// Simple example, see optional options for more configuration.
const pickr = Pickr.create({
    el: '.color-picker',
    theme: 'classic', // or 'monolith', or 'nano'

    swatches: [
        'rgba(244, 67, 54, 1)',
        'rgba(233, 30, 99, 0.95)',
        'rgba(156, 39, 176, 0.9)',
        'rgba(103, 58, 183, 0.85)',
        'rgba(63, 81, 181, 0.8)',
        'rgba(33, 150, 243, 0.75)',
        'rgba(3, 169, 244, 0.7)',
        'rgba(0, 188, 212, 0.7)',
        'rgba(0, 150, 136, 0.75)',
        'rgba(76, 175, 80, 0.8)',
        'rgba(139, 195, 74, 0.85)',
        'rgba(205, 220, 57, 0.9)',
        'rgba(255, 235, 59, 0.95)',
        'rgba(255, 193, 7, 1)'
    ],

    components: {

        // Main components
        preview: true,
        opacity: true,
        hue: true,

        // Input / output Options
        interaction: {
            hex: true,
            rgba: true,
            hsla: true,
            hsva: true,
            cmyk: true,
            input: true,
            clear: true,
            save: true
        }
    }
});

You can find more examples here.

Events

Since version 0.4.x Pickr is event-driven. Use the on(event, cb) and off(event, cb) functions to bind / unbind eventlistener.

Event Description Arguments
init Initialization done - pickr can be used PickrInstance
hide Pickr got closed PickrInstance
show Pickr got opened HSVaColorObject, PickrInstance
save User clicked the save / clear button. Also fired on clear with null as color. HSVaColorObject or null, PickrInstance
clear User cleared the color. PickrInstance
change Color has changed (but not saved). Also fired on swatchselect HSVaColorObject, eventSource, PickrInstance
changestop User stopped to change the color eventSource, PickrInstance
cancel User clicked the cancel button (return to previous color). PickrInstance
swatchselect User clicked one of the swatches HSVaColorObject, PickrInstance

Example:

pickr.on('init', instance => {
    console.log('Event: "init"', instance);
}).on('hide', instance => {
    console.log('Event: "hide"', instance);
}).on('show', (color, instance) => {
    console.log('Event: "show"', color, instance);
}).on('save', (color, instance) => {
    console.log('Event: "save"', color, instance);
}).on('clear', instance => {
    console.log('Event: "clear"', instance);
}).on('change', (color, source, instance) => {
    console.log('Event: "change"', color, source, instance);
}).on('changestop', (source, instance) => {
    console.log('Event: "changestop"', source, instance);
}).on('cancel', instance => {
    console.log('Event: "cancel"', instance);
}).on('swatchselect', (color, instance) => {
    console.log('Event: "swatchselect"', color, instance);
});

Where source can be

  • slider - Any slider in the UI.
  • input - The user input field.
  • swatch - One of the swatches.

Options

const pickr = new Pickr({

    // Selector or element which will be replaced with the actual color-picker.
    // Can be a HTMLElement.
    el: '.color-picker',

    // Where the pickr-app should be added as child.
    container: 'body',

    // Which theme you want to use. Can be 'classic', 'monolith' or 'nano'
    theme: 'classic',

    // Nested scrolling is currently not supported and as this would be really sophisticated to add this
    // it's easier to set this to true which will hide pickr if the user scrolls the area behind it.
    closeOnScroll: false,

    // Custom class which gets added to the pcr-app. Can be used to apply custom styles.
    appClass: 'custom-class',

    // Don't replace 'el' Element with the pickr-button, instead use 'el' as a button.
    // If true, appendToBody will also be automatically true.
    useAsButton: false,

    // Size of gap between pickr (widget) and the corresponding reference (button) in px
    padding: 8,

    // If true pickr won't be floating, and instead will append after the in el resolved element.
    // It's possible to hide it via .hide() anyway.
    inline: false,

    // If true, pickr will be repositioned automatically on page scroll or window resize.
    // Can be set to false to make custom positioning easier.
    autoReposition: true,

    // Defines the direction in which the knobs of hue and opacity can be moved.
    // 'v' => opacity- and hue-slider can both only moved vertically.
    // 'hv' => opacity-slider can be moved horizontally and hue-slider vertically.
    // Can be used to apply custom layouts
    sliders: 'v',

    // Start state. If true 'disabled' will be added to the button's classlist.
    disabled: false,

    // If true, the user won't be able to adjust any opacity.
    // Opacity will be locked at 1 and the opacity slider will be removed.
    // The HSVaColor object also doesn't contain an alpha, so the toString() methods just
    // print HSV, HSL, RGB, HEX, etc.
    lockOpacity: false,

    // Precision of output string (only effective if components.interaction.input is true)
    outputPrecision: 0,

    // Defines change/save behavior:
    // - to keep current color in place until Save is pressed, set to `true`,
    // - to apply color to button and preview (save) in sync with each change
    //   (from picker or palette), set to `false`.
    comparison: true,

    // Default color. If you're using a named color such as red, white ... set
    // a value for defaultRepresentation too as there is no button for named-colors.
    default: '#42445a',

    // Optional color swatches. When null, swatches are disabled.
    // Types are all those which can be produced by pickr e.g. hex(a), hsv(a), hsl(a), rgb(a), cmyk, and also CSS color names like 'magenta'.
    // Example: swatches: ['#F44336', '#E91E63', '#9C27B0', '#673AB7'],
    swatches: null,

    // Default color representation of the input/output textbox.
    // Valid options are `HEX`, `RGBA`, `HSVA`, `HSLA` and `CMYK`.
    defaultRepresentation: 'HEX',

    // Option to keep the color picker always visible.
    // You can still hide / show it via 'pickr.hide()' and 'pickr.show()'.
    // The save button keeps its functionality, so still fires the onSave event when clicked.
    showAlways: false,

    // Close pickr with a keypress.
    // Default is 'Escape'. Can be the event key or code.
    // (see: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key)
    closeWithKey: 'Escape',

    // Defines the position of the color-picker.
    // Any combinations of top, left, bottom or right with one of these optional modifiers: start, middle, end
    // Examples: top-start / right-end
    // If clipping occurs, the color picker will automatically choose its position.
    // Pickr uses https://github.com/Simonwep/nanopop as positioning-engine.
    position: 'bottom-middle',

    // Enables the ability to change numbers in an input field with the scroll-wheel.
    // To use it set the cursor on a position where a number is and scroll, use ctrl to make steps of five
    adjustableNumbers: true,

    // Show or hide specific components.
    // By default only the palette (and the save button) is visible.
    components: {

        // Defines if the palette itself should be visible.
        // Will be overwritten with true if preview, opacity or hue are true
        palette: true,

        preview: true, // Display comparison between previous state and new color
        opacity: true, // Display opacity slider
        hue: true,     // Display hue slider

        // show or hide components on the bottom interaction bar.
        interaction: {

            // Buttons, if you disable one but use the format in default: or setColor() - set the representation-type too!
            hex: false,  // Display 'input/output format as hex' button  (hexadecimal representation of the rgba value)
            rgba: false, // Display 'input/output format as rgba' button (red green blue and alpha)
            hsla: false, // Display 'input/output format as hsla' button (hue saturation lightness and alpha)
            hsva: false, // Display 'input/output format as hsva' button (hue saturation value and alpha)
            cmyk: false, // Display 'input/output format as cmyk' button (cyan mangenta yellow key )

            input: false, // Display input/output textbox which shows the selected color value.
                         // the format of the input is determined by defaultRepresentation,
                         // and can be changed by the user with the buttons set by hex, rgba, hsla, etc (above).
            cancel: false, // Display Cancel Button, resets the color to the previous state
            clear: false, // Display Clear Button; same as cancel, but keeps the window open
            save: false,  // Display Save Button,
        },
    },

    // Translations, these are the default values.
    i18n: {

        // Strings visible in the UI
       'ui:dialog': 'color picker dialog',
       'btn:toggle': 'toggle color picker dialog',
       'btn:swatch': 'color swatch',
       'btn:last-color': 'use previous color',
       'btn:save': 'Save',
       'btn:cancel': 'Cancel',
       'btn:clear': 'Clear',

       // Strings used for aria-labels
       'aria:btn:save': 'save and close',
       'aria:btn:cancel': 'cancel and close',
       'aria:btn:clear': 'clear and close',
       'aria:input': 'color input field',
       'aria:palette': 'color selection area',
       'aria:hue': 'hue selection slider',
       'aria:opacity': 'selection slider'
    }
});

Selection through a Shadow-DOM

Example setup:

<div class="entry">
  #shadow-root
    <div class="innr">
       <div class="another">
         #shadow-root
           <div class="pickr"></div>
       </div>
    </div>
</div>

To select the .pickr element you can use the custom >> shadow-dom-selector in el:

el: '.entry >> .innr .another >> .pickr'

Every ShadowRoot of the query-result behind a >> gets used in the next query selection. An alternative would be to provide the target-element itself as el.

The HSVaColor object

As default color representation is hsva (hue, saturation, value and alpha) used, but you can also convert it to other formats as listed below.

  • hsva.toHSVA() - Converts the object to a hsva array.
  • hsva.toHSLA() - Converts the object to a hsla array.
  • hsva.toRGBA() - Converts the object to a rgba array.
  • hsva.toHEXA() - Converts the object to a hexa-decimal array.
  • hsva.toCMYK() - Converts the object to a cmyk array.
  • hsva.clone() - Clones the color object.

The toString() is overridden, so you can get a color representation string.

hsva.toRGBA(); // Returns [r, g, b, a]
hsva.toRGBA().toString(); // Returns rgba(r, g, b, a) with highest precision
hsva.toRGBA().toString(3); // Returns rgba(r, g, b, a), rounded to the third decimal

Methods

  • pickr.setHSVA(h:Number,s:Number,v:Number,a:Float, silent:Boolean) - Set an color, returns true if the color has been accepted.
  • pickr.setColor(str: :String | null, silent:Boolean):Boolean - Parses a string which represents a color (e.g. #fff, rgb(10, 156, 23)) or name e.g. 'magenta', returns true if the color has been accepted. null will clear the color.

If silent is true (Default is false), the button won't change the current color.

  • pickr.on(event:String, cb:Function):Pickr - Appends an event listener to the given corresponding event-name (see section Events).
  • pickr.off(event:String, cb:Function):Pickr - Removes an event listener from the given corresponding event-name (see section Events).
  • pickr.show():Pickr - Shows the color-picker.
  • pickr.hide():Pickr - Hides the color-picker.
  • pickr.disable():Pickr - Disables pickr and adds the disabled class to the button.
  • pickr.enable():Pickr - Enables pickr and removes the disabled class from the button.
  • pickr.isOpen():Pickr - Returns true if the color picker is currently open.
  • pickr.getRoot():Object - Returns the dom-tree of pickr as tree-structure.
  • pickr.getColor():HSVaColor - Returns the current HSVaColor object.
  • pickr.getSelectedColor():HSVaColor - Returns the currently applied color.
  • pickr.destroy() - Destroys all functionality.
  • pickr.destroyAndRemove() - Destroys all functionality and removes the pickr element including the button.
  • pickr.setColorRepresentation(type:String):Boolean - Change the current color-representation. Valid options are HEX, RGBA, HSVA, HSLA and CMYK, returns false if type was invalid.
  • pickr.getColorRepresentation():String - Returns the currently used color-representation (eg. HEXA, RGBA...)
  • pickr.applyColor(silent:Boolean):Pickr - Same as pressing the save button. If silent is true the onSave event won't be called.
  • pickr.addSwatch(color:String):Boolean - Adds a color to the swatch palette. Returns true if the color has been successful added to the palette.
  • pickr.removeSwatch(index:Number):Boolean- Removes a color from the swatch palette by its index, returns true if successful.

Static methods

Pickr

  • create(options:Object):Pickr - Creates a new instance.

Pickr.utils

  • once(element:HTMLElement, event:String, fn:Function[, options :Object]) - Attach an event handle which will be fired only once
  • on(elements:HTMLElement(s), events:String(s), fn:Function[, options :Object]) - Attach an event handler function.
  • off(elements:HTMLElement(s), event:String(s), fn:Function[, options :Object]) - Remove an event handler.
  • createElementFromString(html:String):HTMLElement - Creates an new HTML Element out of this string.
  • eventPath(evt:Event):[HTMLElement] - A polyfill for the event-path event propery.
  • createFromTemplate(str:String) - See inline doumentation.
  • resolveElement(val:String|HTMLElement) - Resolves a HTMLElement, supports >>> as shadow dom selector.
  • adjustableInputNumbers(el:InputElement, mapper:Function) - Creates the possibility to change the numbers in an inputfield via mouse scrolling. The mapper function takes three arguments: the matched number, an multiplier and the index of the match.

Use this utils carefully, it's not for sure that they will stay forever!

Static properties

  • version - The current version.
  • I18N_DEFAULTS - i18n default values.
  • DEFAULT_OPTIONS - Default options (Do not override this property itself, only change properties of it!).

FAQ

How do I initialize multiple pickr's? Can I access the instance via class or id?

No, you can't. You need to keep track of your instance variables - pickr is (not yet) a web-component. The best option would be to create new elements via document.createElement and directly pass it as el. example.

I want to use pickr in a form, how can I do that?

You can use useAsButton: true and pass a reference (or selector) of your input-element as el. Then you can update the input-element whenever a change was made. example.

I want to update options after mounting pickr, is that possible?

Unfortunately not. The core-code of this project is rather old (over 2 years), and I made it in my early js-days - the widget is not able to dynamically re-render itself in that way. You have to destroy and re-initialize it.

Contributing

If you want to open a issue, create a Pull Request or simply want to know how you can run it on your local machine, please read the Contributing guide.

More Repositories

1

selection

✨ Viselect - A high performance and lightweight library to add a visual way of selecting elements, just like on your Desktop. Zero dependencies, super small. Support for major frameworks!
TypeScript
2,494
star
2

nanopop

🍦 Minimalistic, small, positioning engine. Build for high-performance, minimal footprint and maximum control over positioning behavior.
TypeScript
643
star
3

candy

🍭 Cross-platform YouTube-downloader with playlist and channel support as well as build-in audio / video converter.
Vue
237
star
4

java-express

πŸ§ͺ HTTP Framework based on expressjs, no dependencies, simple usage. Can be used to quickly spin up an API or serve local files.
Java
196
star
5

presentr

Minimalistic javascript presentation-library. Zero dependencies. Can be used in combination with frameworks like Bootstrap, Materialize, Vue etc.
JavaScript
71
star
6

openvpn-pihole

πŸ•΅οΈ A truly delicious combination of two wonderful pieces of software to setup a pi.hole-backed VPN as quick as possible.
Shell
68
star
7

gpickr

Demo of pickr integrated into another widget. A gradient-picker.
JavaScript
60
star
8

ocular

πŸ’° Simplistic, beautiful and straight-forward budgeting app to track your budget across the years. Easy to use, to get started and to set up.
Vue
59
star
9

sassyfication

πŸ’…Library with sass mixins to speed up your css workflow.
SCSS
58
star
10

graceful-ws

πŸ”Œ Graceful WebSocket wrapper with connection re-establishment capabilities.
TypeScript
41
star
11

li18nt

🌎 Lint your i18n translation files. Detect conflicting properties, duplicates and make it more readable and easier to maintain by formatting it!
TypeScript
38
star
12

nason

πŸ“¦ Ultra tiny serializer / encoder with plugin-support. Useful to build binary files containing images, strings, numbers and more!
TypeScript
35
star
13

vite-plugin-optimize-css-modules

πŸ—œ Mangle / minimize css module classnames in production like facebook and Google do!
TypeScript
28
star
14

cinematic

πŸ“½οΈ Ultra tiny library to add cinematics to your HTML5 videos!
TypeScript
22
star
15

conway

πŸ•Ή Supercharged version of conways game-of-life brought to life by wasm and workers.
TypeScript
12
star
16

spectrum

πŸŽ™οΈ Fast, installable, in-browser audio spectrum visualizer. Support for both realtime and audio files!
TypeScript
11
star
17

bavary

🧬 Regular expressions on steroids. Parse anything and everything with a syntax - crafted to parse syntax. A super-set of regular-expressions.
TypeScript
10
star
18

eslint-plugin-align-import

βš™ ESLint plugin to align all your import statements.
JavaScript
8
star
19

ocular-docker

Ready-to-use docker compose setup for ocular ✨
Shell
8
star
20

widgetify

Simple widget library which helps to quickly create a new, responsive, interactive widget or ui tool.
JavaScript
7
star
21

intl-demo

Interactive demo of the ECMAScript Internationalization API
JavaScript
5
star
22

yuppee

βš™οΈ Type-safe migration library to migrate data from one schema to another.
TypeScript
4
star
23

reinisch.io

πŸ”² My Personal Homepage :)
TypeScript
3
star
24

reactivity-playground

πŸ’« Simple recreation of reactivity as its mainly used in Vue3
TypeScript
3
star
25

cssvjs

Fast, spec-conform css-value parser written entirely in vanilla JavaScript. Can be used in any environment.
JavaScript
3
star
26

cleanup-files

🧼 Small utilities to cleanup directories such as download which are all the time full of random stuff.
Rust
1
star
27

genesis

🧞 A simple, generic, fast and lightweight json api for frontend apps. Store your frontend-data as-is without messing around with a database!
Go
1
star
28

bavary-webpack-loader

Webpack loader for bavary declarations
JavaScript
1
star
29

eslint-config-simon

βš™ Eslint config files for my personal projects.
JavaScript
1
star
30

previous-index-of

Find the previous index of a char-sequence at a given offset in a string
JavaScript
1
star
31

bavary-cli

Bavary CLI
TypeScript
1
star