Skip to content

Accessibility: Work in progress

Translations: Work in progress

Color Picker

A versatile color picker component that supports swatches, custom colors, and various picker formats.

Basic Usage

swatch and picker types

ts
import { defaultColorSections, HLColorPicker } from '@platform-ui/highrise'
import type {
  HLColorPickerSections,
  HLColorPickerType,
  HLColorSwatch,
  HLColorPickerOptions,
  HLSwatchTileShape,
  HLSwatchTileSize,
} from '@platform-ui/highrise'
html
<HLColorPicker
  id="basic-color-picker"
  :swatches="[{
      key: 'brand',
      label: 'Brand Colors',
      type: 'brand',
      swatches: ['var(--primary-200)', 'var(--primary-500)', 'var(--primary-800)'],
      showAddButton: false,
      showTooltip: 'value'
    }]"
/>
<HLColorPicker id="basic-color-picker-2" type="picker" />

Empty States

html
<HLContentWrap>
  <HLColorPicker id="basic-color-picker" :swatches="swatches">
    <template #empty="{key}"> No {{ key.toLowerCase() }} colors found </template>
  </HLColorPicker>
</HLContentWrap>
ts
const swatches: HLColorPickerSections[] = [
  {
    key: 'brand',
    label: 'Brand Colors',
    swatches: [],
    showAddButton: false,
    showTooltip: 'value',
  },
  {
    key: 'default',
    label: 'Default Colors',
    swatches: [],
    showAddButton: true,
    showTransparentSwatch: true,
    showEyeDropper: true,
    showTooltip: 'both',
  },
  {
    key: 'custom',
    label: 'Custom Colors',
    swatches: [],
    showAddButton: true,
    showEyeDropper: true,
    showTooltip: 'name',
    editable: true,
  },
]

More Swatches

html
<HLColorPicker id="basic-color-picker" :swatches="colorpickerSections" />
ts
const colorpickerSections: HLColorPickerSections[] = [
  {
    key: 'brand',
    label: 'Brand Colors',
    swatches: ['var(--primary-500)', 'var(--primary-600)', 'var(--primary-700)', 'var(--primary-800)', 'var(--primary-900)'],
    showAddButton: false,
    showTooltip: 'value',
  },
  {
    key: 'default',
    label: 'Default Colors',
    swatches: ['var(--gray-100)', 'var(--gray-200)', 'var(--gray-300)', 'var(--gray-400)', 'var(--gray-500)'],
    showAddButton: true,
    showTransparentSwatch: true,
    showEyeDropper: true,
    showTooltip: 'both',
  },
  {
    key: 'custom',
    label: 'Custom Colors',
    swatches: ['var(--green-100)', 'var(--green-200)', 'var(--green-300)', 'var(--green-400)', 'var(--green-500)'],
    showAddButton: true,
    showEyeDropper: true,
    showTooltip: 'name',
    editable: true,
  },
  {
    key: 'blues',
    label: 'Blues',
    swatches: ['var(--indigo-100)', 'var(--indigo-200)', 'var(--indigo-300)', 'var(--indigo-400)', 'var(--indigo-500)'],
    showAddButton: true,
    showEyeDropper: true,
    showTooltip: 'name',
    editable: true,
  },
  {
    key: 'pinks',
    label: 'Pinks',
    swatches: ['var(--pink-100)', 'var(--pink-200)', 'var(--pink-300)', 'var(--pink-400)', 'var(--pink-500)'],
    showAddButton: true,
    showEyeDropper: true,
    showTooltip: 'name',
    editable: true,
  },
]

CRUD Operations on Swatches

Look out for notifications based on CRUD operations performed on the swatches!

html
<HLColorPicker
  id="basic-color-picker"
  :swatches="colorpickerSections"
  @swatch:add="handleSwatchAdd"
  @swatch:edit="handleSwatchEdit"
  @swatch:delete="handleSwatchDelete"
/>
ts
import type { HLColorPickerSections } from '@platform-ui/highrise'

