wired-elements 之 wired-combo 手绘风格下拉选择器完全指南
2026/9/23 21:40:10 网站建设 项目流程
  • UI组件
  • 前端

【免费下载链接】wired-elements

Collection of custom elements that appear hand drawn. Great for wireframes or a fun look.

项目地址:https://gitcode.com/gh_mirrors/wi/wired-elements
点击查看免费下载

导读

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,依赖litroughjs,类型声明与模块入口均指向编译后的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-itemvalue属性匹配。仓库提供了完整的可运行示例 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。它暴露以下属性:

属性类型说明
valuestring选项的值,用于与wired-comboselected匹配
namestring选项名称
selectedboolean当前是否处于选中状态,由组合框内部驱动

wired-item内部渲染为一个按钮,选中时通过hachureFill(来自 src/wired-lib.ts)在手绘边框内填充斜线纹理,形成"被圈选"的视觉效果,背景色可由 CSS 变量控制(见下文)。

四、属性(Properties)

wired-combo暴露两个核心属性(src/wired-combo.ts#L21-L23):

属性类型默认值说明
disabledbooleanfalse禁用该组合框,禁止展开与选择
selectedstring当前选中项的value

selected是响应式属性,且带有reflect: true,即设置后会在 DOM 属性上同步。源码中组件还维护了一个内部只读对象value(类型为{ value, text }),用于缓存当前选中项的"值 + 显示文本",渲染时将其文本显示在触发面板上(src/wired-combo.ts#L113-L128)。

disabled 的实际行为

从源码 refreshDisabledState 可以看到,当disabledtrue时:

  • 组件增加wired-disabledclass,样式上变为半透明(opacity: 0.5)、cursor: defaultpointer-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)收起下拉面板

其中selectPreviousselectNext都是循环遍历wired-item列表的:从当前选中项出发向前/向后移动,到达边界时回绕(src/wired-combo.ts#L296-L340)。每次切换都会更新selected、刷新选中状态并触发selected事件。

无障碍方面,组件在挂载后自动设置:

  • 宿主元素role="combobox"aria-haspopup="listbox"
  • 弹出面板(wired-cardrole="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)。每次渲染使用随机的seedrandomSeed(),来自 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.

项目地址:https://gitcode.com/gh_mirrors/wi/wired-elements
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询