- UI组件
- 前端
【免费下载链接】wired-elements
Collection of custom elements that appear hand drawn. Great for wireframes or a fun look.
导读
wired-combo是 wired-elements 组件库中模拟原生浏览器<select>的下拉组合选择器(Combobox),其外观采用手绘线框(wireframe)风格,非常适合原型设计、线框图或追求趣味视觉的页面。本文基于仓库中 docs/wired-combo.md 文档,并结合 wired-combo 源码 深入讲解其安装方式、属性、事件、CSS 自定义变量与底层交互实现,帮助你在项目中快速落地这一组件,并理解其内部工作原理。
一、组件概述
wired-combo是一个手绘风格的下拉选择控件,功能上等价于原生select元素:点击后弹出一个包含wired-item选项的列表,用户选择后,选中项文本显示在触发面板上。从源码注释与类定义看(src/wired-combo.ts#L19-L23),组件基于 Lit 实现,内部使用 RoughJS 生成手绘 SVG 描边,并通过wired-card承载弹出的选项列表。
二、安装与引入
1. 通过 npm 安装
将 wired-elements 添加到你的 JavaScript 项目中:
npm i wired-elements该包在仓库 package.json 中声明的版本为3.0.0-rc.7,依赖lit与roughjs,类型声明与模块入口均指向编译后的lib/目录。
2. 在代码中导入模块
import { WiredCombo } from 'wired-elements'; // 或者按需单独导入 import { WiredCombo } from 'wired-elements/lib/wired-combo.js';所有组件也统一从 src/wired-elements.ts 汇总导出,因此一次import { WiredCombo } from 'wired-elements'即可。
3. 直接通过 CDN 在 HTML 页面中使用
<script type="module" src="https://unpkg.com/wired-elements/lib/wired-combo.js?module"></script>导入后,浏览器会注册<wired-combo>自定义元素,可直接在 HTML 中书写。
三、基础用法
在 HTML 中使用wired-combo时,需要配合wired-item声明选项列表:
<wired-combo id="combo" selected="two"> <wired-item value="one">Number One</wired-item> <wired-item value="two">Number Two</wired-item> <wired-item value="three">Number Three</wired-item> </wired-combo>这里selected="two"指定初始选中项,其值需与某个wired-item的value属性匹配。仓库提供了完整的可运行示例 examples/combo.html,其中展示了三个不同状态的组合框(带默认选中、禁用态、无选中态)以及通过按钮读取所有组合框selected值的脚本:
<script> document.querySelector('button').addEventListener('click', () => { const combos = document.querySelectorAll('wired-combo'); combos.forEach((c) => { console.log(c, c.selected); }); }); </script>wired-item 选项元素
wired-item是 wired-combo 的选项载体,其自身文档见 docs/wired-item.md,源码位于 src/wired-item.ts。它暴露以下属性:
| 属性 | 类型 | 说明 |
|---|---|---|
value | string | 选项的值,用于与wired-combo的selected匹配 |
name | string | 选项名称 |
selected | boolean | 当前是否处于选中状态,由组合框内部驱动 |
wired-item内部渲染为一个按钮,选中时通过hachureFill(来自 src/wired-lib.ts)在手绘边框内填充斜线纹理,形成"被圈选"的视觉效果,背景色可由 CSS 变量控制(见下文)。
四、属性(Properties)
wired-combo暴露两个核心属性(src/wired-combo.ts#L21-L23):
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
disabled | boolean | false | 禁用该组合框,禁止展开与选择 |
selected | string | 无 | 当前选中项的value值 |
selected是响应式属性,且带有reflect: true,即设置后会在 DOM 属性上同步。源码中组件还维护了一个内部只读对象value(类型为{ value, text }),用于缓存当前选中项的"值 + 显示文本",渲染时将其文本显示在触发面板上(src/wired-combo.ts#L113-L128)。
disabled 的实际行为
从源码 refreshDisabledState 可以看到,当disabled为true时:
- 组件增加
wired-disabledclass,样式上变为半透明(opacity: 0.5)、cursor: default且pointer-events: none(src/wired-combo.ts#L43-L48); - 组件的
tabIndex被置为-1,使其无法通过 Tab 聚焦; - 下拉箭头多边形被设置为
pointer-events: none,阻止点击(src/wired-combo.ts#L198-L205)。
示例写法:
<wired-combo selected="one" disabled> <wired-item value="one">Disabled</wired-item> <wired-item value="two">Number Two</wired-item> </wired-combo>五、自定义 CSS 变量
wired-combo支持通过 CSS 变量定制外观,文档声明的两个变量如下:
| CSS 变量 | 作用 |
|---|---|
--wired-combo-popup-bg | 组合框展开时下拉面板的背景色,默认值为white |
--wired-item-selected-bg | 选中项的背景(描边)颜色 |
第一个变量在 src/wired-combo.ts#L101 中用于弹出卡片#card的背景:
#card { background: var(--wired-combo-popup-bg, white); }第二个变量在 src/wired-item.ts#L70 中控制选中项手绘描边的颜色:
svg path { stroke: var(--wired-item-selected-bg, #000); }结合示例 examples/combo.html 的写法,可在样式表中覆盖:
wired-combo { --wired-combo-popup-bg: #fafafa; --wired-item-selected-bg: darkblue; }六、事件(Events)
selected:当用户选中某个选项时触发。源码中通过fireEvent派发一个bubbles: true, composed: true的自定义事件(src/wired-combo.ts#L292-L294、src/wired-base.ts#L73-L78),事件对象携带detail.selected,值为当前选中项的value。
监听示例:
document.querySelector('#combo').addEventListener('selected', (e) => { console.log('selected:', e.detail.selected); });注意:selected事件不仅在点击选项时触发,当用户通过键盘上下键切换选项时同样会触发(见下节)。
七、键盘交互与无障碍(ARIA)实现
从源码 firstUpdated 可以看出,wired-combo内置了完整的键盘支持,使其行为接近原生 select:
| 按键 | 行为 |
|---|---|
↑/←(37/38) | 选中上一个选项(selectPrevious) |
↓/→(39/40) | 选中下一个选项(selectNext) |
Enter(13) | 切换下拉面板的展开/收起 |
Space(32) | 展开下拉面板 |
Esc(27) | 收起下拉面板 |
其中selectPrevious与selectNext都是循环遍历wired-item列表的:从当前选中项出发向前/向后移动,到达边界时回绕(src/wired-combo.ts#L296-L340)。每次切换都会更新selected、刷新选中状态并触发selected事件。
无障碍方面,组件在挂载后自动设置:
- 宿主元素
role="combobox"、aria-haspopup="listbox"; - 弹出面板(
wired-card)role="listbox"; - 每个
wired-item设置role="option",选中项设置aria-selected="true"; - 面板展开状态通过
aria-expanded实时同步。
展开面板内的选项在打开时会请求一次重新布局(requestUpdate,见 src/wired-combo.ts#L260-L280),确保手绘图形尺寸正确。
八、底层绘制原理
wired-combo的手绘外观由 RoughJS 生成:组件在updated钩子中清除旧的 SVG 内容,然后根据文本面板的实际尺寸,用 src/wired-lib.ts 提供的rectangle分别绘制文本区边框与右侧 34px 的下拉箭头区,再用polygon绘制箭头三角(src/wired-combo.ts#L181-L206)。每次渲染使用随机的seed(randomSeed(),来自 src/wired-base.ts),因此每次刷新后的"笔迹"略有不同,这正是手绘风格的自然来源。
九、License
wired-combo遵循 MIT 许可,完整许可文本见仓库根目录的 LICENSE。
总结
wired-combo用约三百行源码(src/wired-combo.ts)实现了功能完整、无障碍友好且交互细节丰富的手绘下拉选择器。它支持disabled/selected两个公开属性、selected事件与两个 CSS 自定义变量,配合wired-item使用即可快速构建线框风格的表单。实际动手时,可直接参考 examples/combo.html 体验三种状态下的表现,再按需接入自己的事件处理与样式定制。
- UI组件
- 前端
【免费下载链接】wired-elements
Collection of custom elements that appear hand drawn. Great for wireframes or a fun look.
相关推荐
Wired Elements项目中的手绘风格组合框组件wired-combo详解
Wired Elements项目中的手绘风格组合框组件wired combo详解 引言:手绘UI的魅力与实用价值 在现代Web开发中,用户界面的视觉表现越来越多
UI组件前端wired-elements 之 wired-radio-group:手绘风格单选组组件完整使用与源码解析
wired elements 之 wired radio group:手绘风格单选组组件完整使用与源码解析 导读 wired radio group 是 wir
UI组件前端wired-card 实战指南:用 wired-elements 打造手绘风格卡片容器
wired card 实战指南:用 wired elements 打造手绘风格卡片容器 wired card 是 wired elements 组件库中的容器型
UI组件前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考