const colorpickerSections: HLColorPickerSections[] = [
  {
    key: 'brand',
    label: 'Brand Colors',
    swatches: ['var(--primary-500)', 'var(--primary-600)', 'var(--primary-700)', 'var(--primary-800)', 'var(--primary-900)'],
    showAddButton: false,
    showTooltip: 'value',
  },
  {
    key: 'default',
    label: 'Default Colors',
    swatches: ['var(--gray-100)', 'var(--gray-200)', 'var(--gray-300)', 'var(--gray-400)', 'var(--gray-500)'],
    showAddButton: true,
    showTransparentSwatch: true,
    showEyeDropper: true,
    showTooltip: 'both',
  },
  {
    key: 'custom',
    label: 'Custom Colors',
    swatches: ['var(--green-100)', 'var(--green-200)', 'var(--green-300)', 'var(--green-400)', 'var(--green-500)'],
    showAddButton: true,
    showEyeDropper: true,
    showTooltip: 'name',
    editable: true,
  },
  {
    key: 'blues',
    label: 'Blues',
    swatches: ['var(--indigo-100)', 'var(--indigo-200)', 'var(--indigo-300)', 'var(--indigo-400)', 'var(--indigo-500)'],
    showAddButton: true,
    showEyeDropper: true,
    showTooltip: 'name',
    editable: true,
  },
  {
    key: 'pinks',
    label: 'Pinks',
    swatches: ['var(--pink-100)', 'var(--pink-200)', 'var(--pink-300)', 'var(--pink-400)', 'var(--pink-500)'],
    showAddButton: true,
    showEyeDropper: true,
    showTooltip: 'name',
    editable: true,
  },
]
ts
import { h } from 'vue'
import type { HLColorSwatch } from '@platform-ui/highrise'
import { HLAlert, HLSwatchTile, HLText, useHLNotification } from '@platform-ui/highrise'

const notification = useHLNotification()
function openNotification(
  action: 'add' | 'edit' | 'delete',
  sectionKey: string,
  sectionIndex: number,
  value: string | HLColorSwatch,
  editorDeleteIndex?: number
) {
  const mergedValue = typeof value === 'string' ? value : JSON.stringify(value)
  const message =
    action === 'add' ? 'A new swatch has been added' : action === 'edit' ? 'A swatch has been edited' : 'A swatch has been deleted'
  const color = action === 'add' ? 'green' : action === 'edit' ? 'blue' : 'red'
  const n = notification.create({
    content: () =>
      h(
        HLAlert,
        {
          closable: true,
          color,
          id: 'test-alert',
          width: '720px',
          onClose: () => {
            n.destroy()
          },
        },
        {
          default: () =>
            h(
              'div',
              {
                class: 'flex flex-col gap-2',
              },
              [
                h(
                  HLText,
                  {
                    size: 'xl',
                    weight: 'bold',
                  },
                  () => message
                ),
                h(
                  HLText,
                  {
                    size: 'md',
                    weight: 'medium',
                  },
                  () => `Section: ${sectionKey}`
                ),
                h(
                  HLText,
                  {
                    size: 'md',
                    weight: 'medium',
                  },
                  () => `Section Index: ${sectionIndex}`
                ),
                h(
                  HLText,
                  {
                    size: 'md',
                    weight: 'medium',
                  },
                  () => `Value: ${mergedValue}`
                ),
                h(
                  HLText,
                  {
                    size: 'md',
                    weight: 'medium',
                  },
                  () => `Swatch Index: ${editorDeleteIndex ?? 'N/A'}`
                ),
                h(HLSwatchTile, {
                  value: typeof value === 'string' ? value : value.value8,
                  shape: 'rectangle',
                  size: 'lg',
                }),
              ]
            ),
        }
      ),
    duration: 10000,
  })
}
const handleSwatchAdd = (sectionKey: string, sectionIndex: number, value: string | HLColorSwatch) => {
  console.log('handleSwatchAdd: ', sectionKey, sectionIndex, value)
  openNotification('add', sectionKey, sectionIndex, value)
}
const handleSwatchEdit = (sectionKey: string, sectionIndex: number, editIndex: number, value: string | HLColorSwatch) => {
  console.log('handleSwatchEdit: ', sectionKey, sectionIndex, editIndex, value)
  openNotification('edit', sectionKey, sectionIndex, value, editIndex)
}
const handleSwatchDelete = (sectionKey: string, sectionIndex: number, deleteIndex: number, value: string | HLColorSwatch) => {
  console.log('handleSwatchDelete: ', sectionKey, sectionIndex, deleteIndex, value)
  openNotification('delete', sectionKey, sectionIndex, value, deleteIndex)
}

