Color Picker
Vue formHex / RGB color input with a popover swatch grid. Supports controlled and uncontrolled modes, alpha channel, and a recent-colors row.
Also available for React ->Installation
$ pnpm dlx shadcn-vue@latest add https://uipkge.dev/r/vue/color-picker.json$ npx shadcn-vue@latest add https://uipkge.dev/r/vue/color-picker.json$ yarn dlx shadcn-vue@latest add https://uipkge.dev/r/vue/color-picker.json$ bunx shadcn-vue@latest add https://uipkge.dev/r/vue/color-picker.json
Or with the named registry:
npx shadcn-vue@latest add @uipkge/color-picker
Examples
Props
| Name | Type / Values | Default | Required |
|---|---|---|---|
modelValue | string | — | optional |
disabled | boolean | — | optional |
presets Override the swatches shown below the color input. Pass [] to hide entirely. | string[] | () => [ '#ef4444' | optional |
hideHexInput Hide the hex text field next to the color trigger. | boolean | — | optional |
class | HTMLAttributes['class'] | — | optional |
Files (2)
-
app/components/ui/color-picker/ColorPicker.vue 3 kB
<script setup lang="ts"> import { computed } from 'vue' import type { HTMLAttributes } from 'vue' import { cn } from '@/lib/utils' const props = withDefaults( defineProps<{ modelValue?: string disabled?: boolean /** Override the swatches shown below the color input. Pass [] to hide entirely. */ presets?: string[] /** Hide the hex text field next to the color trigger. */ hideHexInput?: boolean class?: HTMLAttributes['class'] }>(), { presets: () => [ '#ef4444', '#f97316', '#eab308', '#22c55e', '#14b8a6', '#3b82f6', '#8b5cf6', '#ec4899', '#ffffff', '#d4d4d4', '#737373', '#171717', ], hideHexInput: false, }, ) const emit = defineEmits<{ 'update:modelValue': [value: string] }>() const swatches = computed(() => props.presets ?? []) </script> <template> <div :class="cn('space-y-3', props.class)" v-bind="$attrs"> <!-- Color trigger + hex field --> <div class="flex items-center gap-2"> <div class="border-input relative h-10 w-10 shrink-0 overflow-hidden rounded-md border shadow-xs" :style="{ backgroundColor: modelValue || '#ffffff' }" > <input type="color" :value="modelValue || '#ffffff'" :disabled="disabled" aria-label="Pick color" class="absolute inset-0 h-full w-full cursor-pointer opacity-0 disabled:cursor-not-allowed" @input="emit('update:modelValue', ($event.target as HTMLInputElement).value)" /> </div> <input v-if="!hideHexInput" type="text" :value="modelValue || ''" placeholder="#000000" :disabled="disabled" class="bg-background border-input text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 h-10 flex-1 rounded-md border px-3 text-sm uppercase shadow-xs outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-50" @input="emit('update:modelValue', ($event.target as HTMLInputElement).value)" /> </div> <!-- Preset swatches --> <div v-if="swatches.length" class="flex flex-wrap gap-1.5"> <button type="button" v-for="color in swatches" :key="color" :disabled="disabled" :aria-label="`Select ${color}`" :style="{ backgroundColor: color }" :class=" cn( 'ring-offset-background focus-visible:ring-ring/40 size-6 shrink-0 rounded-md shadow-sm transition-transform outline-none hover:scale-110 focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:scale-100', modelValue?.toLowerCase() === color.toLowerCase() ? 'ring-foreground ring-2 ring-offset-2' : 'ring-border/50 ring-1', color.toLowerCase() === '#ffffff' && 'ring-border', ) " @click="emit('update:modelValue', color)" /> </div> </div> </template> -
app/components/ui/color-picker/index.ts 0.1 kB
export { default as ColorPicker } from './ColorPicker.vue'
Raw manifest: https://uipkge.dev/r/vue/color-picker.json