HelpBot Assistant

How can I help you?

Handle no color support in React Color picker component

21 Feb 202618 minutes to read

The ColorPicker component supports a no-color feature. When you click the no-color tile in the palette, the selected color becomes empty, indicating that no color has been selected.

Default no color

To enable this feature, set the noColor property to true.

In the following sample, the first tile of the palette represents the no-color option. Click it to clear the color selection.

import { ColorPickerComponent } from '@syncfusion/ej2-react-inputs';
import * as React from "react";
import * as ReactDOM from "react-dom";
import { useEffect } from "react";
function App() {
    let preview;
    function onChange(args) {
        preview.style.backgroundColor = args.currentValue.hex;
        preview.textContent = args.currentValue.hex ? args.currentValue.hex : 'No color';
    }
    useEffect(() => {
        preview = document.getElementById('preview');
        preview.style.backgroundColor = '#ba68c8';
        preview.textContent = '#ba68c8';
    }, []);
    return (<div id='container'>
        <div className='wrap'>
            <div id='preview'/>
            <h4>Select Color</h4>
            <ColorPickerComponent id='colorpicker' value='#ba68c8' mode='Palette' noColor={true} showButtons={false} modeSwitcher={false} change={onChange}/>
        </div>
        </div>);
}
export default App;
ReactDOM.render(<App />, document.getElementById('element'));
import { ColorPickerComponent, ColorPickerEventArgs } from '@syncfusion/ej2-react-inputs';
import * as React from "react";
import * as ReactDOM from "react-dom";
import { useEffect } from "react";

function App() {
    let preview: HTMLElement;
    function onChange (args: ColorPickerEventArgs): void {
        preview.style.backgroundColor = args.currentValue.hex;
        preview.textContent = args.currentValue.hex ? args.currentValue.hex : 'No color';
    }

    useEffect(() => {
        preview = document.getElementById('preview') as HTMLElement;
        preview.style.backgroundColor = '#ba68c8';
        preview.textContent = '#ba68c8';
    }, []);

    return (
        <div id='container'>
        <div className='wrap'>
            <div id='preview'/>
            <h4>Select Color</h4>
            <ColorPickerComponent id='colorpicker' value='#ba68c8' mode='Palette' noColor={true} showButtons={false} modeSwitcher={false} change={onChange}/>
        </div>
        </div>
    );
}
export default App;
ReactDOM.render(<App />, document.getElementById('element'));

When the noColor property is enabled, ensure that the modeSwitcher property is disabled.

Custom no color

The following sample shows the palette with a custom no-color option.

import * as React from "react";
import * as ReactDOM from "react-dom";
import { ColorPickerComponent, PaletteTileEventArgs, ColorPickerEventArgs } from '@syncfusion/ej2-react-inputs';
import { SplitButtonComponent } from '@syncfusion/ej2-react-splitbuttons';

