Components
Loading preview...
A composable color picker that synchronizes color value between multiple color components.
@reapollo
npx shadcn@latest add https://21st.dev/r/larsen66/heroui-color-pickerimport * as React from "react";
import {
ColorPicker,
ColorSlider,
ColorSwatch,
Label,
ListBox,
Select,
type ColorChannel,
type ColorSpace,
} from "@/components/ui/heroui-color-picker";
const sourcePreviewOutput = "219°";
export default function WithSlidersDemo() {
const [colorSpace, setColorSpace] = React.useState<ColorSpace>("hsl");
const colorChannelsByColorSpace: Record<ColorSpace, ColorChannel[]> = {
hsb: ["hue", "saturation", "brightness", "alpha"],
hsl: ["hue", "saturation", "lightness", "alpha"],
rgb: ["red", "green", "blue", "alpha"],
};
return (
<div className="flex min-h-screen w-full items-center justify-center overflow-hidden bg-background p-8">
<ColorPicker defaultValue="hsl(219, 58%, 93%)" defaultOpen>
<ColorPicker.Trigger>
<ColorSwatch size="lg" />
<Label>Pick a color</Label>
</ColorPicker.Trigger>
<ColorPicker.Popover className="max-w-62 gap-2 px-2 py-3">
<Select aria-label="Color space" value={colorSpace} variant="secondary" onChange={(value) => setColorSpace(value as ColorSpace)}>
<Select.Trigger>
<Select.Value className="uppercase" />
<Select.Indicator />
</Select.Trigger>
<Select.Popover>
<ListBox>
{Object.keys(colorChannelsByColorSpace).map((space) => (
<ListBox.Item key={space} className="uppercase" id={space} textValue={space}>
{space}
<ListBox.ItemIndicator />
</ListBox.Item>
))}
</ListBox>
</Select.Popover>
</Select>
<div className="flex flex-col gap-2">
{colorChannelsByColorSpace[colorSpace].map((channel) => (
<ColorSlider key={channel} aria-label={channel} channel={channel} className="gap-1 px-1" colorSpace={colorSpace}>
<Label className="capitalize">{channel}</Label>
<ColorSlider.Output className="text-muted" />
<ColorSlider.Track>
<ColorSlider.Thumb />
</ColorSlider.Track>
</ColorSlider>
))}
</div>
</ColorPicker.Popover>
</ColorPicker>
</div>
);
}
export { WithSlidersDemo };