npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wil-works/evoke-tools-ui

v1.4.1

Published

Evoke Tools UI — 纯 JS Vue3 产品级 GUI 框架(工具区 / 停靠 / 外壳件 + 运行时契约,命名空间 --et-*,底座 @wil-works/evoke-business-ui)

Readme

@wil-works/evoke-tools-ui

npm version npm version

Evoke Tools UI —— 纯 JS Vue3 产品级 GUI 框架(命名空间 --et-*)。

服务对象:要把界面做成一个软件的产品——文档/画布居中,工具退到边缘, chrome(标题栏 / 工具区 / 状态栏)环绕内容;常驻布局、键盘优先、命令驱动。

  • 设计语言白皮书:DESIGN.md
  • 计划全文:仓库根 plans/tools-ui/01–07
  • 文档站:docs-tools/(指南 9 页 + 36 件组件页全覆盖 + 9 个案例)

版本与 API 稳定性承诺(v1.0 起)

@wil-works/evoke-tools-ui 自 1.0.0 起遵守语义化版本,以下为承诺范围:

| 面 | 承诺 | 说明 | | --- | --- | --- | | 组件 props / emits / slots | 冻结:只增不改不删(minor 新增、patch 修缺陷) | 删除或改名走 major;新增 prop 总有默认值,不改既有渲染 | | ./runtime 契约(函数签名与返回结构) | 冻结:同上 | 返回结构新增字段 = minor;删除/改名 = major | | 令牌 --et-* | 冻结:值可随主题变,名字不删不改 | 新令牌 minor 新增;消费方直接引用单个令牌的写法不受影响 | | class 钩子 et-* / is-* 状态类 | 冻结 | 产品按类做样式覆盖/测试选择器;改名 = major | | 子路径导出(./styles、./runtime、./icons、./<component>) | 冻结 | 新增组件子路径 = minor | | 兜底行为 | 承诺级:图标未命中回落显式兜底图标、布局损坏降级默认布局不白屏、存储异常静默降级 | 这三条是框架级承诺,变更走 major 并提前一个 minor 弃用警告 |

弃用流程:要删的东西先在 minor 里标记弃用(运行时 dev warn 一条,不刷屏), 至少一个 minor 之后才在 major 删除。1.0 之后没有"顺手改名"——改名就是破坏性变更。

质量门与测试层(构建前置)

七道门(G1 令牌 / G2 图标 / G3 命令面 / G4 可访问名 / G5 组字 / G6 文案 / G7 几何)挂入 pnpm build:tools;发布前 node scripts/pre-release-check.mjs 跑版本展示点守卫 + 图标数 + 组件数宣称核对(G8,M4 新增)。测试层 L1 契约 / L2 组件 / L3 视觉(基线入库,CI 的 visual 作业锁定)/ L4 集成(workbench 装配)/ L5 复用检验(非办公域)。

安装与使用

pnpm add @wil-works/evoke-tools-ui @wil-works/evoke-business-ui vue
import { createApp } from 'vue'
import EvokeToolsUI from '@wil-works/evoke-tools-ui'
import '@wil-works/evoke-tools-ui/styles'
import '@wil-works/evoke-business-ui/styles' // 底座样式(reset + --eb-* + 暗色)

const app = createApp(App)
app.use(EvokeToolsUI)

三档密度

密度是根级属性(<html data-density>),由 EtProvider 写入;组件只引用令牌。

<et-provider density="compact">
  <app />
</et-provider>

紧凑 24 / 默认 32 / 宽松 40 的控件高对齐 Fluent UI 的 small/medium/large 阶梯。

两层与用途分类(v1.3 起)

| 层 | 入口 | 件数 | 装什么 | | --- | --- | --- | --- | | common-tools | @wil-works/evoke-tools-ui/common | 29 | 基准件 / 通用壳 / 命令面 / 面板 / 反馈 / 输入(不含办公语义) | | office-tools | @wil-works/evoke-tools-ui/office | 7 | 功能区 / 溢出菜单 / 后台页 / 表页签 / 公式栏 / 画布宿主 / 画布桥(办公形态) |

import CommonTools from '@wil-works/evoke-tools-ui/common'
import OfficeTools from '@wil-works/evoke-tools-ui/office'
createApp(App).use(CommonTools).use(OfficeTools)   // 也可只装一层

一级分类按工具用途(壳 / 工具区 / 命令 / 面板 / 反馈 / 输入 / 基础),二级标粒度 (原子件 / 功能块 / 契约)。两份单一来源:

  • src/taxonomy.js —— 分类(层 / 用途 / 粒度 / 摘要):文档站侧栏、两层概览页与站内搜索都从它派生; scripts/check-taxonomy.mjs(G9 门)与 test/taxonomy.test.js 守一致性。
  • src/slots.js —— 槽位组合契约(谁开了哪些槽、吃什么、作用域是什么):文档站「组合契约」页从它渲染, scripts/check-slots.mjs(G10 门)与 SFC 双向核对——删槽、漏记都会红。

工具区与命令(common · toolbar / command)

<et-ribbon-bar
  v-model="activeTab"
  v-model:collapsed="collapsed"
  :schema="ribbonSchema"
  :registry="commandRegistry"
  :context-tabs="contextTabs"
  :ctx="{ hasSelection: true }"
  persist-key="my-app-ribbon"
  @command="onCommand"
