---
title: "ColorChooser"
description: "A visual color picker component."
canonical_url: "https://nuxt.mhaibaraai.cn/en/docs/components/color-chooser"
---
# ColorChooser

> A visual color picker component.

## Introduction

`MColorChooser` is a visual color picker component. It provides a color wheel and HSL sliders for color selection, supports custom trigger styles, preset swatches, copy and clear actions, and synchronizes the value in one of three formats: hex, rgb, or hsl.

> [!NOTE]
> See: https://ui.nuxt.com/docs/components/color-picker
> 
> Built on Nuxt UI's ColorPicker component

## Usage

The default button trigger displays the current color value. Click to open the popover and select a color from the panel to sync with v-model:

```vue
<script setup lang="ts">
const value = ref("#0ea5e9")
</script>

<template>
  <MColorChooser />
</template>
```

### `formats` Output Format

Switch between `hex`, `rgb`, `hsl`, `cmyk`, and `lab` at the top of the popover — the current value is converted to the selected format:

```vue
<script setup lang="ts">
const value = ref("#22c55e")
</script>

<template>
  <MColorChooser :formats='["hex","rgb","hsl","cmyk","lab"]' />
</template>
```

### `swatches` Single-Group Presets

A one-dimensional `swatches` array renders as a continuous color palette. Clicking a swatch selects the color and closes the popover by default:

```vue
<script setup lang="ts">
const value = ref("#ef4444")
</script>

<template>
  <MColorChooser :swatches='["#ef4444","#f97316","#f59e0b","#eab308","#84cc16","#22c55e","#10b981","#14b8a6","#06b6d4","#0ea5e9","#3b82f6","#6366f1","#8b5cf6","#a855f7","#d946ef","#ec4899"]' />
</template>
```

### `swatches` Grouped Presets

A two-dimensional `swatches` array groups colors by row to display hues and neutral tones. `closeOnSwatch` controls whether the popover closes after selection:

```vue
<script setup lang="ts">
const value = ref("#3b82f6")
</script>

<template>
  <MColorChooser :close-on-swatch="false" :swatches='[["#ef4444","#f97316","#f59e0b","#eab308","#84cc16","#22c55e","#10b981","#14b8a6"],["#06b6d4","#0ea5e9","#3b82f6","#6366f1","#8b5cf6","#a855f7","#d946ef","#ec4899"],["#0a0a0a","#404040","#737373","#a3a3a3","#d4d4d4","#e5e5e5","#f5f5f5","#ffffff"]]' />
</template>
```

### `trigger` Trigger Style

`trigger` controls the trigger appearance: `button` renders a button, `chip` renders a compact color block only, and `input` provides a color dot + text input that validates hex on blur:

```vue
<script setup lang="ts">
const value = ref("#f59e0b")
</script>

<template>
  <MColorChooser trigger="chip" />
</template>
```

### `copyable` Copy Button

`copyable` enables a copy button at the bottom of the popover. Clicking it fires the `@copy` event:

```vue
<script setup lang="ts">
const value = ref("#a855f7")
</script>

<template>
  <MColorChooser copyable />
</template>
```

### `clearable` Clear Button

`clearable` enables a clear button at the bottom of the popover. Clicking it resets the current value and fires the `@clear` event:

```vue
<script setup lang="ts">
const value = ref("#a855f7")
</script>

<template>
  <MColorChooser clearable />
</template>
```

### `ui` Style Customization

`ui` overrides the class of internal slots to customize the swatch grid and swatch size, without affecting the color picker, copy, or clear mechanisms:

```vue
<script setup lang="ts">
const value = ref("#14b8a6")
</script>

<template>
  <MColorChooser :ui='{"swatches":"grid grid-cols-4 gap-2","swatch":"size-8 rounded-lg ring-2 ring-default cursor-pointer hover:ring-primary"}' :swatches='["#ef4444","#f97316","#f59e0b","#eab308","#84cc16","#22c55e","#10b981","#14b8a6","#06b6d4","#0ea5e9","#3b82f6","#6366f1","#8b5cf6","#a855f7","#d946ef","#ec4899"]' />
</template>
```

### `disabled` Disabled State