Default Swatches

html
<HLColorPicker id="basic-color-picker" :swatches="colorpickerSections" :width="394" />
ts
const colorpickerSections: HLColorPickerSections[] = [
  {
    key: 'brand',
    label: 'Brand Colors',
    swatches: ['var(--primary-500)', 'var(--primary-600)', 'var(--primary-700)', 'var(--primary-800)', 'var(--primary-900)'],
    showAddButton: false,
    showTooltip: 'value',
  },
  ...defaultColorSections,
  {
    key: 'custom',
    label: 'Custom Colors',
    swatches: ['var(--green-100)', 'var(--green-200)', 'var(--green-300)', 'var(--green-400)', 'var(--green-500)'],
    showAddButton: true,
    showEyeDropper: true,
    showTooltip: 'name',
    editable: true,
  },
]

Tooltip Types

The showTooltip property controls what information is displayed when hovering over a color swatch. It has four possible values:

  • name: Shows only the color's label in the tooltip
  • value: Shows only the color value and alpha percentage in the tooltip
  • both: Shows both the name and value information If the color has a label: Shows the label in the header and the color value with alpha below If the color has no label: Shows just the color value with alpha
  • false: No tooltip will appear when hovering over the color swatch
html
<HLColorPicker id="basic-color-picker" :swatches="colorpickerSections" :width="392" />
ts
const tooltipTypesColorpickerSections = [
  {
    key: 'custom1',
    label: 'Show Name',
    swatches: [
      {
        value: '#22C55E',
        value8: '#22C55EFF',
        alpha: 100,
        label: 'Success Green',
      },
      {
        value: '#16A34A',
        value8: '#16A34AFF',
        alpha: 100,
        label: 'Forest Green',
      },
      {
        value: '#15803D',
        value8: '#15803DFF',
        alpha: 100,
        label: 'Deep Green',
      },
      {
        value: '#166534',
        value8: '#166534FF',
        alpha: 100,
        label: 'Dark Green',
      },
      {
        value: '#14532D',
        value8: '#14532DFF',
        alpha: 100,
        label: 'Pine Green',
      },
      {
        value: '#14532D',
        value8: '#14532DFE',
        alpha: 99,
        label: 'Pine Green v2',
        custom: '{{ customValues.pine.green.v2 }}',
      },
    ],
    showAddButton: true,
    showEyeDropper: true,
    showTransparentSwatch: true,
    showTooltip: 'name',
    editable: true,
  },
  {
    key: 'custom2',
    label: 'Show Value',
    swatches: [
      {
        value: '#3B82F6',
        value8: '#3B82F6FF',
        alpha: 100,
        label: 'Primary Blue',
      },
      {
        value: '#2563EB',
        value8: '#2563EBFF',
        alpha: 100,
        label: 'Royal Blue',
      },
      {
        value: '#1D4ED8',
        value8: '#1D4ED8FF',
        alpha: 100,
        label: 'Deep Blue',
      },
      {
        value: '#1E40AF',
        value8: '#1E40AFFF',
        alpha: 100,
        label: 'Navy Blue',
      },
      {
        value: '#1E3A8A',
        value8: '#1E3A8AFF',
        alpha: 100,
        label: 'Dark Blue',
      },
      {
        value: '#1E3A8A',
        value8: '#1E3A8AFE',
        alpha: 99,
        label: 'Dark Blue v2',
        custom:
          '{{ customValues.darkBlue.v2.darkBlue.v2.darkBlue.v2.darkBlue.v2.darkBlue.v2.darkBlue.v2.darkBlue.v2.darkBlue.v2.darkBlue.v2.darkBlue.v2.darkBlue.v2.darkBlue.v2.darkBlue.v2.darkBlue.v2.darkBlue.v2 }}',
      },
    ],
    showAddButton: true,
    showEyeDropper: true,
    showTransparentSwatch: true,
    showTooltip: 'value',
    editable: true,
  },
  {
    key: 'custom3',
    label: 'Show Both',
    swatches: [
      {
        value: '#EF4444',
        value8: '#EF4444FF',
        alpha: 100,
        label: 'Bright Red',
      },
      {
        value: '#DC2626',
        value8: '#DC2626FF',
        alpha: 100,
        label: 'Fire Red',
      },
      {
        value: '#B91C1C',
        value8: '#B91C1CFF',
        alpha: 100,
        label: 'Ruby Red',
      },
      {
        value: '#991B1B',
        value8: '#991B1BFF',
        alpha: 100,
        label: 'Dark Red',
      },
      {
        value: '#7F1D1D',
        value8: '#7F1D1DFF',
        alpha: 100,
        label: 'Deep Red',
      },
      {
        value: '#7F1D1D',
        value8: '#7F1D1DFE',
        alpha: 99,
        label: 'Deep Red v2',
        custom:
          '{{ customValues.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2.deepRed.v2 }}',
      },
    ],
    showAddButton: true,
    showEyeDropper: true,
    showTransparentSwatch: true,
    showTooltip: 'both',
    editable: true,
  },
]