/>
  • 命令表驱动:createCommandRegistry() + schema(tab→组→条目),mergeSchema 打补丁;
  • 真折叠(Ctrl+F1 / ⌥⌘R / 双击)与 peek 浮层;分量降级与溢出「更多」禁换行;
  • 同一命令表再驱动 <et-command-palette>(⌘K)与 <et-context-menu>(右键)。

工作台与面板(common · shell / panel)

<et-workbench v-model:layout="layout" :default-layout="DEFAULT" persist-key="my-app"
  @layout-corrupted="onCorrupted">
  <template #toolbar><et-ribbon-bar :schema="..." :registry="..." /></template>
  <template #panel="{ panel }"><my-panel :id="panel.id" /></template>
  <template #documents><et-document-tabs v-model="doc" :documents="docs" /></template>
  <main>画布</main>
  <template #statusbar>就绪</template>
</et-workbench>
  • 布局即数据:createLayoutTree / togglePanelCollapsed / hidePanel / maximizePanel(纯函数, ./runtime 出口);EtWorkbench 是唯一写树处;
  • EtDock(stack 并列分摊尺寸 / tabs 档)+ EtPanel(28px 标题栏 + 折叠/最大化/关闭)+ EtScrollArea + EtEmptyState(一句引导 + 一个主钮)+ EtDocumentTabs(脏标记/关闭/溢出)。

外壳件与反馈(common · shell / feedback,含 office 的 Backstage)

<et-title-bar title="我的工具" doc-title="报表.xlsx" @window-control="onWinCtl" />
<et-workbench ...>…</et-workbench>
<et-status-bar :items="[{ key: 'ready', label: '就绪' }]" zoom="100%" />
<et-theme-bridge />   <!-- 零 DOM:主题 → 画布 --ot-* 调色板 -->
<et-dialog v-model="open" title="新建" confirm-text="创建" @confirm="onConfirm" />
<et-backstage v-model="backstage"><template #nav>…</template>…</et-backstage>
<et-toast v-model="toastOpen" message="已保存" />
<et-banner type="warn" title="有未保存改动" />
  • 主题桥:EtThemeBridge 零 DOM,把主题令牌解析成画布 --ot-*(登记表无硬编码色值);
  • 双宿主:EtTitleBar 的窗口控制位 Web 不渲染 / 桌面 mac 左序 / Win·Linux 右序(host prop 可钉死);
  • 焦点三处一致:Dialog / Backstage / 命令面板共用 runtime/focus/trap(Tab 循环 + Esc 收敛 + 焦点归还触发器);backstage 开关不引发画布尺寸跳动。

子路径导出

| 入口 | 内容 | | --- | --- | | . | 全部组件(36)+ 运行时契约 + 图标机制 + 分类与槽位元数据 | | ./common | common-tools:29 件(基准件 / 通用壳 / 命令面 / 面板 / 反馈 / 输入) | | ./office | office-tools:7 件(功能区 / 溢出菜单 / 后台页 / 表页签 / 公式栏 / 画布宿主 / 画布桥) | | ./styles | --et-* 令牌 + 暗色 + 基础样式 | | ./runtime | L0 契约:命令注册表 / 菜单 schema / 工具区状态机 / 键位表 / 焦点漫游 / 布局树 / 画布调色板 / 焦点陷阱 / 宿主探测 | | ./icons | 图标解析兜底 + 领域别名注册 API | | ./<component> | 按需引入,如 @wil-works/evoke-tools-ui/tool-button |

质量门(构建前置,违规即失败)

| 门 | 判据 | 脚本 | | --- | --- | --- | | G1 | 令牌纯度 / 回流禁令 / 引用完整 / 依赖白名单 | scripts/check-token-rule.mjs | | G9 | 两层(common/office)与用途分类同源,三处视图不许漂移 | scripts/check-taxonomy.mjs | | G10 | 槽位契约 ↔ SFC 双向一致(删槽 / 漏记都失败) | scripts/check-slots.mjs | | G7 | 布局属性禁字面量 px、z-index 走阶梯、工具组契约 | scripts/check-geometry.mjs | | G2 | 悬空图标名 = 失败 | scripts/check-icon-names.mjs | | G4 | 图标按钮必须 aria-label | scripts/a11y-names.mjs | | G5 | window/document 级 keydown 必过组字守卫 | scripts/ime-guard.mjs | | G3 | 命令引用已注册 / surfaces 合法 / 状态单点实现 | scripts/check-command-surface.mjs | | G6 | 模板禁 § 引用、禁成段说明、禁开发说明字样 | scripts/check-copy.mjs | | —— | 三档密度 / chrome 预算与设计文档表格逐项一致 | scripts/check-density.mjs |

开发

pnpm build:tools            # 五道门 + vue-tsc 类型产物 + 子路径存根
pnpm vitest run packages/evoke-tools-ui   # 一组件一测试
pnpm tokens:export          # 令牌 JSON(design-tokens/evoke-tools-ui.*.json)
pnpm example:tools-workbench   # 工作台装配示例(源码级 HMR)

边界(不做什么)

不做业务组件、不做办公语义(不认识"单元格/公式/工作表")、不做官网件、不做图表、 不绑定数据获取/状态管理/路由、不做移动端专属形态、不引入第三方组件库。 能复用 business-ui 的一律复用;扩展不得修改底座既有语义。