GPUIX元素完全参考:11个原生元素一次看懂(附代码示例)
【免费下载链接】gpuixNode.js & React bindings for Zed GPUI.项目地址: https://gitcode.com/gh_mirrors/gp/gpuix
GPUIX是 Zed 编辑器 GPU 渲染框架 GPUI 的 React 绑定库,让你用 React 和 TypeScript 构建直接渲染到 GPU 的原生桌面应用——没有 Electron,没有 Web 视图。本文带你一次看懂 GPUIX 的全部11 个原生元素:从最基础的<div>和<text>,到语法高亮代码块<code>、diff 查看器<diff>、Markdown 渲染<markdown>,再到虚拟列表<virtual-list>和浮层<anchored>,并附可直接上手的代码示例。
上面这个 Waku 风格的聊天应用完全由 GPUIX 驱动:侧边栏、虚拟滚动消息列表、输入框、<markdown>渲染器,全部是原生元素。
GPUIX 原生元素速查表
GPUIX 共提供 11 个已实现的宿主元素(另有一个规划中的<canvas>),完整清单见 README.md 的 "Supported Elements" 一节:
| 元素 | 一句话说明 | 典型用途 |
|---|---|---|
<div> | 弹性布局容器 | 卡片、按钮、布局骨架 |
<text> | 可选中、可复制的文本 | 标签、段落 |
<code> | Tree-sitter 语法高亮代码块 | 代码展示 |
<diff> | 统一 diff 查看器,支持词级高亮 | 代码评审视图 |
<markdown> | GitHub 风格 Markdown | 文档、聊天消息 |
<input> | 原生单行文本编辑器 | 搜索框 |
<textarea> | 原生多行、自动增高编辑器 | 聊天输入框 |
<virtual-list> | 只构建可视区域的长列表 | 消息流、大数据列表 |
<img> | 位图/SVG 彩色图片 | 头像、插图 |
<svg> | 可着色的单色 SVG 图标 | 工具栏图标 |
<anchored> | 相对锚点定位的浮层 | 菜单、Tooltip |
每个元素在 Rust 侧都有独立的实现文件,核心自定义元素集中在 packages/native/src/custom_elements/ 目录,元素类型定义可查 packages/react/src/types/host.ts。
布局与文本:<div>与<text>
这两个是最基础的元素,撑起整个应用的骨架。<div>支持完整的 flexbox 布局,<text>支持所有文字样式,且所有文本天生可选中复制。
<div style={{ display: 'flex', gap: 8, padding: 16, backgroundColor: '#313244' }}> <text style={{ color: '#ffffff', fontSize: 18 }}>Hello GPUIX!</text> </div>两个新手必须知道的要点:
- 文本颜色默认是黑色:与 CSS 不同,GPUI 不会从父元素继承
color,务必显式设置。 - hover / active 是原生样式对象:写在
style里由 Rust 直接应用,零 JavaScript 往返。
<div style={{ backgroundColor: '#313244', borderRadius: 8, padding: 12, hover: { backgroundColor: '#45475a' }, active: { backgroundColor: '#585b70' }, }}> 按钮 </div>文本三件套:<markdown>、<code>、<diff>
这是 GPUIX 的杀手级元素 🎯 三个文本组件在 Rust 中用 Tree-sitter 计算语法高亮,颜色来自主题而非布局,高亮延迟到达也不会重排,且全部支持跨元素拖选复制。三者同框效果:
Markdown 渲染:<markdown>
支持 GitHub 风格 Markdown:标题、列表、表格、引用、围栏代码、删除线、任务列表,裸 URL 自动链接。
<markdown source={readme} onLinkClick={(e) => open(e.value)} />代码高亮:<code>
每行固定行高,块高度在语法高亮运行前就已确定,支持行号和语言头部条。内置 Rust、TypeScript、JavaScript、Python、Go、JSON 等 15 种语言。
<code code={source} language="typescript" showLineNumbers />差异查看:<diff>
接收标准git diff补丁,默认随父容器流动(父列表可以成为唯一滚动容器);开启wordDiff只高亮真正变化的词。maxLines可截断长补丁并触发onShowMore。
<diff patch={unifiedPatch} wordDiff maxLines={open ? undefined : 24} onShowMore={() => setOpen(true)} onToggleFile={(e) => toggle(e.value)} />三者都接受可选的theme属性,逐层覆盖内置暗色主题;行高、gutter 宽度、标题字号等布局数字放在theme.metrics里,调样式只需一次 React 重渲染,无需重编译原生模块。
原生文本输入:<input>与<textarea>
两者都走 GPUI 的平台级输入处理器,自带原生光标、文字选择、IME 组合输入、剪贴板、撤销重做和字形安全删除。
<textarea value={draft} placeholder="Ask anything" minRows={1} maxRows={8} onChange={(event) => setDraft(event.value ?? '')} onSubmit={send} />Enter触发onSubmit;<textarea>中Shift+Enter换行- 编辑器先在原生侧更新,再把完整值报告给 React
- 光标编辑时常亮、空闲后每 500ms 闪烁,失焦停止重绘
- 光标颜色可通过
<input theme={{ caret: '#22c55e' }} />覆盖
<input>需要autoFocus或点击才能获得焦点,否则收不到按键事件。
长列表性能利器:<virtual-list>
普通滚动容器会构建每一个子元素;<virtual-list>则只构建、布局、绘制视口附近的行,是聊天消息流这类长列表的正确选择。
<virtual-list alignment="bottom" followTail estimatedItemHeight={180} style={{ flexGrow: 1, minHeight: 0 }} > {messages.map((message) => ( <Message key={message.id} message={message} /> ))} </virtual-list>常用属性速览:
| 属性 | 默认 | 作用 |
|---|---|---|
alignment | "top" | 聊天式底部定位用"bottom" |
followTail | false | 贴底时自动跟随新增行 |
overdraw | 512 | 视口外多构建的像素 |
estimatedItemHeight | 无 | 未测量行的初始高度估算 |
⚠️ 注意:GPUIX 不支持嵌套滚动。一个父级可以滚动,内部不能再放<virtual-list>或overflow: "scroll"。
图片与图标:<img>与<svg>
两者都接收文件系统路径而非 URL。
<img>:加载 PNG、JPEG、WebP、GIF、SVG(全彩色),objectFit与 CSS 一致(contain默认 /cover/fill/scaleDown/none),加载失败显示占位图而不是崩溃。<svg>:走 GPUI 的单色图标渲染器,用style.color着色,专为工具栏图标设计。style.color是必须的,不设则不绘制。
<svg src={iconPath} style={{ width: 16, height: 16, color: '#b4b4b4' }} />chat 示例的全部侧边栏和输入框图标就是这么实现的,图标素材见 examples/assets/icons/。
浮层定位:<anchored>
<anchored>让元素相对一个锚点定位,配合deferred可渲染在稍后的绘制通道上——菜单、Tooltip、Select 下拉必须用它,才能盖住<virtual-list>和页面其余部分。
<anchored side="top" align="end" gap={6} deferred> <div style={{ backgroundColor: '#232323', padding: 8 }}> <text style={{ color: '#ffffff' }}>菜单项</text> </div> </anchored>常用属性:side(top/right/bottom/left)、align(start/center/end)、anchor(八向锚点)、offset、fit: "snap"自动收进窗口内。
跨元素文本选择:零配置
GPUIX 绘制的每一处文本——包括<code>、<diff>、<markdown>内部——都可以选中和复制。从标题拖到围栏代码块,中间内容全部选中;Cmd+C按文档顺序合并复制。
想退出选择(工具栏、按钮、行号槽)只需userSelect: "none",它像 CSS 一样向下继承。
上手示例与运行方式
项目内置四个示例,全部使用硬编码数据,位于 examples/ 目录:
| 示例 | 运行命令 | 展示内容 |
|---|---|---|
| chat | cd examples && bun --hot chat.tsx | 完整聊天应用:虚拟列表 + markdown + 动画侧边栏 |
| native-text | cd examples && bun --hot native-text.tsx | <markdown>/<code>/<diff>三件套切换 |
| counter | cd examples && bun --hot counter.tsx | 最小应用:状态、事件、hover |
| diff | cd examples && bun --hot diff.tsx | 用<div>+<text>手搓的 diff 对照 |
最小入口只需三步:
import { render } from '@gpuix/react' function App() { return <div style={{ padding: 16 }}><text style={{ color: '#fff' }}>hello</text></div> } render(<App />, { title: 'My App', width: 800, height: 600 })依赖 Rust 工具链和 Node.js 18+,macOS 需 Xcode Metal Toolchain。完整构建步骤见 README.md 的 Building 章节,架构细节可参考 AGENTS.md。
小结
11 个 GPUIX 原生元素覆盖了桌面应用的全部核心场景:
- 布局:
<div>flexbox + 原生 hover/active - 文本:
<text>/<markdown>/<code>/<diff>,全可选中 - 输入:
<input>/<textarea>原生编辑器 - 性能:
<virtual-list>只渲染可视行 - 视觉:
<img>/<svg>图片图标 - 浮层:
<anchored>后置绘制通道
配合bun --hot热重载和 GPU 测试渲染器截图,一套 React 心智模型即可构建流畅的原生桌面应用 🚀
【免费下载链接】gpuixNode.js & React bindings for Zed GPUI.项目地址: https://gitcode.com/gh_mirrors/gp/gpuix
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考