Customize color picker

Is it possible to customize the color picker? I want to set predefined colors.

Image_3239_1782713530225


3 Replies

JA Jafar Ali Shahulhameed Syncfusion Team June 29, 2026 10:59 AM UTC

Hi Jackson,


Yes, it is possible to customize the Syncfusion JavaScript ColorPicker to display predefined colors using the presetColors property. Additionally, the modeSwitcher property allows users to toggle between Palette (predefined colors) and Picker (full gradient UI).

This approach helps provide a controlled set of colors while still giving flexibility for advanced color selection. Refer the code changes below,

Code snippet:

let colorPicker: ColorPicker = new ColorPicker(

  {

    mode: 'Palette',

    modeSwitcher: true, // Enables toggle between Palette & Picker

    presetColors: {

      'Custom Colors': [

        '#000000', '#333333', '#666666','#999999', '#CCCCCC',

        '#FFFFFF', '#FF0000', '#00FF00', '#0000FF', '#FFFF00',

        '#FF00FF', '#00FFFF', '#800000', '#008000', '#000080',

        '#808000', '#800080', '#008080', '#FFA500', '#A52A2A',

      ],

    },

  },

  '#color-picker'

);


Workflow of the Code

  1. Initialize Component
    The ColorPicker is initialized and attached to the input element.
  2. Set Mode as Palette
    mode: 'Palette' ensures predefined colors are shown initially.
  3. Define Predefined Colors
    presetColors creates a collection of selectable color blocks arranged in a grid.
  4. Enable Mode Switching
    modeSwitcher: true adds a toggle button:
    • Switch to Picker mode → full gradient + HEX/RGB input
    • Switch back to Palette mode → predefined colors
  5. Rendering
    The component automatically adjusts layout based on number of colors, forming a multi-row palette.


Screenshot:


Sample: https://stackblitz.com/edit/38yhvd9k-vxk1xrxd?file=index.ts,index.html


Refer the below documentations for more details,

preserColors: https://ej2.syncfusion.com/documentation/api/color-picker/index-default#presetcolors

modeSwitcher: https://ej2.syncfusion.com/documentation/api/color-picker/index-default#modeswitcher


Check out the shared details and get back to us if you need further assistance.


Regards,

Jafar Ali S



JT Jackson Tong June 30, 2026 05:06 AM UTC

Hi Jafar,

Could you please give example in the PDF viewer? Also is it possible to add color palette in context menu (red, black, green) to quickly change annotation color?



PK Priyanka Karthikeyan Syncfusion Team July 6, 2026 09:25 AM UTC