`disabled` prevents the popover from opening. The `input` trigger enters a read-only state while still displaying the current value:

```vue
<script setup lang="ts">
const value = ref("#6b7280")
</script>

<template>
  <MColorChooser disabled />
</template>
```

## Examples

### Inheriting Field Context

When placed inside `UFormField`, it inherits `size` and error state, and the trigger renders according to the form state:

```vue
<template>
  <UFormField label="Brand Color" size="xs" error="Example error state">
    <MColorChooser />
  </UFormField>
</template>
```

### Inside `UFieldGroup`

When placed alongside a button inside `UFieldGroup`, they share size, border-radius, and border connection — ideal for inline color picking within a form:

```vue
<template>
  <UFieldGroup size="xs">
    <MColorChooser trigger="input" />
    <UButton icon="i-lucide-pipette" color="neutral" variant="subtle" />
  </UFieldGroup>
</template>
```

### Custom Trigger Rendering

The `default` slot gives full control over the trigger appearance, while `open` and `value` slot props keep the popover state accessible:

```vue [ComponentsColorChooserSlotExample.vue]
<script setup lang="ts">
const value = ref('#ec4899')

const tailwindPalette = [
  '#ef4444', '#f97316', '#f59e0b', '#eab308',
  '#84cc16', '#22c55e', '#10b981', '#14b8a6',
  '#06b6d4', '#0ea5e9', '#3b82f6', '#6366f1',
  '#8b5cf6', '#a855f7', '#d946ef', '#ec4899'
]
</script>

<template>
  <MColorChooser v-model="value" :swatches="tailwindPalette">
    <template #default="{ open, value: current }">
      <button
        type="button"
        class="size-12 rounded-xl border-2 border-default cursor-pointer hover:scale-105 transition flex items-center justify-center"
        :style="{ backgroundColor: current }"
        :aria-expanded="open"
      >
        <UIcon v-if="!current" name="i-lucide-plus" class="text-muted" />
      </button>
    </template>
  </MColorChooser>
</template>
```

## API

### Props