function App() {
    let preview;
    let splitBtn;
    let colorPicker;

    let presets = {
        'custom': ['#f44336', '#e91e63', '#9c27b0', '#673ab7', '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#8bc34a', '#cddc39', '#ffeb3b', '#ffc107']
    };

    function beforeTileRender(args) {
        args.element.classList.add('e-custom-tile');
    }

    function onChange (args) {
        preview = document.getElementById('preview');
        document.querySelector(".e-split-btn .e-picker-icon").style.borderBottomColor = args.currentValue.hex;
        preview.style.backgroundColor = args.currentValue.hex;
        preview.textContent = args.currentValue.hex;
        if (splitBtn.element.getAttribute("aria-expanded")) {
            splitBtn.toggle();
            splitBtn.element.focus();
        }
    }

    function onCreated() {
        preview = document.getElementById('preview');
        preview.style.backgroundColor = '#ba68c8';
        preview.textContent = '#ba68c8';
        document.getElementById('no-color').onclick = () => {
            //sets color picker value property to null
            colorPicker.setProperties({ 'value': '' }, true);
            document.querySelector('.e-split-btn .e-picker-icon').style.borderBottomColor = 'transparent';
            preview.textContent = 'No color';
            preview.style.backgroundColor = 'transparent';
        }
    }

    return (
        <div id='container'>
        <div className='wrap'>
            <ul id="target">
                <li className="e-item e-palette-item">
                    <ColorPickerComponent id='colorpicker' ref={(scope) => { colorPicker = scope; }} value='#f44336' mode='Palette' inline={true} columns={4} presetColors={presets} showButtons={false} modeSwitcher={false} beforeTileRender={beforeTileRender} change={onChange} created={onCreated}></ColorPickerComponent>
                </li>
                <li className="e-item" id="no-color">
                    <span className="e-menu-icon e-nocolor"></span>
                    No color
                </li>
            </ul>
            <div>
                <div id='preview'></div>
                <h4>Select color</h4>
                <SplitButtonComponent id='splitbtn' iconCss='e-cp-icons e-picker-icon' target='#target' ref={(scope) => { splitBtn = scope; }}></SplitButtonComponent>
            </div>
        </div>
        </div>
    );
}
export default App;
ReactDOM.render(<App />, document.getElementById('element'));
import * as React from "react";
import * as ReactDOM from "react-dom";
import { ColorPickerComponent, PaletteTileEventArgs, ColorPickerEventArgs } from '@syncfusion/ej2-react-inputs';
import { SplitButtonComponent } from '@syncfusion/ej2-react-splitbuttons';

function App() {
    let preview: HTMLElement;
    let splitBtn: SplitButtonComponent;
    let colorPicker: ColorPickerComponent;

    let presets: { [key: string]: string[] } = {
        'custom': ['#f44336', '#e91e63', '#9c27b0', '#673ab7', '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#8bc34a', '#cddc39', '#ffeb3b', '#ffc107']
    };

    function beforeTileRender(args: PaletteTileEventArgs): void {
        args.element.classList.add('e-custom-tile');
    }

    function onChange (args: ColorPickerEventArgs): void {
        preview = document.getElementById('preview') as HTMLElement;
        (document.querySelector(".e-split-btn .e-picker-icon") as HTMLElement).style.borderBottomColor = args.currentValue.hex;
        preview.style.backgroundColor = args.currentValue.hex;
        preview.textContent = args.currentValue.hex;
        if (splitBtn.element.getAttribute("aria-expanded")) {
            splitBtn.toggle();
            splitBtn.element.focus();
        }
    }

    function onCreated(): void {
        preview = document.getElementById('preview') as HTMLElement;
        preview.style.backgroundColor = '#ba68c8';
        preview.textContent = '#ba68c8';
        document.getElementById('no-color')!.onclick = (): void => {
            //sets color picker value property to null
            colorPicker.setProperties({ 'value': '' }, true);
            (document.querySelector('.e-split-btn .e-picker-icon') as HTMLElement).style.borderBottomColor = 'transparent';
            preview.textContent = 'No color';
            preview.style.backgroundColor = 'transparent';
        }
    }

    return (
        <div id='container'>
        <div className='wrap'>
            <ul id="target">
                <li className="e-item e-palette-item">
                    <ColorPickerComponent id='colorpicker' ref={(scope) => { colorPicker = scope as ColorPickerComponent; }} value='#f44336' mode='Palette' inline={true} columns={4} presetColors={presets} showButtons={false} modeSwitcher={false} beforeTileRender={beforeTileRender} change={onChange} created={onCreated}></ColorPickerComponent>
                </li>
                <li className="e-item" id="no-color">
                    <span className="e-menu-icon e-nocolor"></span>
                    No color
                </li>
            </ul>
            <div>
                <div id='preview'></div>
                <h4>Select color</h4>
                <SplitButtonComponent id='splitbtn' iconCss='e-cp-icons e-picker-icon' target='#target' ref={(scope) => { splitBtn = scope as SplitButtonComponent; }}></SplitButtonComponent>
            </div>
        </div>
        </div>
    );
}

