All components
Hex Color Picker
inputsUi-Layouts component.
responsive · 480px
Install
Same command in any shadcn project — React (Vite/CRA), Next.js, Remix, Astro, and more:
$
npx shadcn@latest add https://your-domain/r/ui-layouts-color-picker.jsonUsage
'use client';
import { useState } from "react";
import { ColorPicker } from "@/registry/ui-layouts/color-picker";
export default function Demo() {
const [color, setColor] = useState("#6366f1");
return (
<div className="flex items-center justify-center p-8">
<ColorPicker
color={color}
onChange={setColor}
label="Color"
isEyeDroppper={false}
/>
</div>
);
}Component source
'use client';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { cn } from '@/lib/utils';
import { Copy, Pipette } from 'lucide-react';
import { HexColorPicker } from 'react-colorful';
import { toast } from 'sonner';
interface ColorPickerProps {
color: string;
onChange: (color: string) => void;
label: string;
isEyeDroppper?: boolean;
className?: string;
}
export function ColorPicker({
color,
onChange,
label,
isEyeDroppper = false,
className,
}: ColorPickerProps) {
function copyToClipboard() {
navigator.clipboard.writeText(color);
toast('Copied!', {
description: `${color} copied to clipboard`,
duration: 2000,
});
}
async function useEyeDropper() {
if (!('EyeDropper' in window)) {
toast.error('Not supported', {
description: 'Eyedropper is not supported in your browser',
duration: 3000,
});
return;
}
try {
// @ts-expect-error - EyeDropper is not in the TypeScript DOM types yet
const eyeDropper = new window.EyeDropper();
const result = await eyeDropper.open();
onChange(result.sRGBHex);
} catch (e) {
console.error('Error using eyedropper', e);
}
}
return (
<div className={cn('flex items-center gap-2', className)}>
<Label className='w-24'>{label}</Label>
<Popover>
<PopoverTrigger asChild>
<Button
variant='outline'
className='h-8 w-12 border-2 p-0'
style={{ backgroundColor: color }}
>
<span className='sr-only'>Pick a color</span>
</Button>
</PopoverTrigger>
<PopoverContent className='w-full p-3 bg-primary-foreground'>
<HexColorPicker color={color} onChange={onChange} className='w-full!' />
<div className='mt-2 flex w-full gap-2'>
<Input
value={color}
onChange={(e) => onChange(e.target.value)}
className='h-10 w-full'
/>
<Button
variant='outline'
size='icon'
onClick={copyToClipboard}
className='h-10 w-12 shrink border-neutral-300 bg-neutral-100 text-neutral-900 hover:bg-neutral-200'
style={{ borderRadius: '6px' }}
>
<Copy className='h-4 w-4' />
<span className='sr-only'>Copy color</span>
</Button>
</div>
{isEyeDroppper && (
<div className='mt-2 flex gap-2'>
<Button
variant='outline'
size='icon'
onClick={useEyeDropper}
className='h-10 w-10 border-neutral-300 bg-neutral-100 text-neutral-900 hover:bg-neutral-200'
style={{ borderRadius: '6px' }}
>
<Pipette className='h-4 w-4' />
<span className='sr-only'>Pick color</span>
</Button>
<div
className='h-10 flex-1'
style={{ backgroundColor: color, borderRadius: '6px' }}
/>
</div>
)}
</PopoverContent>
</Popover>
</div>
);
}Source: Ui-Layouts