@exponential_app/eui-element

中文文档
0.21.0发布于 2026/11/10Apache-2.0TypeScriptES Module构建来源已验证近 30 天下载 5450

genUI作为一个自定义元素:在主机页面上画出一个没有框架的核心 A2UI 表面,在 Solid 画像和共享的网页层上,其DOM,编译的样式表和运行时的主题与 React 渲染相同

中文使用文档
文档目录11 节
  1. 变化者
  2. API 密码
  3. QrScanner相机
  4. 卡鲁塞尔缩略图
  5. 活动
  6. 主持人 API
  7. 扩展
  8. 无框架主机的图标
  9. 条目
  10. 版式
  11. 图标

@exponential_app/eui-element: genUI 作为自定义元素

<exponential-surface> 在核心目录中绘制 A2UI 表面 (单位:千美元)@exponential_app/eui)在任意一页,没有框架(FEED-130)。 没有 有个自己的画家 它能搭载固体制造器 (单位:千美元)@exponential_app/eui-solid里面,你得到一个画家和两个 进入点。 元素使用光 DOM 并且是 display: contents 结束 一个共享的零特性规则 define() 安装( e):where(exponential-surface){display:contents}, (中文(简体) ), 所以,你的任何规则 赢了,所以表面的 .xui-surface 根为框, 同一地点的 React的DIV会是。 一个任务中附加的元素挂起 一起:第一个一次,剩下的在一个批次内的微任务中.

变化者

对于每个表面,元素 精确地描绘什么反应渲染器 油漆:相同的元素、属性, <style data-xui-style> 床单, 层和运行时间主题. src/parity.test.ts 比较元素的 .xui-surface 子树对 @exponential_app/eui-react 在jsdom中,使用 软件包 serializeDom 财务报告和审定财务报表 renderReact。 。 。 .

<script type="module">
  import "@exponential_app/eui-element/define"   // or the self-contained ./standalone bundle
</script>

<exponential-surface theme="orange" mode="system" src="/ui/stream" post="/ui/events"></exponential-surface>

<script type="module">
  const el = document.querySelector("exponential-surface")
  el.addEventListener("xui-action", (e) => e.detail.waitUntil(fetch("/save", { method: "POST", body: JSON.stringify(e.detail.context) })))
</script>

没有服务器,就打电话 apply() 输入 A2UI v0.9 信件 :

const el = document.createElement("exponential-surface")
document.body.append(el)
el.apply({ createSurface: { surfaceId: "main", catalogId } })
el.apply({ updateComponents: { surfaceId: "main", components } })

API 密码

属性/ 属性什麽
theme内置标识( 属性) 。 属性还取一个主题 JSON 或 a ResolvedTheme; 对象不反映。 一个无法使用的主题从不扔出:默认的主题画和 xui-theme-issues 火灾.
modelight, (中文(简体) ), dark 或者说 system (默认者,按住)
density, (中文(简体) ), contrastcompact, (中文(简体) ), default 或者说 comfortable· ; normal, (中文(简体) ), high 或者说 system
locale, (中文(简体) ), time-zone (单位:千美元)timeZone(中文(简体) )BCP 47 地块( 默认) en-US)和IANA时区(默认站台)
directionltr 或者说 rtl (默认: 语区方向)
form-factor (单位:千美元)formFactor(中文(简体) )phone 或者说 wide: 主机的形式因子,什么 @media (form-factor: …) 匹配( 默认: 取自表面宽度, phone 主题以下 $breakpoint.md(中文(简体) )
width, (中文(简体) ), height数字字符串表示px;任何其他字符串都是CSS长度. 明确 height 是高度条件的取景口.
surface-id (单位:千美元)surfaceId(中文(简体) )表面 ID( 默认) main: xui-s-<id> 班级,商店 apply() 造作,而宿主所画的表面
src, (中文(简体) ), post, (中文(简体) ), transport主办方API(见下文)
surfaceA 类 createSurface 存储( 相对于其他来源优先)
root, (中文(简体) ), templates, (中文(简体) ), dataFixture 模式:一个正态树,它的被升起的模板和一个数据模型
host一个 ExponentialHost 替换为 src
pluginA 类 HostPlugin:图标, Markdown、URL和媒体政策, optionSource, (中文(简体) ), mediaRequest, (中文(简体) ), mediaStreamUrl, (中文(简体) ), resolveUrl, (中文(简体) ), functions, (中文(简体) ), qrScanner (QrScanner相机,下面),和回调
extensions, (中文(简体) ), strings, (中文(简体) ), states, (中文(简体) ), measure, (中文(简体) ), viewportHeight和固体道具一样

字符串属性反映它们的属性. 将财产设定为 null 删除它的属性。 元素附加前设置的属性 (或在升级之前)仍然适用.

只读属性 :

  • handle页:1 SurfaceHandle,或 null 直到第一幅画.
  • issues:活动商店减少问题.
  • status运输状况; statusDetail: 细节( 错误, 或 URL 政策拒绝的原因) src编号 :post) (中文(简体) ).
  • surfaceState页:1 SurfaceState 被画.