export default App;
ReactDOM.render(<App />, document.getElementById('element'));
#loader {
    color: #008cff;
    font-family: 'Helvetica Neue', 'calibiri';
    font-size: 14px;
    height: 40px;
    left: 45%;
    position: absolute;
    top: 45%;
    width: 30%;
}

@font-face {
font-family: 'paint';
src:
url(data:application/x-font-ttf;charset=utf-8;base64,AAEAAAAKAIAAAwAgT1MvMj0gSRIAAAEoAAAAVmNtYXDnEOdVAAABiAAAADZnbHlmIZD+uwAAAcgAAADMaGVhZBKhhHQAAADQAAAANmhoZWEHjANrAAAArAAAACRobXR4B+j/8wAAAYAAAAAIbG9jYQBmAAAAAAHAAAAABm1heHABDgBKAAABCAAAACBuYW1ln6hzswAAApQAAAINcG9zdEkLMmUAAASkAAAANgABAAADUv9qAFoEAP/z//4D6gABAAAAAAAAAAAAAAAAAAAAAgABAAAAAQAAAZfc6F8PPPUACwPoAAAAANfSn9kAAAAA19Kf2f/z//wD6gPhAAAACAACAAAAAAAAAAEAAAACAD4AAgAAAAAAAgAAAAoACgAAAP8AAAAAAAAAAQP0AZAABQAAAnoCvAAAAIwCegK8AAAB4AAxAQIAAAIABQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUGZFZABA5wDnAANS/2oAWgPhAJYAAAABAAAAAAAABAAAAAPo//MAAAACAAAAAwAAABQAAwABAAAAFAAEACIAAAAEAAQAAQAA5wD//wAA5wD//wAAAAEABAAAAAEAAAAAAAAAZgAAAAL/8//8A+oD4QAKAD0AAAEWBgceATc1JiQHJTMmNjceARcVJx4BBx4BFQ4BIiYnNDY3PgEvAS4BIw4BBwEGHgI3AT4BLwE1LgEnDgEDeiRlCgulCxP+8RT+GyYDQFxOZQwTBQEDDxEBJzonAREOCQkPJQ4cDBcdAf6oG1a3nx8BWQ4RHKADeG1oWwHTLHVwYVmL6Kx1BHEqfwYFqWUHEx4tDAocEx0nJx0RHgoVUDQpDgsBFAH+px2guFUaAVkNOiCgCXnhCAWOAAAAAAAAEgDeAAEAAAAAAAAAAQAAAAEAAAAAAAEABQABAAEAAAAAAAIABwAGAAEAAAAAAAMABQANAAEAAAAAAAQABQASAAEAAAAAAAUACwAXAAEAAAAAAAYABQAiAAEAAAAAAAoALAAnAAEAAAAAAAsAEgBTAAMAAQQJAAAAAgBlAAMAAQQJAAEACgBnAAMAAQQJAAIADgBxAAMAAQQJAAMACgB/AAMAAQQJAAQACgCJAAMAAQQJAAUAFgCTAAMAAQQJAAYACgCpAAMAAQQJAAoAWACzAAMAAQQJAAsAJAELIHBhaW50UmVndWxhcnBhaW50cGFpbnRWZXJzaW9uIDEuMHBhaW50Rm9udCBnZW5lcmF0ZWQgdXNpbmcgU3luY2Z1c2lvbiBNZXRybyBTdHVkaW93d3cuc3luY2Z1c2lvbi5jb20AIABwAGEAaQBuAHQAUgBlAGcAdQBsAGEAcgBwAGEAaQBuAHQAcABhAGkAbgB0AFYAZQByAHMAaQBvAG4AIAAxAC4AMABwAGEAaQBuAHQARgBvAG4AdAAgAGcAZQBuAGUAcgBhAHQAZQBkACAAdQBzAGkAbgBnACAAUwB5AG4AYwBmAHUAcwBpAG8AbgAgAE0AZQB0AHIAbwAgAFMAdAB1AGQAaQBvAHcAdwB3AC4AcwB5AG4AYwBmAHUAcwBpAG8AbgAuAGMAbwBtAAAAAAIAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgECAQMADHBhaW50LWJ1Y2tldAAAAAA=) format('truetype');
font-weight: normal;
font-style: normal;
}

.e-cp-icons {
 font-family: 'paint' !important;
speak: none;
font-size: 55px;
font-style: normal;
font-weight: normal;
font-variant: normal;
text-transform: none;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

/* Preview area styles */
#preview {
  border: 1px solid;
  height: 40px;
  line-height: 40px;
  width: 100%;
}

.wrap {
  margin: 0 auto;
  width: 300px;
  text-align: center;
}

/* ColorPicker customization */
.e-dropdown-popup ul#target {
  padding: 0;
}