Different Swatch Shapes

html
<HLColorPicker id="basic-color-picker" swatch-size="3xs" :width="392" :swatches="shapeSizeExampleSections" />
ts
const shapeSizeExampleSections: HLColorPickerSections[] = [
  {
    key: 'custom1',
    label: 'Show Name',
    swatches: [
      {
        value: '#22C55E',
        value8: '#22C55EFF',
        alpha: 100,
        label: 'Success Green',
        overrideTileShape: 'circle',
      },
      {
        value: '#16A34A',
        value8: '#16A34AFF',
        alpha: 100,
        label: 'Forest Green',
      },
      {
        value: '#15803D',
        value8: '#15803DFF',
        alpha: 100,
        label: 'Deep Green',
        overrideTileShape: 'rectangle',
      },
      {
        value: '#166534',
        value8: '#166534FF',
        alpha: 100,
        label: 'Dark Green',
      },
      {
        value: '#14532D',
        value8: '#14532DFF',
        alpha: 100,
        label: 'Pine Green',
      },
    ],
    showAddButton: true,
    showEyeDropper: true,
    showTransparentSwatch: true,
    showTooltip: 'name',
    editable: true,
    overrideTileShape: 'rectangle',
  },
  {
    key: 'custom1',
    label: 'Show Value',
    swatches: [
      {
        value: '#3B82F6',
        value8: '#3B82F6FF',
        alpha: 100,
        label: 'Primary Blue',
      },
      {
        value: '#2563EB',
        value8: '#2563EBFF',
        alpha: 100,
        label: 'Royal Blue',
      },
      {
        value: '#1D4ED8',
        value8: '#1D4ED8FF',
        alpha: 100,
        label: 'Deep Blue',
      },
      {
        value: '#1E40AF',
        value8: '#1E40AFFF',
        alpha: 100,
        label: 'Navy Blue',
      },
      {
        value: '#1E3A8A',
        value8: '#1E3A8AFF',
        alpha: 100,
        label: 'Dark Blue',
      },
    ],
    showAddButton: true,
    showEyeDropper: true,
    showTransparentSwatch: true,
    showTooltip: 'value',
    editable: true,
  },
]

Custom Trigger

html
<HLColorPicker
  id="basic-color-picker"
  :width="394"
  :swatches="[
  {
    key: 'custom',
    label: 'Custom Colors',
    swatches: ['var(--green-100)', 'var(--green-200)', 'var(--green-300)', 'var(--green-400)', 'var(--green-500)'],
  },
  placement="top"
]"
>
  <template #trigger>
    <HLButton id="cp-trigger-1" size="sm" variant="secondary" color="blue"> Select Color </HLButton>
  </template>
</HLColorPicker>

Props

NameTypeDefaultDescription
id *string | undefinedundefinedThe unique identifier for the color picker
valuestring'#ff0000'The current color value
type'swatch' | 'picker' as HLColorPickerType'swatch'The type of color picker to display
swatchShape'square' | 'circle' | 'rectangle' as HLSwatchTileShape'square'The shape of color swatches
swatchSize'lg' | 'md' | 'sm' | 'xs' | '2xs' | '3xs' as HLSwatchTileSize'xs'The size of color swatches
swatchesHLColorPickerSections[][]Array of color section configurations
autoCloseOnSelectbooleanfalseWhether to close the picker after color selection
pickerOptionsHLColorPickerOptionsdefaultPickerOptsConfiguration options for the color picker
widthnumber276Width of the color picker in pixels
placement'top' | 'bottom' | 'left' | 'right' | 'top-start' | 'top-end' | 'left-start' | 'left-end' | 'right-start' | 'right-end' | 'bottom-start' | 'bottom-end''bottom-start'Placement of the color picker