方法:

  • apply(message) 发送消息到 surface 属性,其他为主机(receive),否则,到一款初用时创建的商店.
  • setData(pointer, value) 写活动商店。 在固定模式下,它设置了新的 data。 。 。 .
  • reset() 重置活动商店 .
  • run(command), (中文(简体) ), focus(id), (中文(简体) ), announce(text, live?), (中文(简体) ), scrollIntoView(id) 财务报告和审定财务报表 scrollToIndex(id, index, align?) 穿过把手 在第一次油漆之前,他们回来 false 或无所事事。 不带字符串的号码, focus() 财务报告和审定财务报表 scrollIntoView() 保持他们的常态 HTMLElement 意为.

分离元素处理所涂 DOM. 重新装入画作 每一个财产都活下来了 随函附上任何儿童 作者放入元素内.

QrScanner相机

A 类 QrScanner 只画取景器;相机是页面的,通过 plugin.qrScanner (固体制造器的钩子,VAPP-162):

el.plugin = {
  qrScanner: {
    // feed: an empty element filling the viewfinder (append a <video>);
    // formats: default ["qr"]; call onValue per decoded string; return the stop.
    start(feed, formats, onValue) {
      const video = feed.appendChild(document.createElement("video"))
      // … getUserMedia + a decoder calling onValue(text) …
      return () => video.srcObject?.getTracks().forEach((t) => t.stop())
    },
  },
}
el.addEventListener("xui-action", (e) => e.detail.event === "scanned" && pair(e.detail.payload.value))

一个值点火节点 scanned 处理器( e)xui-action,以及 plugin.onAction)一次,按不同价值计算。 无 qrScanner (或何时) start 返回时 false)扫描仪显示 Camera unavailable。 。 。 .

第6轮(EXP-1495)通过"固体"画家:一款有"自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自来自 counter: true 显示 i / n 药和一 thumbnails: [url…] 在页下显示条(两个或两个以上页)。 缩略图按键页面 一个点,所以页面得到 xui-action 与 event: "change" 财务报告和审定财务报表 payload.page。 。 。 .

活动

每个事件都是 CustomEvent 气泡和构成。 当有的时候 一个匹配 plugin 召回,召回 和事件起火。 在一个 承诺涉及,结果被加入: 控制直到 他们都安顿下来了.

事件细节
xui-actionSurfaceActionEvent + 键 waitUntil(promise)按钮待处理(aria-busy="true" 财务报告和审定财务报表 disabled 一次; data-pending="true" 之后 PENDING_DELAY_MS直到承诺达成为止.
xui-inputSurfaceInputEvent + 键 waitUntil在承诺达成时,将确认修订内容.
xui-function-call{ call, respond(value) }。第一个 respond 赢了 没有回应, 插件的 onFunctionCall 使用结果.
xui-open-url{ url },在 URL 策略通过之后。 可取消 : 如果没有取消, 则改为 plugin.openUrl,则 window.open(url, "_blank", "noopener,noreferrer")。 。 。 .
xui-upload{ files, target: { nodeId, name }, waitUntil }
xui-paint-error{ error }
xui-theme-issues{ issues }
xui-unknown{ node }
xui-status{ status, detail? }
xui-ready{ handle }。每个挂载一次起火,在手柄到达之后的微工作表中,所以听众在紧接着添加 appendChild 还得到它.

HTMLElementEventMap 财务报告和审定财务报表 HTMLElementTagNameMap 被扩充,所以 addEventListener("xui-action", …) 财务报告和审定财务报表 document.createElement("exponential-surface") 输入.

主持人 API

何时 src 设置和否 host 属性, 元素构建 new ExponentialHost({ transport }) 这些运输工具之一:

  • WebSocketTransport 何时 src 是一个 ws:编号 :wss: URL 或 网络 transport="ws"。 。 。 .
  • SseTransport 何时 transport="sse"。 。 。 .
  • JsonlStreamTransport 否则.

客户端消息被 POSTD 到 post (默认) src) (中文(简体) ). 元素连接 它在连接时建造的宿主,在分离时关闭并重建它 何时 src, (中文(简体) ), post 或者说 transport 变化。 一个主机表面的画什么也没有 直到主机有一个表面 surface-id。动作、功能、 URL 和 通过主机的媒体路由( r)hostPlugin) (中文(简体) ). xui-open-url 继续放火 在主机打开 URL 之前.

A 类 host 属性属于页面。 元素只连接它 拥有运输工具,从未连接过(status === "closed")),以及该词 从来没有关闭它.