.e-dropdown-popup ul .e-item.e-palette-item {
  height: auto;
  padding: 0;
}

.e-btn-icon.e-picker-icon {
  border-bottom-color: #f44336;
  border-bottom-style: solid;
  border-bottom-width: 3px;
}

/* Picker icon */
.e-btn-icon.e-picker-icon::before {
  content: '\e700';
}

/* No color li styles */
.e-dropdown-popup ul .e-item .e-menu-icon.e-nocolor {
  height: 22px;
  margin-top: 8px;
  width: 22px;
  background: transparent url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyB3aWR0aD0iNnB4IiBoZWlnaHQ9IjZweCIgdmlld0JveD0iMCAwIDYgNiIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4KICAgIDwhLS0gR2VuZXJhdG9yOiBTa2V0Y2ggNTAgKDU0OTgzKSAtIGh0dHA6Ly93d3cuYm9oZW1pYW5jb2RpbmcuY29tL3NrZXRjaCAtLT4KICAgIDx0aXRsZT5Hcm91cCA5PC90aXRsZT4KICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPgogICAgPGRlZnM+PC9kZWZzPgogICAgPGcgaWQ9IlBhZ2UtMSIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+CiAgICAgICAgPGcgaWQ9Ikdyb3VwLTkiPgogICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLTExIiBmaWxsPSIjRTBFMEUwIiB4PSIwIiB5PSIwIiB3aWR0aD0iMyIgaGVpZ2h0PSIzIj48L3JlY3Q+CiAgICAgICAgICAgIDxyZWN0IGlkPSJSZWN0YW5nbGUtMTEtQ29weS0yIiBmaWxsPSIjRkZGRkZGIiB4PSIwIiB5PSIzIiB3aWR0aD0iMyIgaGVpZ2h0PSIzIj48L3JlY3Q+CiAgICAgICAgICAgIDxyZWN0IGlkPSJSZWN0YW5nbGUtMTEtQ29weSIgZmlsbD0iI0ZGRkZGRiIgeD0iMyIgeT0iMCIgd2lkdGg9IjMiIGhlaWdodD0iMyI+PC9yZWN0PgogICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLTExLUNvcHktMyIgZmlsbD0iI0UwRTBFMCIgeD0iMyIgeT0iMyIgd2lkdGg9IjMiIGhlaWdodD0iMyI+PC9yZWN0PgogICAgICAgIDwvZz4KICAgIDwvZz4KPC9zdmc+');
}

/* Tile customization */
.e-container .e-palette .e-tile.e-custom-tile {
  height: 24px;
  width: 24px;
  margin: 4px;
}

h4, #preview {
    font-family: 'Helvetica Neue', 'Helvetica', 'Arial', 'sans-serif';
    font-size: 14px;
}