Sections
Components
- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Collapsible
- ColorPicker
- Combobox
- Command
- Context Menu
- Curves
- Data Table
- Date Picker
- Dialog
- Drawer
- Dropdown Menu
- Empty
- Field
- FontPicker
- Form
- Gradient Picker
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- Marker
- Menubar
- Message
- Message Scroller
- Native Select
- Navigation Menu
- Number Field
- Pagination
- Pin Input
- Popover
- Progress
- Questionnaire
- Radio Group
- Range Calendar
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Stepper
- Switch
- Table
- Tabs
- Tags Input
- Textarea
- Toast
- Toggle
- Toggle Group
- Tool Rail
- Tooltip
- Tree
- Typography
- Vector Pad
Directory
Forms
Utilities
Fill
Stroke — rgb() in, hex out
Glow
<script setup lang="ts">
import { ref } from 'vue'
import { ColorPicker } from '@/components/ui/color-picker'
const fill = ref('#06b6d4')
const stroke = ref('rgb(244 63 94 / 0.6)')
const glow = ref('#f59e0b')
</script>
<template>
<div class="flex max-w-sm flex-col gap-3">
<div class="flex items-center gap-3">
<ColorPicker v-model="fill" />
<span class="text-muted-foreground text-xs/relaxed">Fill</span>
</div>
<div class="flex items-center gap-3">
<ColorPicker v-model="stroke" />
<span class="text-muted-foreground text-xs/relaxed">Stroke — rgb() in, hex out</span>
</div>
<div class="flex items-center gap-3">
<ColorPicker v-model="glow" default-value="#8b5cf6" />
<span class="text-muted-foreground text-xs/relaxed">Glow</span>
</div>
<svg viewBox="0 0 120 60" class="mt-1 h-16 w-full rounded-lg border border-border/60 bg-input/10">
<rect
x="20"
y="12"
width="80"
height="36"
rx="8"
:fill="fill"
:stroke="stroke"
stroke-width="4"
:filter="`drop-shadow(0 0 6px ${glow})`"
/>
</svg>
</div>
</template>Installation
pnpm dlx hui-kit@latest add color-picker
Usage
<script setup lang="ts">
import { ref } from 'vue'
import { ColorPicker } from '@/components/ui/color-picker'
const color = ref('#3b82f6')
</script>
<template>
<ColorPicker v-model="color" />
</template>The value is always a string. Any CSS color is accepted on the way in — #06b6d4, rgb(6 182 212), hsl(187 94% 43%), even teal — and emitted back as #rrggbb, or #rrggbbaa when translucent.
Anatomy
The trigger shows the current swatch and hex value; everything else lives in the popover:
- the saturation/value surface — drag anywhere, pointer capture included
- the hue slider over the full spectrum
- the alpha slider over a checkerboard
- a HEX / RGB / HSL switch with compact channel inputs
- an eyedropper button, rendered only where
window.EyeDropperexists (Chromium) - fourteen preset swatches, one per hue family
Examples
Default value
Uncontrolled usage with default-value.
#10b981
<script setup lang="ts">
import { ref } from 'vue'
import { ColorPicker } from '@/components/ui/color-picker'
const accent = ref('#10b981')
</script>
<template>
<div class="flex items-center gap-3">
<ColorPicker v-model="accent" default-value="#8b5cf6" />
<span class="text-muted-foreground text-xs/relaxed tabular-nums">{{ accent }}</span>
</div>
</template>Custom presets
Pass your own swatch list, or empty it out entirely.
Warm presets only
No preset strip
<script setup lang="ts">
import { ref } from 'vue'
import { ColorPicker, PRESET_COLORS } from '@/components/ui/color-picker'
const brand = ref('#ef4444')
const bare = ref('#f97316')
</script>
<template>
<div class="flex flex-col gap-3">
<div class="flex items-center gap-3">
<ColorPicker v-model="brand" :presets="[...PRESET_COLORS.slice(0, 7)]" />
<span class="text-muted-foreground text-xs/relaxed">Warm presets only</span>
</div>
<div class="flex items-center gap-3">
<ColorPicker v-model="bare" :presets="[]" />
<span class="text-muted-foreground text-xs/relaxed">No preset strip</span>
</div>
</div>
</template>