Hi Jackson,
Thank you for your inquiry! We've successfully implemented a customized ColorPicker solution with predefined colors for your PDF viewer annotation use case.
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>PDF Viewer with Color Picker and Annotation Context Menu</title>
        
        <script src="https://cdn.syncfusion.com/ej2/34.1.29/dist/ej2.min.js" type="text/javascript"></script>
        <link rel='nofollow' href="https://cdn.syncfusion.com/ej2/34.1.29/tailwind3.css" rel="stylesheet">
    
        <link rel='nofollow' href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    
        <!-- PDF.js -->
        <script src="https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.11.174/pdf.min.js"></script>
        
        <!-- Syncfusion EJ2 Scripts -->
        <script src="https://cdn.jsdelivr.net/npm/@syncfusion/ej2-base@latest/dist/global.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/@syncfusion/ej2-buttons@latest/dist/global.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/@syncfusion/ej2-splitbuttons@latest/dist/global.js"></script>
        
        <style>
            * {
                margin: 0;
                padding: 0;
                box-sizing: border-box;
            }
            
            body {
                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
                background-color: #f5f5f5;
                padding: 20px;
            }
            
            .container {
                max-width: 1200px;
                margin: 0 auto;
                background: white;
                border-radius: 8px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.1);
                overflow: hidden;
            }
            
            .toolbar {
                background: #f8f9fa;
                padding: 15px 20px;
                border-bottom: 1px solid #ddd;
                display: flex;
                gap: 20px;
                align-items: center;
                flex-wrap: wrap;
            }
            
            .toolbar-group {
                display: flex;
                gap: 10px;
                align-items: center;
            }
            
            .toolbar-label {
                font-weight: 600;
                color: #333;
                font-size: 14px;
            }
            
            .color-palette {
                display: flex;
                gap: 8px;
            }
            
            .color-btn {
                width: 30px;
                height: 30px;
                border: 2px solid #ddd;
                border-radius: 4px;
                cursor: pointer;
                transition: all 0.2s;
            }
            
            .color-btn:hover {
                transform: scale(1.1);
                border-color: #333;
            }
            
            .color-btn.active {
                border-color: #333;
                box-shadow: 0 0 8px rgba(0,0,0,0.3);
            }
            
            .pdf-container {
                display: flex;
                height: 600px;
                background: #e9ecef;
                position: relative;
                overflow: auto;
            }
            
            #pdf-canvas {
                margin: auto;
                background: white;
                box-shadow: 0 0 10px rgba(0,0,0,0.1);
            }
            
            .annotation-highlight {
                position: absolute;
                opacity: 0.3;
                cursor: pointer;
                border: 2px solid;
            }
            
            .annotation-highlight:hover {
                opacity: 0.5;
            }
            
            .context-menu {
                position: absolute;
                background: white;
                border: 1px solid #ddd;
                border-radius: 4px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.15);
                z-index: 1000;
                min-width: 150px;
                display: none;
            }
            
            .context-menu.active {
                display: block;
            }
            
            .context-menu-item {
                padding: 10px 15px;
                cursor: pointer;
                display: flex;
                align-items: center;
                gap: 10px;
                transition: background 0.2s;
            }
            
            .context-menu-item:hover {
                background: #f0f0f0;
            }
            
            .color-dot {
                width: 16px;
                height: 16px;
                border-radius: 2px;
            }
            
            .info-box {
                padding: 20px;
                text-align: center;
                color: #666;
            }
            
            .ej2-colorpicker {
                margin: 0;
            }
        </style>
    </head>
    <body>
        <div class="container">
            <div class="toolbar">
                <!-- Annotation Color Selector -->
                <div class="toolbar-group">
                    <label class="toolbar-label">Annotation Color:</label>
                    <div class="color-palette">
                        <button class="color-btn active" data-color="#FF0000" style="background-color: #FF0000;" title="Red"></button>
                        <button class="color-btn" data-color="#000000" style="background-color: #000000;" title="Black"></button>
                        <button class="color-btn" data-color="#00AA00" style="background-color: #00AA00;" title="Green"></button>
                        <button class="color-btn" data-color="#0000FF" style="background-color: #0000FF;" title="Blue"></button>
                        <button class="color-btn" data-color="#FFFF00" style="background-color: #FFFF00;" title="Yellow"></button>
                    </div>
                </div>
                
                <!-- ColorPicker Component -->
                <div class="toolbar-group">
                    <label class="toolbar-label">Advanced Color:</label>
                    <input type="text" id="colorpicker" name="colorpicker">
                </div>
            </div>
            
            <div class="pdf-container">
                <canvas id="pdf-canvas"></canvas>
                <div class="info-box">
                    <p>Demo PDF Canvas</p>
                    <p style="font-size: 12px; margin-top: 10px;">Right-click on the canvas to add annotations</p>
                </div>
            </div>
        </div>
        
        <!-- Context Menu -->
        <div class="context-menu" id="contextMenu">
            <div class="context-menu-item" data-color="#FF0000">
                <div class="color-dot" style="background-color: #FF0000;"></div>
                <span>Red</span>
            </div>
            <div class="context-menu-item" data-color="#000000">
                <div class="color-dot" style="background-color: #000000;"></div>
                <span>Black</span>
            </div>
            <div class="context-menu-item" data-color="#00AA00">
                <div class="color-dot" style="background-color: #00AA00;"></div>
                <span>Green</span>
            </div>
            <div class="context-menu-item" data-color="#0000FF">
                <div class="color-dot" style="background-color: #0000FF;"></div>
                <span>Blue</span>
            </div>
        </div>
    
        <script>
            // Initialize ColorPicker with predefined colors
            let colorPicker = new ej.inputs.ColorPicker(
                {
                    mode: 'Palette',
                    modeSwitcher: true,
                    presetColors: {
                        'Annotation Colors': [
                            '#FF0000', '#000000', '#00AA00', '#0000FF', '#FFFF00',
                            '#FF00FF', '#00FFFF', '#FFA500', '#A52A2A', '#808080'
                        ],
                        'Standard Colors': [
                            '#000000', '#333333', '#666666', '#999999', '#CCCCCC',
                            '#FFFFFF', '#FF0000', '#00FF00', '#0000FF'
                        ]
                    },
                    change: (args) => {
                        currentColor = args.value;
                        updateActiveButton();
                    }
                },
                '#colorpicker'
            );
    
            // Global state
            let currentColor = '#FF0000';
            let annotations = [];
            let selectedAnnotationIndex = null;
            const canvas = document.getElementById('pdf-canvas');
            const contextMenu = document.getElementById('contextMenu');
            const pdfContainer = document.querySelector('.pdf-container');
    
            // Draw sample PDF-like content
            function initializeCanvas() {
                canvas.width = 600;
                canvas.height = 800;
                const ctx = canvas.getContext('2d');
                
                // White background
                ctx.fillStyle = '#FFFFFF';
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                
                // Border
                ctx.strokeStyle = '#999';
                ctx.lineWidth = 2;
                ctx.strokeRect(10, 10, canvas.width - 20, canvas.height - 20);
                
                // Sample text
                ctx.fillStyle = '#000000';
                ctx.font = 'bold 24px Arial';
                ctx.fillText('Sample PDF Document', 50, 60);
                
                ctx.font = '14px Arial';
                ctx.fillText('This is a demo PDF viewer with annotation support.', 50, 100);
                ctx.fillText('Right-click on the canvas to add or modify annotations.', 50, 130);
                
                // Sample content
                ctx.font = '12px Arial';
                let y = 180;
                const text = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris.';
                const words = text.split(' ');
                let line = '';
                
                for (let word of words) {
                    let testLine = line + word + ' ';
                    let metrics = ctx.measureText(testLine);
                    if (metrics.width > 500) {
                        ctx.fillText(line, 50, y);
                        line = word + ' ';
                        y += 20;
                    } else {
                        line = testLine;
                    }
                }
                ctx.fillText(line, 50, y);
            }
    
            // Add annotation to canvas
            function addAnnotation(x, y, width, height, color) {
                const rect = canvas.getBoundingClientRect();
                const annotation = {
                    x: x - rect.left,
                    y: y - rect.top,
                    width: width,
                    height: height,
                    color: color,
                    id: annotations.length
                };
                annotations.push(annotation);
                renderAnnotations();
                return annotation.id;
            }
    
            // Render all annotations
            function renderAnnotations() {
                const rect = canvas.getBoundingClientRect();
                pdfContainer.querySelectorAll('.annotation-highlight').forEach(el => el.remove());
                
                annotations.forEach((ann, index) => {
                    const div = document.createElement('div');
                    div.className = 'annotation-highlight';
                    div.style.left = (rect.left + ann.x) + 'px';
                    div.style.top = (rect.top + ann.y) + 'px';
                    div.style.width = ann.width + 'px';
                    div.style.height = ann.height + 'px';
                    div.style.backgroundColor = ann.color;
                    div.style.borderColor = ann.color;
                    div.dataset.index = index;
                    
                    div.addEventListener('contextmenu', (e) => showContextMenu(e, index));
                    div.addEventListener('click', () => selectAnnotation(index));
                    
                    pdfContainer.appendChild(div);
                });
            }
    
            // Select annotation
            function selectAnnotation(index) {
                selectedAnnotationIndex = index;
                currentColor = annotations[index].color;
                updateActiveButton();
            }
    
            // Show context menu
            function showContextMenu(e, annotationIndex) {
                e.preventDefault();
                e.stopPropagation();
                
                selectedAnnotationIndex = annotationIndex;
                contextMenu.style.left = e.clientX + 'px';
                contextMenu.style.top = e.clientY + 'px';
                contextMenu.classList.add('active');
            }
    
            // Hide context menu
            function hideContextMenu() {
                contextMenu.classList.remove('active');
            }
    
            // Update active button in toolbar
            function updateActiveButton() {
                document.querySelectorAll('.color-palette .color-btn').forEach(btn => {
                    btn.classList.remove('active');
                    if (btn.dataset.color === currentColor) {
                        btn.classList.add('active');
                    }
                });
            }
    
            // Color palette buttons
            document.querySelectorAll('.color-palette .color-btn').forEach(btn => {
                btn.addEventListener('click', (e) => {
                    currentColor = e.target.dataset.color;
                    updateActiveButton();
                });
            });
    
            // Context menu items
            document.querySelectorAll('.context-menu-item').forEach(item => {
                item.addEventListener('click', (e) => {
                    const color = e.currentTarget.dataset.color;
                    if (selectedAnnotationIndex !== null) {
                        annotations[selectedAnnotationIndex].color = color;
                        currentColor = color;
                        updateActiveButton();
                        renderAnnotations();
                    }
                    hideContextMenu();
                });
            });
    
            // Right-click on canvas to add annotation
            canvas.addEventListener('contextmenu', (e) => {
                e.preventDefault();
                
                // Add sample annotation
                const rect = canvas.getBoundingClientRect();
                const x = e.clientX - rect.left;
                const y = e.clientY - rect.top;
                
                addAnnotation(e.clientX, e.clientY, 100, 40, currentColor);
            });
    
            // Click outside to close context menu
            document.addEventListener('click', hideContextMenu);
    
            // Initialize
            initializeCanvas();
            renderAnnotations();
        </script>
    </body>
    </html>
    
