ICEN UI 选择器
Docs ⌘K
Core · 稳定

选择器

单选、分组搜索和多选标签。支持首字定位与完整键盘操作,动态选项会自动更新。

Preview
表单 select

基础单选

可搜索 · 分组

多选 · 最多 3 个

富选项 · 固定面板宽

html
<div class="demo-col">  <p class="chart-cap" style="margin:0 0 6px">基础单选</p>  <div class="icen-select" data-icen-select style="width:100%;max-width:280px">    <button class="icen-select-trigger icen-pressable icen-focus-ring" type="button" aria-haspopup="listbox" aria-expanded="false">      <span class="icen-select-value is-empty">选择一种水果</span>    </button>    <div class="icen-select-panel" hidden>      <button class="icen-select-option" type="button" data-icen-value="apple">苹果</button>      <button class="icen-select-option" type="button" data-icen-value="banana">香蕉</button>      <button class="icen-select-option" type="button" data-icen-value="orange">橙子</button>      <button class="icen-select-option" type="button" data-icen-value="grape">葡萄</button>      <button class="icen-select-option" type="button" data-icen-value="mango">芒果</button>    </div>    <input type="hidden" data-icen-select-value name="fruit" />  </div>  <p class="chart-cap" style="margin:14px 0 6px">可搜索 · 分组</p>  <div class="icen-select" data-icen-select data-icen-select-search style="width:100%;max-width:280px">    <button class="icen-select-trigger icen-pressable icen-focus-ring" type="button" aria-haspopup="listbox" aria-expanded="false">      <span class="icen-select-value is-empty">搜索城市…</span>    </button>    <div class="icen-select-panel" hidden>      <div class="icen-select-group">        <p class="icen-select-group-label">华北</p>        <button class="icen-select-option" type="button" data-icen-value="bj">北京</button>        <button class="icen-select-option" type="button" data-icen-value="tj">天津</button>      </div>      <div class="icen-select-group">        <p class="icen-select-group-label">华东</p>        <button class="icen-select-option" type="button" data-icen-value="sh">上海</button>        <button class="icen-select-option" type="button" data-icen-value="hz">杭州</button>        <button class="icen-select-option" type="button" data-icen-value="nj">南京</button>      </div>      <div class="icen-select-group">        <p class="icen-select-group-label">华南</p>        <button class="icen-select-option" type="button" data-icen-value="gz">广州</button>        <button class="icen-select-option" type="button" data-icen-value="sz">深圳</button>      </div>    </div>    <input type="hidden" data-icen-select-value name="city" />  </div>  <p class="chart-cap" style="margin:14px 0 6px">多选 · 最多 3 个</p>  <div class="icen-select" data-icen-select data-icen-select-multiple data-icen-select-max="3" data-icen-select-placeholder="选择标签(最多 3 个)" style="width:100%;max-width:280px">    <button class="icen-select-trigger icen-pressable icen-focus-ring" type="button" aria-haspopup="listbox" aria-expanded="false">      <span class="icen-select-value is-empty">选择标签(最多 3 个)</span>    </button>    <button class="icen-select-clear" type="button" aria-label="清除全部" hidden><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" focusable="false" class="icen-symbol" aria-hidden="true"><path d="M6 6l8 8M14 6l-8 8"></path></svg></button>    <div class="icen-select-panel" hidden>      <button class="icen-select-option" type="button" data-icen-value="ts">TypeScript</button>      <button class="icen-select-option" type="button" data-icen-value="react">React</button>      <button class="icen-select-option" type="button" data-icen-value="vue">Vue</button>      <button class="icen-select-option" type="button" data-icen-value="svelte">Svelte</button>      <button class="icen-select-option" type="button" data-icen-value="rust">Rust</button>      <button class="icen-select-option" type="button" data-icen-value="go">Go</button>    </div>    <input type="hidden" data-icen-select-value name="tags" />  </div>  <p class="chart-cap" style="margin:14px 0 6px">富选项 · 固定面板宽</p>  <div class="icen-select" data-icen-select data-icen-panel-width="216" style="width:100%;max-width:216px">    <button class="icen-select-trigger icen-pressable icen-focus-ring" type="button" aria-haspopup="listbox" aria-expanded="false">      <span class="icen-select-value is-empty">选择色彩预设</span>    </button>    <div class="icen-select-panel" hidden>      <button class="icen-select-option" type="button" data-icen-value="modern"><span class="icen-select-swatch" aria-hidden="true"><i style="background:#f5f6f8"></i><i style="background:#087bf5"></i><i style="background:#58758f"></i></span>现代</button>      <button class="icen-select-option" type="button" data-icen-value="dongyun"><span class="icen-select-swatch" aria-hidden="true"><i style="background:#f4f1e9"></i><i style="background:#477668"></i><i style="background:#85724d"></i></span>东韵</button>      <button class="icen-select-option" type="button" data-icen-value="jugou"><span class="icen-select-swatch" aria-hidden="true"><i style="background:#edece6"></i><i style="background:#b53c2d"></i><i style="background:#596d75"></i></span>巨构</button>      <button class="icen-select-option" type="button" data-icen-value="piano"><span class="icen-select-swatch" aria-hidden="true"><i style="background:#f5f3ed"></i><i style="background:#94713f"></i><i style="background:#657386"></i></span>钢琴</button>      <button class="icen-select-option" type="button" data-icen-value="monet"><span class="icen-select-swatch" aria-hidden="true"><i style="background:#f4f7f4"></i><i style="background:#2b675c"></i><i style="background:#667c8a"></i></span>莫奈</button>      <button class="icen-select-option" type="button" data-icen-value="vangogh"><span class="icen-select-swatch" aria-hidden="true"><i style="background:#f8f3e4"></i><i style="background:#275ea0"></i><i style="background:#a0711e"></i></span>梵高</button>    </div>    <input type="hidden" data-icen-select-value name="preset" />  </div></div>