Types

ts
export type HLColorPickerSections = {
  key: string
  label: string | false
  swatches: Array<HLColorSwatch | string>
  showAddButton?: boolean
  showTransparentSwatch?: boolean
  showEyeDropper?: boolean
  showTooltip?: 'name' | 'value' | 'both' | false
  editable?: boolean
  overrideTileShape?: 'square' | 'circle' | 'rectangle'
}
ts
export type HLColorPickerOptions = {
  // Format to show by default in the color picker
  defaultPickerFormat?: 'HEX' | 'RGB' | 'HSL' | 'HSB' | 'Custom'
  // Available format options in the dropdown
  pickerFormatOptions?: Array<'HEX' | 'RGB' | 'HSL' | 'HSB' | 'Custom'>
  // Show alpha/opacity control
  showAlpha?: boolean
  // Show save/cancel buttons
  showCTA?: boolean
  // Show eyedropper tool
  showEyeDropper?: boolean
  // Show hue slider
  showHue?: boolean
  // Show input fields for color values
  showInputFields?: boolean
}

// Default values
const defaultPickerOpts = {
  defaultPickerFormat: 'HEX',
  pickerFormatOptions: ['HEX', 'RGB', 'HSL', 'HSB', 'Custom'],
  showAlpha: true,
  showCTA: true,
  showEyeDropper: true,
  showHue: true,
  showInputFields: true,
} as const
ts
export type HLColorSwatch = {
  alpha: number
  value: string
  value8: string
  label?: string
  oldValue?: string | HLColorSwatch
  overrideTileShape?: 'square' | 'circle' | 'rectangle'
  custom?: false | string
  inputType?: 'HEX' | 'RGB' | 'HSL' | 'HSB' | 'Custom'
}

Supported Color Formats

The color picker supports the following formats:

FormatExampleDescription
HEX#FF00006-digit (RGB) hexadecimal
HEXA#FF0000FF8-digit (RGBA) hexadecimal
RGBrgb(255, 0, 0)RGB values (0-255)
RGBArgba(255, 0, 0, 1)RGB with alpha channel (0-1)
HSLhsl(0, 100%, 50%)Hue (0-360), Saturation (0-100%), Lightness (0-100%)
HSLAhsla(0, 100%, 50%, 1)HSL with alpha channel (0-1)
HSBhsb(0, 100%, 100%)Hue (0-360), Saturation (0-100%), Brightness (0-100%)
Customvar(--primary-500) | {{ location.customValue }}Custom variable names

Emits

NameParametersDescription
@select(value: string, selectedValue: string | HLColorSwatch, sectionKey?: string, sectionIndex?: number, tileIndex?: number) => voidEmitted when a color is selected; Only HEXA value is emitted for type="picker". Other arguments are for type="swatch"
@swatch:add(sectionKey: string, sectionIndex: number, newValue: HLColorSwatch) => voidEmitted when a new swatch is added; index not necessary as new swatches are added to the start of the array; swatches array is not updated in case of custom value
@swatch:delete(sectionKey: string, sectionIndex: number, deleteIndex: number, deletedValue: string | HLColorSwatch) => voidEmitted when a swatch is deleted
@swatch:edit(sectionKey: string, sectionIndex: number, editIndex: number, updatedValue: string | HLColorSwatch) => voidEmitted when a swatch is edited
@swatch:reset(sectionKey: string, sectionIndex: number, resetIndex: number, revertedValue: string | HLColorSwatch) => voidEmitted when a swatch is deleted
@update:show(value: boolean) => voidEmitted when picker visibility changes
@update:swatches(value: HLColorPickerSections[]) => voidEmitted when swatches are updated

Slots

NameParametersDescription
trigger()Custom trigger element. If not provided, defaults to a color swatch with the current value