---
title: "ColorChooser"
description: "可视化颜色选择器组件。"
seo_title: "ColorChooser"
seo_description: "A visual color picker supporting hex/rgb/hsl formats, preset swatches, copy and clearable selection."
canonical_url: "https://nuxt.mhaibaraai.cn/docs/components/color-chooser"
---
# ColorChooser

> 可视化颜色选择器组件。

## 简介

`MColorChooser` 是一个可视化的颜色选择器组件。提供色盘与 HSL 滑块取色，支持自定义触发器形态、预设色板、复制与清除，并将值同步为 hex、rgb 或 hsl 三种格式之一。

> \[\!NOTE\]
> See: https://ui.nuxt.com/docs/components/color-picker
> 
> 基于 Nuxt UI 的 ColorPicker 组件封装

## 用法

默认按钮触发器展示当前色值，点击打开 popover 后从面板选择并同步 v-model：

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

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

### `formats` 输出格式

在 popover 顶部切换 `hex`、`rgb`、`hsl` 、`cmyk`、`lab`，当前值会转换为对应格式：

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

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

### `swatches` 单组预设

一维 `swatches` 渲染为连续色板，点击色块选中颜色并默认关闭弹层：

```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` 分组预设

二维 `swatches` 按行分组展示色相与中性色，`closeOnSwatch` 控制选择后是否关闭：

```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` 控制触发器形态：`button` 渲染按钮，`chip` 仅渲染紧凑色块，`input` 提供色点 + 文本输入并在 blur 时校验 hex：

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

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

### `copyable` 复制按钮

`copyable` 启用 popover 底部的复制按钮，点击触发 `@copy` 事件：

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

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

### `clearable` 清除按钮

`clearable` 启用 popover 底部的清除按钮，点击重置当前值并触发 `@clear` 事件：

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

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

### `ui` 样式定制

`ui` 覆盖内部 slot 的 class，可定制色板网格与色块尺寸，不影响取色、复制和清除机制：

```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` 阻止 popover 打开，`input` 触发器进入只读状态，当前值保持可展示：

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

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

## 示例

### 继承字段上下文

放入 `UFormField` 后继承 `size` 与错误态，触发器按表单状态渲染：

```vue
<template>
  <UFormField label="品牌色" size="xs" error="示例错误态">
    <MColorChooser />
  </UFormField>
</template>
```

### 融入`UFieldGroup`

与按钮置于 `UFieldGroup` 时共用尺寸、圆角和边框衔接，适合表单行内取色：

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

### 自定义触发器渲染

`default` 插槽可完全接管触发器外观，同时通过 `open` 与 `value` slot props 保持弹层状态可见：

```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?: ColorFormat | 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。
   */
  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.
   */
  mode?: M | undefined;
  /**
   * The content of the popover.
   */
  content?: (Omit<PopoverContentProps, "as" | "asChild" | "forceMount"> & Partial<EmitsToProps<PopoverContentImplEmits>>) | undefined;
  /**
   * Display an arrow alongside the popover.
   * `{ rounded: true }`{lang="ts-type"}
   */
  arrow?: boolean | Omit<PopoverArrowProps, "as" | "asChild"> | undefined;
  /**
   * Render the popover in a portal.
   */
  portal?: string | boolean | 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?: ReferenceElement | undefined;
  /**
   * When `false`, the popover will not close when clicking outside or pressing escape.
   */
  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.
   */
  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](/sitemap.md) for all pages.
