https://github.com/dayflow-js/BlossomColorPicker
A beautiful, blooming color picker for Web, built with pure CSS and compatible with JS, React, Vue, Svelte, and Angular. 🌟 If you like it, give it a star :)
https://github.com/dayflow-js/BlossomColorPicker
blossom-ui color-picker
Last synced: 27 days ago
JSON representation
A beautiful, blooming color picker for Web, built with pure CSS and compatible with JS, React, Vue, Svelte, and Angular. 🌟 If you like it, give it a star :)
- Host: GitHub
- URL: https://github.com/dayflow-js/BlossomColorPicker
- Owner: dayflow-js
- License: mit
- Created: 2026-02-05T14:09:12.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-04-28T22:27:24.000Z (about 1 month ago)
- Last Synced: 2026-04-29T00:25:09.932Z (about 1 month ago)
- Topics: blossom-ui, color-picker
- Language: TypeScript
- Homepage: https://blossom.dayflow.studio
- Size: 777 KB
- Stars: 337
- Watchers: 1
- Forks: 16
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: Changelog.md
- License: LICENSE
Awesome Lists containing this project
- fucking-awesome-angular - BlossomColorPicker - A polished, blooming color picker for the Web, offered as a standalone JS library with lightweight wrappers for Angular, React, Vue, and Svelte. (Third Party Components / Form Controls)
- awesome-angular - BlossomColorPicker - A polished, blooming color picker for the Web, offered as a standalone JS library with lightweight wrappers for Angular, React, Vue, and Svelte. (Third Party Components / Form Controls)
README
# Blossom Color Picker
[](https://www.npmjs.com/package/@dayflow/blossom-color-picker)
[](https://github.com/dayflow-js/BlossomColorPicker/pulls)
[](https://github.com/dayflow-js/BlossomColorPicker/blob/main/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
| Package | Description | Version |
| :-------------------------------------- | :---------------------------------- | :------ |
| `@dayflow/blossom-color-picker` | Vanilla JS core (zero dependencies) | 2.0.0 |
| `@dayflow/blossom-color-picker-react` | React wrapper | 1.0.0 |
| `@dayflow/blossom-color-picker-vue` | Vue 3 wrapper | 1.0.0 |
| `@dayflow/blossom-color-picker-svelte` | Svelte wrapper | 1.0.0 |
| `@dayflow/blossom-color-picker-angular` | Angular wrapper | 1.0.0 |
## Installation
```bash
# 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
```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
```tsx
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 setColor(c)} />;
}
```
### Vue 3
```vue
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;
}
```
### Svelte
```svelte
import { BlossomColorPicker } from '@dayflow/blossom-color-picker-svelte';
let color = $state({
hue: 330, saturation: 70, alpha: 100, layer: 'outer',
});
function handleChange(newColor) {
color = newColor;
}
```
### Angular
```typescript
import { Component } from '@angular/core';
import {
BlossomColorPickerComponent,
type BlossomColorPickerColor,
} from '@dayflow/blossom-color-picker-angular';
@Component({
selector: 'app-root',
imports: [BlossomColorPickerComponent],
template: `
`,
})
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)`).
| Option | Type | Default | Description |
| :-------------------- | :----------------------------------------- | :-------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------- |
| `value` | `BlossomColorPickerValue` | - | Controlled value of the picker. |
| `defaultValue` | `BlossomColorPickerValue` | `{ hue: 330, saturation: 70, alpha: 50, layer: 'outer' }` | Initial value for uncontrolled mode. |
| `colors` | `ColorInput[]` | (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)`. |
| `disabled` | `boolean` | `false` | Whether the picker is disabled. |
| `openOnHover` | `boolean` | `false` | If true, opens the picker on hover instead of click. |
| `initialExpanded` | `boolean` | `false` | Whether the picker starts expanded. |
| `animationDuration` | `number` | `300` | Duration of the blooming animation in ms. |
| `showAlphaSlider` | `boolean` | `true` | Whether to show the saturation arc slider. |
| `coreSize` | `number` | `32` | Diameter of the central circle in px. |
| `petalSize` | `number` | `32` | Diameter of individual color petals in px. |
| `showCoreColor` | `boolean` | `true` | When true, the core shows the selected color while expanded. |
| `sliderPosition` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'right'` | Fixed position for the arc slider. |
| `adaptivePositioning` | `boolean` | `true` | **Smart Shifter**: Automatically shifts the picker to stay within viewport and repositions the slider for best visibility. |
| `circularBarWidth` | `number` | `12` | Thickness of the circular color bar in px. |
| `sliderWidth` | `number` | `12` | Thickness of the arc slider track and handle in px. |
| `sliderOffset` | `number` | `30` | Distance between the outermost petals and the arc slider in px. |
| `className` / `class` | `string` | `""` | Additional CSS class (React: `className`, Svelte: `class`). |
### Vanilla JS Methods
The core class exposes these additional methods:
| Method | Description |
| :----------------- | :---------------------------------------------------- |
| `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.
| Field | Type | Description |
| :------------------- | :------------------- | :---------------------------------------------------- |
| `hue` | `number` | Hue angle (0-360). |
| `saturation` | `number` | Slider position (0-100). 0 = bright, 100 = dark. |
| `lightness` | `number?` | HSL lightness (auto-computed from slider if omitted). |
| `originalSaturation` | `number?` | Base saturation of the selected petal. |
| `alpha` | `number` | Alpha value (0-100). |
| `layer` | `'inner' \| 'outer'` | Which layer the selected petal belongs to. |
### `BlossomColorPickerColor`
Extends `BlossomColorPickerValue` — returned by `onChange` and `onCollapse`.
| Field | Type | Description |
| :----- | :------- | :--------------------------------------- |
| `hex` | `string` | Hex color string, e.g. `"#6586E5"`. |
| `hsl` | `string` | HSL string, e.g. `"hsl(225, 71%, 65%)"`. |
| `hsla` | `string` | HSLA string with alpha. |
### `ColorInput`
```ts
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:
```js
// 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
],
});
```
```tsx
// React
```
## 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](https://github.com/JayceV552), idea from [@lichinlin](https://x.com/lichinlin/status/2019084548072689980).