特性

触发器与输入框同视觉,表单里混排不跳脱;多选的移除按钮原生可聚焦,键盘可直接操作。

接口

初始化
initSelect()(kit 一行入口可直接命名导入)
导出
refreshSelect
事件
icen:select-change detail 契约见 IcenEventMap
类型
dist/behaviors/select.d.mts(随 npm 包发布,含全部 JSDoc 约束)

安装

bun add @icen.ai/ui

一行引入该组件(CSS 与 behavior 自动带上,无需关心内部 CSS 文件名):

js
import { initSelect } from '@icen.ai/ui/kit/select';initSelect();

也可以用脚手架直接打印引入行:

bash
bunx --bun @icen.ai/ui add select

Astro 项目注意:kit 入口里的 CSS import 在页面 <script> 里会被 Astro 的 client bundle 摇掉——请改在布局 frontmatter 里引 CSS(import '@icen.ai/ui/components/select.css';),JS 行为仍可走 kit。Vite SPA / webpack 项目无此问题。

用法

js
import { initSelect, refreshSelect } from '@icen.ai/ui/kit/select';const destroy = initSelect(root);// 子节点、标签文字、原生 disabled 改动会自动同步。// 手动修改 is-selected 类后,可明确请求一次静默同步:refreshSelect(root);// 页面或组件卸载时:destroy();// 事件:icen:select-change(bubbles + composed,detail 全型登记 IcenEventMap)//   detail { value, values, label }://     单选   value = 选中值,values = [value],label = 选项可见文本//     多选   values = 全部选中值,value = 首个选中值,label = 选中项文本 ', ' 连接//     清空   (.icen-select-clear 或逐项取消)→ { value: '', values: [], label: '' }//   隐藏 input(data-icen-select-value)同步值(多选逗号连接)并派原生 change —— 双通道://   icen 事件给行为层,原生 change 给表单框架。import { onIcen } from '@icen.ai/ui';onIcen('icen:select-change', (e) => console.log(e.detail.value, e.detail.values, e.detail.label));<!-- 基础单选 --><div class="icen-select" data-icen-select>…</div><!-- 可搜索(带分组) --><div class="icen-select" data-icen-select data-icen-select-search>…</div><!-- 多选 + 上限 --><div class="icen-select" data-icen-select data-icen-select-multiple data-icen-select-max="3">…</div><!-- 多选:trigger 同级加 .icen-select-clear;选中标签与触发按钮为同级,移除按钮原生可聚焦 --><!-- 富选项:.select-option 内可直接写任意 HTML(色卡 / 图标 / 多行) --><!-- 面板尺寸(全库统一 PanelSizing 契约,浮层组件通用):     data-icen-panel-width="216"        固定宽(最高优先)     data-icen-panel-min / -max         以 trigger 宽为基准夹取     data-icen-panel-max-height="320"   高度上限(select 默认 240) -->