Blossom Color Picker

March 31, 2026 · View on GitHub

npm version PRs Welcome GitHub license

A beautiful, blooming color picker for Web. Available as a standalone vanilla JS class, or as a thin React / Vue / Svelte / Angular wrapper.

https://github.com/user-attachments/assets/553ee0ff-1f52-497f-bc8f-cee9a7b91d66

Packages

PackageDescriptionVersion
@dayflow/blossom-color-pickerVanilla JS core (zero dependencies)2.0.0
@dayflow/blossom-color-picker-reactReact wrapper1.0.0
@dayflow/blossom-color-picker-vueVue 3 wrapper1.0.0
@dayflow/blossom-color-picker-svelteSvelte wrapper1.0.0
@dayflow/blossom-color-picker-angularAngular wrapper1.0.0

Installation

# Vanilla JS (core)
npm install @dayflow/blossom-color-picker

# React
npm install @dayflow/blossom-color-picker-react

# Vue 3
npm install @dayflow/blossom-color-picker-vue

# Svelte
npm install @dayflow/blossom-color-picker-svelte

# Angular
npm install @dayflow/blossom-color-picker-angular

Usage

Vanilla JS

import { BlossomColorPicker } from '@dayflow/blossom-color-picker';
import '@dayflow/blossom-color-picker/styles.css'; // <- must import css in pure JS

const picker = new BlossomColorPicker(document.getElementById('picker'), {
  onChange: color => console.log(color.hex),
});

// Programmatic control
picker.expand();
picker.collapse();
picker.toggle();
picker.setValue({ hue: 200, saturation: 50, alpha: 100, layer: 'outer' });
picker.setOptions({ disabled: true });
picker.destroy();

React

import { BlossomColorPicker } from '@dayflow/blossom-color-picker-react';

function App() {
  const [color, setColor] = useState({
    hue: 330,
    saturation: 70,
    alpha: 100,
    layer: 'outer' as const,
  });

  return <BlossomColorPicker value={color} onChange={c => setColor(c)} />;
}

Vue 3

<script setup>
import { ref } from 'vue';
import { BlossomColorPicker } from '@dayflow/blossom-color-picker-vue';

const color = ref({
  hue: 330,
  saturation: 70,
  alpha: 100,
  layer: 'outer',
});

function handleChange(c) {
  color.value = c;
}
</script>

<template>
  <BlossomColorPicker :value="color" @change="handleChange" />
</template>

Svelte

<script>
  import { BlossomColorPicker } from '@dayflow/blossom-color-picker-svelte';

  let color = $state({
    hue: 330, saturation: 70, alpha: 100, layer: 'outer',
  });

  function handleChange(newColor) {
    color = newColor;
  }
</script>

<BlossomColorPicker value={color} onchange={handleChange} />

Angular

import { Component } from '@angular/core';
import {
  BlossomColorPickerComponent,
  type BlossomColorPickerColor,
} from '@dayflow/blossom-color-picker-angular';

@Component({
  selector: 'app-root',
  imports: [BlossomColorPickerComponent],
  template: `
    <blossom-color-picker
      [value]="color"
      (colorChange)="onColorChange($event)"
    />
  `,
})
export class App {
  color = { hue: 330, saturation: 70, alpha: 100, layer: 'outer' as const };

  onColorChange(c: BlossomColorPickerColor) {
    this.color = c;
  }
}

Options / Props

All packages share the same set of options. In React they are passed as JSX props; in Vue as component props (with events via @change / @collapse); in Svelte as callback props (onchange / oncollapse); in Angular as @Input() bindings (with events via (colorChange) / (colorCollapse)).

OptionTypeDefaultDescription
valueBlossomColorPickerValue-Controlled value of the picker.
defaultValueBlossomColorPickerValue{ hue: 330, saturation: 70, alpha: 50, layer: 'outer' }Initial value for uncontrolled mode.
colorsColorInput[](Default 18-color set)Color list, automatically sorted and distributed into layers.
onChange(color: BlossomColorPickerColor) => void-Called when color changes. Vue: @change. Svelte: onchange. Angular: (colorChange).
onCollapse(color: BlossomColorPickerColor) => void-Called when the picker collapses. Vue: @collapse. Svelte: oncollapse. Angular: (colorCollapse).
disabledbooleanfalseWhether the picker is disabled.
openOnHoverbooleanfalseIf true, opens the picker on hover instead of click.
initialExpandedbooleanfalseWhether the picker starts expanded.
animationDurationnumber300Duration of the blooming animation in ms.
showAlphaSliderbooleantrueWhether to show the saturation arc slider.
coreSizenumber32Diameter of the central circle in px.
petalSizenumber32Diameter of individual color petals in px.
showCoreColorbooleantrueWhen true, the core shows the selected color while expanded.
sliderPosition'top' | 'bottom' | 'left' | 'right''right'Fixed position for the arc slider.
adaptivePositioningbooleantrueSmart Shifter: Automatically shifts the picker to stay within viewport and repositions the slider for best visibility.
circularBarWidthnumber12Thickness of the circular color bar in px.
sliderWidthnumber12Thickness of the arc slider track and handle in px.
sliderOffsetnumber30Distance between the outermost petals and the arc slider in px.
className / classstring""Additional CSS class (React: className, Svelte: class).

Vanilla JS Methods

The core class exposes these additional methods:

MethodDescription
setValue(value)Set the current color value.
getValue()Get the current color as a BlossomColorPickerColor.
expand()Open the picker.
collapse()Close the picker.
toggle()Toggle open/close.
setOptions(opts)Update any options at runtime.
destroy()Remove all DOM elements and event listeners.

Type Reference

BlossomColorPickerValue

The value object used for controlled / uncontrolled state.

FieldTypeDescription
huenumberHue angle (0-360).
saturationnumberSlider position (0-100). 0 = bright, 100 = dark.
lightnessnumber?HSL lightness (auto-computed from slider if omitted).
originalSaturationnumber?Base saturation of the selected petal.
alphanumberAlpha value (0-100).
layer'inner' | 'outer'Which layer the selected petal belongs to.

BlossomColorPickerColor

Extends BlossomColorPickerValue — returned by onChange and onCollapse.

FieldTypeDescription
hexstringHex color string, e.g. "#6586E5".
hslstringHSL string, e.g. "hsl(225, 71%, 65%)".
hslastringHSLA string with alpha.

ColorInput

type ColorInput = string | { h: number; s: number; l: number };

Color Formats

The colors option accepts any of the following formats, and they can be mixed:

// Vanilla JS
const picker = new BlossomColorPicker(el, {
  colors: [
    '#FF6B6B', // hex
    'rgb(107, 203, 119)', // rgb()
    'rgba(65, 105, 225, 0.9)', // rgba()
    'hsl(280, 70%, 55%)', // hsl()
    'hsl(200 80% 60%)', // hsl() space-separated
    { h: 45, s: 90, l: 65 }, // HSL object
  ],
});
// React
<BlossomColorPicker
  colors={['#FF6B6B', 'rgb(107, 203, 119)', { h: 45, s: 90, l: 65 }]}
/>

Project Structure

This is a monorepo with five packages:

packages/
  core/      @dayflow/blossom-color-picker          — standalone vanilla JS class
  react/     @dayflow/blossom-color-picker-react     — thin React wrapper
  vue/       @dayflow/blossom-color-picker-vue       — thin Vue 3 wrapper
  svelte/    @dayflow/blossom-color-picker-svelte    — thin Svelte 5 wrapper
  angular/   @dayflow/blossom-color-picker-angular   — thin Angular wrapper

Made by Jayce Li, idea from @lichinlin.