src 财务报告和审定财务报表 post 通过该页面的 URL 策略( R)plugin.urls,每个 在建造运输工具之前(decideTransport一个私人, 回放或链接- 本地主机( l)10.0.0.5, (中文(简体) ), localhost, (中文(简体) ), *.local, (中文(简体) ), 169.254.169.254, (中文(简体) ), ::1,十进制和IPv4-mapped literals)被拒绝,除非 plugin.urls.allowPrivate 选入(该页面的私人来源是,所以) 本地主机流上的 dev 服务器; a hosts 许可名单搁置; schemes: ["https"] 仅指https + wss; javascript:, (中文(简体) ), file:, (中文(简体) ), data: 从不连接。 A 类 ws:编号 :wss: url 被确定为 http(s) 双子 。 拒绝 src 或者说 post 不创建主机并获取任何信息 : status 实值 closed, (中文(简体) ), statusDetail 说为什么(src denied by the URL policy (private)和 xui-status 开火一次。 独立的捆绑带同样的过滤器.

扩展

import { defineElementExtension } from "@exponential_app/eui-element"

el.extensions = [defineElementExtension({
  catalog,                                    // defineExtension(...) or its JSON
  components: {
    Gauge: (ctx) => {
      const div = document.createElement("div")
      ctx.applyRootProps(div)                   // class, data-xui-id, data-xui-c, data-r-*, aria, dir, style
      div.textContent = `${ctx.props.value}`
      div.append(...ctx.children())             // ctx.slot("header") for a slot
      div.onclick = () => ctx.emit("press")
      return div
    },
  },
})]

画家是一个简单的功能: ElementPaintContext 进去,一个DOM 元素出来了。 它在节点、道具、主题、模式或根时再次运行 属性变化,新元素替换了旧元素。 画的 每个再油漆上的孩子和插槽都是相同的节点. registerExtension(ext) 为页面上的每个表面登记一个。 A 类 components 键 核心原生超过它的画家。 一个主机从 src 学习 分类 el.extensions 当它建成时: 在 元素附加( 或之前) src) (中文(简体) ).

无框架主机的图标

el.plugin = { icons: iconsFromSvg((name) => sprite[name]) }   // SVG markup strings

每个标记字符串都成为图标组件,每相隔间创建一次 绳子。 一个没有标记的名字 回到了制造者自己的Lucide 甘草(变种). 包装器装在 <svg> 根何为清晰反应的根 携带其收到的道具:

  • width编号 :height =: width ? size * 24岁.
  • class =标本自班 +画家班.
  • aria-hidden="true",除非通过 aria-*/作用/标题道具.
  • stroke =: color, (中文(简体) ), stroke-width =: strokeWidth。 。 。 .
  • 给定的所有其他字符串或数字属性( E)data-icon(......) (中文(简体) ).

标记是可信的,但 <script>, (中文(简体) ), foreignObject, (中文(简体) ), on* 属性 财务报告和审定财务报表 javascript: 链接已被删除 .

条目

条目什麽
@exponential_app/eui-element没有副作用:, TAG, (中文(简体) ), define(tag?)、帮助者和再出口 createSurface, (中文(简体) ), registerExtension 财务报告和审定财务报表 defineSolidExtension
@exponential_app/eui-element/define电话 define() 导入时( 偶数; 由其它类丢入的标签; 另外一个标签获得自己的子类)
@exponential_app/eui-element/standalone同样的自成一体(Solid和内含的渲染器)装入一个ES模块

版式

路径什麽
src/element.tsExponentialSurfaceElement:信号、属性和属性、源顺序、合并插件、挂起
src/events.ts事件名称、详细类型、全球扩增、 waitUntil 加入时
src/transport.tssrc编号 :post编号 :transport - 一个 ExponentialHost
src/extensions.tsdefineElementExtension, (中文(简体) ), registerExtension, (中文(简体) ), applyRootProps
src/icons.tsiconsFromSvg, (中文(简体) ), svgIcon
src/index.ts, (中文(简体) ), define.ts, (中文(简体) ), standalone.ts条目
src/*.test.tsjsdom套房:元素、事件、传输、扩展、DOM与React的等同

图标

bun run --filter @exponential_app/eui-element typecheck
bun run --filter @exponential_app/eui-element test

版本与发布记录

@exponential_app/eui-element 共发布 29 个版本,首次发布于 2026/10/30;过去 12 个月发布了 29 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.21.0latest2026/11/103 天前
0.20.02026/11/094 天前
0.19.02026/11/086 天前
0.18.02026/11/077 天前
0.17.02026/11/067 天前
0.16.22026/11/068 天前

关于 @exponential_app/eui-element 的常见问题

@exponential_app/eui-element 是什么?

genUI作为一个自定义元素:在主机页面上画出一个没有框架的核心 A2UI 表面,在 Solid 画像和共享的网页层上,其DOM,编译的样式表和运行时的主题与 React 渲染相同

如何安装 @exponential_app/eui-element?

在项目目录运行 npm install @exponential_app/eui-element,或使用 pnpm add / yarn add / bun add。

@exponential_app/eui-element 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@exponential_app/eui-element 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@exponential_app/eui-element 可以商用吗?

@exponential_app/eui-element 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@exponential_app/eui-element 的下载量有多少?

根据 npm 官方下载统计,@exponential_app/eui-element 在 2026/10/14 – 2026/11/12 这 30 天内被下载 5,450 次,日均约 182 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@exponential_app/eui-element 还在维护吗?

最新版本 0.21.0 发布于 2026/11/10(3 天前);至今共发布 29 个版本,其中过去 12 个月发布了 29 个;首次发布于 2026/10/30。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。