ColorPicker
A colour picker holds one colour and opens a popover to change it. What it mostly does is share: every colour component underneath reads the picker's value and writes back to it, so a swatch, an area, a slider and a field inside one picker are all looking at the same colour without a single v-model between them.
import { ColorPicker, ColorPickerPopover, ColorPickerTrigger } from "ropav";color-picker-basic.vue
<script setup lang="ts">
import {
ColorArea,
ColorAreaThumb,
ColorPicker,
ColorPickerPopover,
ColorPickerTrigger,
ColorSlider,
ColorSliderThumb,
ColorSliderTrack,
ColorSwatch,
Label,
} from "ropav";
</script>
<template>
<ColorPicker default-value="#0485f7">
<ColorPickerTrigger>
<ColorSwatch size="lg" />
<Label>Brand colour</Label>
</ColorPickerTrigger>
<ColorPickerPopover>
<ColorArea
aria-label="Saturation and brightness"
class="picker"
color-space="hsb"
x-channel="saturation"
y-channel="brightness"
>
<ColorAreaThumb />
</ColorArea>
<ColorSlider channel="hue" class="channel" color-space="hsb">
<ColorSliderTrack>
<ColorSliderThumb />
</ColorSliderTrack>
</ColorSlider>
</ColorPickerPopover>
</ColorPicker>
</template>
<style scoped>
.picker {
max-width: 100%;
}
.channel {
padding-inline: var(--rp-spacing);
}
</style>The trigger is a button showing a ColorSwatch with no color of its own — it takes the picker's. Inside the popover, ColorArea covers two channels and a ColorSlider covers the third; ColorSwatchPicker for presets and ColorField for a typed hex value are the other two pieces.
Holding the colour
default-value starts an uncontrolled picker; value with a change listener, or v-model:value, hands the colour to the caller. change carries a parsed Color, so color.toString("hex") is how you get back to a string.
The popover's open state works the same way: default-open, or is-open with open-change.
Accessibility
- The popover is a dialog, so Esc closes it and focus returns to the trigger.
- Every control inside names itself. The area and the sliders describe the channel they move and the colour they arrive at, which is what makes a colour reachable without seeing it — and it is why the popover should hold real colour controls rather than a canvas you drew yourself.
- The trigger needs to say what colour is being picked. The swatch announces the colour; the label beside it is what says which colour on the page it belongs to.
API
ColorPicker
| Prop | Type | Default | Description |
|---|---|---|---|
defaultOpen | boolean | — | Whether the popover starts open. |
defaultValue | string | Color | "#000000" | Colour the picker starts on while it is uncontrolled. |
isOpen | boolean | — | Controlled open state. |
value | string | Color | — | Controlled colour. A string is parsed. |
The default slot receives:
| Slot prop | Type |
|---|---|
color | Color |
| Event | Payload |
|---|---|
change | Color |
openChange | boolean |
update:isOpen | boolean |
update:value | Color |
ColorPickerPopover
| Prop | Type | Default | Description |
|---|---|---|---|
containerPadding | number | — | |
crossOffset | number | — | |
isKeyboardDismissDisabled | boolean | — | |
offset | number | — | |
placement | "bottom" | "bottom end" | "bottom left" | "bottom right" | "bottom start" | "end" | "end bottom" | "end top" | "left" | "left bottom" | "left top" | "right" | "right bottom" | "right top" | "start" | "start bottom" | "start top" | "top" | "top end" | "top left" | "top right" | "top start" | "bottom left" | |
shouldFlip | boolean | — |
Slots: default.
ColorPickerTrigger
| Prop | Type | Default | Description |
|---|---|---|---|
type | "button" | "reset" | "submit" | "button" |
Slots: default.