```ts
/**
 * Props for the MColorChooser component
 */
interface MColorChooserProps {
  id?: string | undefined;
  name?: string | undefined;
  /**
   * 当前激活的颜色格式。
   * @default 'hex'
   */
  format?: "hex" | "rgb" | "hsl" | "cmyk" | "lab" | undefined;
  /**
   * 启用的颜色格式 tab 列表，长度 >= 2 时在 popover 顶部渲染切换器。
   * 仅一项时不渲染 tab，等价于 `format`。
   * @default ["hex"]
   */
  formats?: ColorFormat[] | undefined;
  /**
   * 预设色板。
   * 一维数组渲染为单行，二维数组渲染为多行分组。
   */
  swatches?: string[] | string[][] | undefined;
  /**
   * 点击预设色后是否自动关闭弹层。
   * @default true
   */
  closeOnSwatch?: boolean | undefined;
  /**
   * 是否在底部 actions 区显示清除按钮。
   */
  clearable?: boolean | undefined;
  /**
   * actions 区显示复制按钮（基于 navigator.clipboard）。
   */
  copyable?: boolean | undefined;
  /**
   * 触发器形态。
   * - `button`：色点 + 色值 / label 的常规按钮（默认）
   * - `chip`：仅一个圆形色点
   * - `input`：色点 leading + 可输入色值文本框
   * @default 'button'
   */
  trigger?: "button" | "chip" | "input" | undefined;
  /**
   * `trigger='button'` 时按钮上的文本，未传则显示当前色值。
   */
  label?: string | undefined;
  /**
   * 未选中颜色时的占位文案。
   * @default '选择颜色'
   */
  placeholder?: string | undefined;
  /**
   * 触发器尺寸，同时驱动主题 size variant。
   * @default 'md'
   */
  size?: "md" | "xs" | "sm" | "lg" | "xl" | undefined;
  /**
   * 触发按钮的颜色（trigger=button|chip 生效）。
   * @default 'neutral'
   */
  color?: "primary" | "secondary" | "info" | "success" | "warning" | "error" | "important" | "neutral" | undefined;
  /**
   * 触发按钮的视觉变体（trigger=button|chip 生效）。
   * @default 'subtle'
   */
  variant?: "solid" | "outline" | "soft" | "subtle" | "ghost" | "link" | undefined;
  /**
   * 是否禁用。禁用时弹层不会打开、所有交互失效。
   */
  disabled?: boolean | undefined;
  /**
   * Highlight the ring color like a focus state.
   */
  highlight?: boolean | undefined;
  /**
   * 未选中颜色时占位的图标。
   * @default 'i-lucide-palette'
   */
  icon?: any;
  /**
   * 透传给 `UColorPicker` 的属性。
   * `modelValue`、`format`、`disabled` 由组件内部托管。
   */
  colorPickerProps?: Omit<ColorPickerProps, "format" | "disabled" | "modelValue"> | undefined;
  ui?: Record<string, C> & { content?: SlotClass; arrow?: SlotClass; body?: SlotClass; header?: SlotClass; section?: SlotClass; swatches?: SlotClass; swatch?: SlotClass; actions?: SlotClass; actionsValue?: SlotClass; actionsButtons?: SlotClass; triggerChipWrapper?: SlotClass; triggerChip?: SlotClass; triggerLabel?: SlotClass; triggerIcon?: SlotClass; } | undefined;
  /**
   * The display mode of the popover.
   * @default 'click'
   */
  mode?: M | undefined;
  /**
   * The content of the popover.
   * @default { side: 'bottom', sideOffset: 8, collisionPadding: 8 }
   */
  content?: Omit<PopoverContentProps, "as" | "asChild" | "forceMount"> & Partial<EmitsToProps<PopoverContentImplEmits>> | undefined;
  /**
   * Display an arrow alongside the popover.
   * `{ rounded: true }`{lang="ts-type"}
   * @default false
   */
  arrow?: boolean | Omit<PopoverArrowProps, "as" | "asChild"> | undefined;
  /**
   * Render the popover in a portal.
   * @default true
   */
  portal?: string | false | true | HTMLElement | undefined;
  /**
   * The reference (or anchor) element that is being referred to for positioning.
   * 
   * Accepts an element or a virtual element (anything with `getBoundingClientRect`),
   * and can be changed reactively to re-anchor the popover (e.g. for a guided tour).
   * If not provided will use the current component as anchor.
   */
  reference?: Element | VirtualElement | undefined;
  /**
   * When `false`, the popover will not close when clicking outside or pressing escape.
   * @default true
   */
  dismissible?: boolean | undefined;
  /**
   * The modality of the popover. When set to true, interaction with outside elements will be disabled and only popover content will be visible to screen readers.
   * @default false
   */
  modal?: boolean | undefined;
  /**
   * The duration from when the mouse enters the trigger until the hover card opens.
   */
  openDelay?: number | undefined;
  /**
   * The duration from when the mouse leaves the trigger or content until the hover card closes.
   */
  closeDelay?: number | undefined;
  /**
   * When `true`, tapping the trigger on touch devices toggles the hover card open/closed. By default touch interactions are ignored to match pointer hover semantics.
   */
  enableTouch?: boolean | undefined;
  modelValue?: string | undefined;
}
```

### Emits

```ts
/**
 * Emitted events for the MColorChooser component
 */
interface MColorChooserEmits {
  update:modelValue: (payload: [value: string | undefined]) => void;
  update:open: (payload: [open: boolean]) => void;
  change: (payload: [value: string | undefined]) => void;
  clear: (payload: []) => void;
  copy: (payload: [value: string]) => void;
  format-change: (payload: [format: ColorFormat]) => void;
}
```

### Slots

```ts
/**
 * Slots for the MColorChooser component
 */
interface MColorChooserSlots {
  default(): any;
  leading(): any;
  trailing(): any;
  swatches(): any;
  actions(): any;
}
```

## Theme

<component-theme>



</component-theme>

## Changelog

See commit history for [src/runtime/components/ColorChooser.vue](https://github.com/mhaibaraai/movk-nuxt/commits/main/src/runtime/components/ColorChooser.vue).


## Sitemap

See the full [sitemap](https://nuxt.mhaibaraai.cn/sitemap.md) for all pages.
