# ColorPicker 颜色选择

从一个按钮触发器唤出取色面板：饱和 / 亮度色板、色相条，以及（开启后）透明度滑杆。`v-model` 始终是 HEX 字符串，面板内可在 HEX 与 RGB 两种输入方式之间切换，两者都写回同一个值。

## 代码演示

### 基础用法

`v-model` 绑定 HEX 字符串，空字符串表示「未选择」。加 `clearable` 后触发器上出现清除按钮。

**演示说明：** 触发器左侧是当前色的色板，右侧是色值文本。

```vue
<script setup lang="ts">
import { ref } from 'vue'

const primary = ref('#1976d2')
const accent = ref('#9c27b0')
</script>

<template>
  <div class="m-row-demo--col">
    <div class="m-row-demo">
      <MColorPicker v-model="primary" />
      <MColorPicker v-model="accent" clearable />
    </div>
    <span>主色 {{ primary }} / 强调色 {{ accent || '未选择' }}</span>
  </div>
</template>
```

### 尺寸

`small` / `default` / `large` 三档，同时影响触发区高度与文字。

```vue
<script setup lang="ts">
import { ref } from 'vue'

const small = ref('#1976d2')
const normal = ref('#43a047')
const large = ref('#e53935')
</script>

<template>
  <div class="m-row-demo">
    <MColorPicker v-model="small" size="small" />
    <MColorPicker v-model="normal" size="default" />
    <MColorPicker v-model="large" size="large" />
  </div>
</template>
```

### 透明度

`showAlpha` 开启后输出 9 位 `#RRGGBBAA`，关闭时输出 7 位 `#RRGGBB`。

**演示说明：** 面板里会多出一条透明度滑杆。

```vue
<script setup lang="ts">
import { ref } from 'vue'

const opaque = ref('#1976d2')
const alpha = ref('#1976d280')
</script>

<template>
  <div class="m-row-demo--col">
    <div class="m-row-demo">
      <MColorPicker v-model="opaque" :show-alpha="false" />
      <MColorPicker v-model="alpha" :show-alpha="true" />
    </div>
    <span>不含透明度 #RRGGBB：{{ opaque }}</span>
    <span>含透明度 #RRGGBBAA：{{ alpha }}</span>
  </div>
</template>
```

### 预设色

`presets` 传入常用色，面板底部会渲染成一排色块，点击即选中。

**演示说明：** 非法项会被过滤，重复项会去重。

```vue
<script setup lang="ts">
import { ref } from 'vue'

const brand = ref('#1976d2')
const custom = ref('')
const presetColors = ['#1976d2', '#9c27b0', '#43a047', '#fb8c00', '#e53935', '#757575']
</script>

<template>
  <div class="m-row-demo--col">
    <div class="m-row-demo">
      <MColorPicker v-model="brand" clearable :presets="presetColors" />
      <MColorPicker v-model="custom" :presets="presetColors" />
    </div>
    <span>品牌色：{{ brand }}，自定义色：{{ custom || '未选择' }}</span>
  </div>
</template>
```

### 禁用

`disabled` 时触发器不可点击，面板不会展开。

```vue
<script setup lang="ts">
import { ref } from 'vue'

const locked = ref('#1976d2')
const empty = ref('')
</script>

<template>
  <div class="m-row-demo">
    <MColorPicker v-model="locked" disabled />
    <MColorPicker v-model="empty" disabled />
  </div>
</template>
```

## API

### Props

| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `modelValue` | `string` | `''` | HEX：`#RGB` / `#RGBA` / `#RRGGBB` / `#RRGGBBAA`；空字符串表示未选择 |
| `disabled` | `boolean` | `false` | 是否禁用 |
| `size` | `'small' \| 'default' \| 'large'` | `'default'` | 尺寸 |
| `showAlpha` | `boolean` | `false` | 开启后输出 `#RRGGBBAA`，否则输出 `#RRGGBB` |
| `clearable` | `boolean` | `false` | 是否显示清除按钮 |
| `presets` | `string[]` | `[]` | 预设色列表（会做归一化与去重） |
| `ariaLabel` | `string` | `'选择颜色'` | 无障碍标签 |

### Events

| 事件 | 参数 | 说明 |
| --- | --- | --- |
| `update:modelValue` | `value: string` | 颜色值变化 |
| `change` | `value: string` | 颜色值变化 |
| `clear` | 无 | 点击清除且此前确有值时触发 |

### Slots

无。

## 使用建议

::: tip 绑定值始终是 HEX
面板右上角的按钮可以在 HEX 输入与 RGB 三通道输入之间切换，但那只是输入方式；`v-model` 读到的永远是 `#RRGGBB` 或 `#RRGGBBAA` 字符串，业务侧不需要判断当前是哪种输入模式。
:::

::: tip 与设计令牌配合
把取色结果回填到 CSS 变量（如 `--m-primary`）时，建议统一开启或关闭 `showAlpha`，避免同一套令牌里混入 7 位与 9 位两种长度。
:::

::: warning 非法输入会在面板内提示
在 HEX 输入框里输入无法解析的内容时，面板会显示「请输入有效的 HEX 颜色」并标记 `aria-invalid`，此时不会写回 `modelValue`。
:::

::: warning 组件没有圆角 prop
`MColorPicker` 未提供 `radius` / `panelRadius` 一类的圆角参数，触发区与弹出面板使用组件内置圆角。需要改圆角时只能从样式层覆盖，不要传入不存在的 prop。
:::

## 相关组件

- [Input 输入框](/components/input)：只需要输入十六进制色值、不需要取色面板时使用。
- [Slider 滑块](/components/slider)：透明度、色相等连续量的滑杆交互参考。
