NovaColorPicker 取色器
NovaColorPicker 提供 HSV 面板、Hue/Alpha 滑条与 HEX/RGB/HSL 文本输入,默认通过 NovaDropdown 渲染浮层,并继承 NovaEnvironment 提供的主题与语言。可直接 import { NovaColorPicker } from 'nova-next' 使用;安装步骤请参阅 快速开始。
示例
基础用法
最常见的 3 个受控取色器,展示 v-model 与默认触发器外观。
预览
#1890ff
#52c41a
#ff4d4f
源码
vue
<script setup lang="ts">
import { ref } from 'vue'
import '@jiangshengdev/nova-next/styles/themes.css'
import '@jiangshengdev/nova-next/styles/dropdown.css'
import '@jiangshengdev/nova-next/styles/color-picker.css'
import { NovaColorPicker } from '@jiangshengdev/nova-next'
const brandColor = ref('#1890ff')
const successColor = ref('#52c41a')
const dangerColor = ref('#ff4d4f')
</script>
<template>
<div class="demo-column">
<div class="demo-group">
<NovaColorPicker v-model="brandColor" />
<p class="demo-tip">{{ brandColor }}</p>
</div>
<div class="demo-group">
<NovaColorPicker v-model="successColor" />
<p class="demo-tip">{{ successColor }}</p>
</div>
<div class="demo-group">
<NovaColorPicker v-model="dangerColor" />
<p class="demo-tip">{{ dangerColor }}</p>
</div>
</div>
</template>
<style scoped>
.demo-column {
display: flex;
flex-wrap: wrap;
gap: 12px 48px;
}
.demo-group {
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-items: center;
gap: 8px;
}
.demo-tip {
margin: 0;
font-size: 13px;
font-family: ui-monospace, monospace;
}
</style>透明度与格式
根据开关切换 Alpha 滑条,并在 HEX/RGB/HSL 三种输出间切换。
预览
输出格式
源码
vue
<script setup lang="ts">
import { ref, watch } from 'vue'
import '@jiangshengdev/nova-next/styles/themes.css'
import '@jiangshengdev/nova-next/styles/dropdown.css'
import '@jiangshengdev/nova-next/styles/color-picker.css'
import { NovaColorPicker, Color } from '@jiangshengdev/nova-next'
const color = ref('rgba(64, 158, 255, 0.8)')
const alphaEnabled = ref(true)
const format = ref<'hex' | 'rgb' | 'hsl'>('rgb')
// 当 alphaEnabled 或 format 改变时,重新格式化颜色值
watch([alphaEnabled, format], ([newAlphaEnabled], [oldAlphaEnabled]) => {
const parsedColor = Color.parse(color.value)
const { red, green, blue } = parsedColor
if (!newAlphaEnabled) {
// 移除透明通道
const opaqueColor = new Color(red, green, blue)
color.value = opaqueColor.toString(format.value)
} else if (oldAlphaEnabled === false) {
// 从关闭切换到开启,设置为 80% 透明
const transparentColor = new Color(red, green, blue, 0.8)
color.value = transparentColor.toString(format.value)
} else {
// 只是格式切换,保持透明通道
color.value = parsedColor.toString(format.value)
}
})
</script>
<template>
<div class="demo-alpha">
<div class="demo-controls">
<div class="demo-control">
<label class="demo-checkbox">
<input v-model="alphaEnabled" type="checkbox" /> 透明通道
</label>
</div>
<div class="demo-control">
<span>输出格式</span>
<label class="demo-radio"> <input v-model="format" type="radio" value="hex" /> HEX </label>
<label class="demo-radio">
<input v-model="format" type="radio" value="rgb" /> RGB(A)
</label>
<label class="demo-radio">
<input v-model="format" type="radio" value="hsl" /> HSL(A)
</label>
</div>
</div>
<div class="demo-picker">
<NovaColorPicker v-model="color" :alpha="alphaEnabled" :format="format" />
<span class="demo-value">{{ color }}</span>
</div>
</div>
</template>
<style scoped>
.demo-alpha {
display: flex;
flex-wrap: wrap;
flex-direction: column;
gap: 12px;
}
.demo-controls {
display: flex;
flex-wrap: wrap;
flex-direction: column;
align-items: flex-start;
gap: 8px;
font-size: 13px;
}
.demo-control {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.demo-checkbox {
display: inline-flex;
align-items: center;
gap: 4px;
cursor: pointer;
}
.demo-checkbox input[type='checkbox'] {
margin: 0;
}
.demo-radio {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 4px;
cursor: pointer;
}
.demo-radio input[type='radio'] {
margin: 0;
}
.demo-picker {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.demo-value {
font-family: ui-monospace, monospace;
font-size: 13px;
}
</style>预设色卡
使用 preset 提供常用与主题色列表,面板关闭后自动回写最新值。
预览
常用颜色#40a9ff
主题色组合#faad14
源码
vue
<script setup lang="ts">
import { ref } from 'vue'
import '@jiangshengdev/nova-next/styles/themes.css'
import '@jiangshengdev/nova-next/styles/dropdown.css'
import '@jiangshengdev/nova-next/styles/color-picker.css'
import { NovaColorPicker } from '@jiangshengdev/nova-next'
const color = ref('#40a9ff')
const accent = ref('#faad14')
const presetColors = ['#ff4d4f', '#ff7a45', '#ffa940', '#ffc53d', '#bae637', '#73d13d', '#40a9ff']
const themeColors = ['#1677ff', '#36cfc9', '#faad14', '#f5222d']
</script>
<template>
<div class="demo-preset">
<div class="demo-group">
<span class="demo-label">常用颜色</span>
<NovaColorPicker v-model="color" :preset="presetColors" />
<span class="demo-value">{{ color }}</span>
</div>
<div class="demo-group">
<span class="demo-label">主题色组合</span>
<NovaColorPicker v-model="accent" :preset="themeColors" />
<span class="demo-value">{{ accent }}</span>
</div>
</div>
</template>
<style scoped>
.demo-preset {
display: flex;
flex-wrap: wrap;
flex-direction: row;
gap: 12px 48px;
}
.demo-group {
display: flex;
flex-wrap: wrap;
flex-direction: row;
align-items: center;
gap: 8px;
}
.demo-label {
font-size: 13px;
}
.demo-value {
font-family: ui-monospace, monospace;
font-size: 13px;
}
</style>自定义触发器
通过 trigger 插槽替换触发按钮,仍保留下拉定位与焦点管理。
预览
源码
vue
<script setup lang="ts">
import { ref } from 'vue'
import '@jiangshengdev/nova-next/styles/themes.css'
import '@jiangshengdev/nova-next/styles/dropdown.css'
import '@jiangshengdev/nova-next/styles/color-picker.css'
import { NovaColorPicker } from '@jiangshengdev/nova-next'
const highlight = ref('#722ed1')
</script>
<template>
<div class="demo-trigger">
<NovaColorPicker v-model="highlight">
<template #trigger>
<button type="button" class="demo-trigger-button">
<span class="demo-trigger-label">选中颜色</span>
<span class="demo-trigger-value">{{ highlight }}</span>
</button>
</template>
</NovaColorPicker>
</div>
</template>
<style scoped>
.demo-trigger {
display: flex;
flex-wrap: wrap;
align-items: center;
}
.demo-trigger-button {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 14px;
border: 1px solid var(--vp-c-divider);
border-radius: 8px;
background: transparent;
cursor: pointer;
font-size: 14px;
}
.demo-trigger-value {
font-family: ui-monospace, monospace;
}
</style>属性
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
modelValue | 受控值,配合 v-model 使用,优先级高于 value。 | string | null |
value | 非受控初始值,未传入 modelValue 时生效。 | string | '#ff0000' |
alpha | 是否展示 Alpha 滑条与输入,关闭时会自动丢弃透明度。 | boolean | false |
format | 决定 v-model 输出格式。 | 'hex' | 'rgb' | 'hsl' | 'hex' |
preset | 预设色列表,传入十六进制或 CSS 颜色字符串即可渲染拾色块。 | string[] | null |
disabled | 禁用状态,继承自 NovaDropdown,会阻止触发与键盘交互。 | boolean | false |
theme | 覆盖环境主题,内部同时写入 data-nova-theme。 | string | null |
placement | 下拉面板定位,同 NovaDropdown,支持 bottomLeft 等多个预设位置。 | Placement | 'bottomLeft' |
teleportToBody | 是否将面板 Teleport 到 document.body,便于脱离溢出容器。 | boolean | true |
panelClass | 作用于下拉面板的额外类名,可自定义尺寸与圆角。 | unknown | null |
panelStyle | 作用于下拉面板的内联样式。 | StyleValue | null |
panelProps | 添加到下拉面板根节点的原生属性,如 data-*。 | Record<string, unknown> | null |
插槽
| 名称 | 说明 |
|---|---|
trigger | 自定义触发器内容,保持焦点自动管理。作用域提供 color、disabled 等 ColorPickerTriggerScoped 数据。 |
preset | 自定义预设区域,可根据 preset 数组与 setColorAndPosition 方法自行渲染色卡。 |
事件
| 名称 | 说明 |
|---|---|
update | JSX 专用更新事件,返回最新颜色字符串。 |
update:modelValue | v-model 所需的同步事件。 |
NovaColorPicker 不额外派发打开/关闭事件,相关需求可通过外层 NovaDropdown 处理。