Solution Overview
The implementation includes:
1. Quick Color Palette (Toolbar)
  • 5 predefined colors: Red, Black, Green, Blue, Yellow
  • One-click selection for fast annotation creation
  • Visual feedback showing the currently selected color
2. Advanced ColorPicker Component
  • Syncfusion ColorPicker with Palette Mode (predefined colors)
  • Mode Switcher enabled to toggle between:
    • Palette Mode: Pre-defined color groups
    • Picker Mode: Full gradient UI with HEX/RGB input
  • Preset Color Groups:
    • Annotation Colors (10 colors)
    • Standard Colors (9 colors)
3. Context Menu for Annotation Colors
  • Right-click on PDF canvas → Color palette appears
  • Select color → Annotation created with that color
  • Right-click on existing annotation → Change its color instantly
  • Quick access to: Red, Black, Green, Blue
Workflow
Creating New Annotations:
  1. Right-click on the PDF canvas
  2. Select desired color from context menu
  3. Annotation appears with the selected color
Modifying Existing Annotations:
  1. Right-click on an annotation
  2. Choose new color from context menu
  3. Annotation updates immediately
Code Features
Predefined Color Sets - Controlled color palette for consistency
Context Menu Integration - Right-click to quickly change colors
Mode Switching - Switch between simple palette and advanced color picker
Visual Feedback - Active color indication in toolbar
Responsive Design - Works smoothly on various screen sizes
Sample Implementation
The complete working code is provided in the attached HTML file. You can:
  • Open it directly in any browser
  • No backend server required
  • Fully functional with Syncfusion CDN libraries
Regards,
Priyanka K

Loader.
Up arrow icon