☰
Open CoDesign 空状态设计规范:用 empty-states 技能让 AI 生成告别 “No data“ 占位符
2026/9/27 23:35:21 网站建设 项目流程
  • 人工智能
  • AI 应用
  • 桌面应用

【免费下载链接】open-codesign

Open-source Claude Design alternative. One-click import your Claude Code / Codex API key. Prompt → prototype / slides / PDF. Multi-model (Claude, GPT, Gemini, Kimi, GLM, Ollama). BYOK, local-first, MIT.

项目地址:https://gitcode.com/gh_mirrors/op/open-codesign
点击查看免费下载

本指南以 Open CoDesign 内置方法技能(method skill)empty-states.md 为绝对核心,讲解「首次使用 / 无结果 / 错误」三种空状态的分类规则、文案与代码模式,并结合仓库源码(技能加载器、SkillFrontmatter 校验、内置脚手架)揭示其在实际 AI 生成流程中的落地机制。读完本文,你将掌握一套可直接复用的空状态设计规范,以及 Open CoDesign 中技能文件的编写、加载与调用原理,能自己编写或改造同类的设计技能。

Open CoDesign 是一款本地优先(local-first)、支持多模型(Claude、GPT、Gemini、Kimi、GLM、Ollama)的开源设计生成工具,核心工作流是"Prompt → 原型 / 幻灯片 / PDF"。为了让 AI 生成的设计稿在细节上达到专业水准,项目内置了一批"方法技能"(method skill)——以 Markdown 编写的规则说明书,由 agent 在写代码前加载。empty-states就是其中专门约束"空状态"(empty state)设计的技能。

一、empty-states 技能是什么:定位与触发条件

empty-states是 Open CoDesign 内置技能之一,其任务定位记录在技能文件的 YAML frontmatter 中(见 empty-states.md):

  • name: empty-states:技能 ID,同时是skill(name)工具调用的入参;
  • description:明确说明它为三类关键空状态设计界面——首次使用(还没有任何记录)、无结果(筛选/搜索无匹配)、错误(网络/服务失败),并用于替换一切笼统的 "No data" 占位符;
  • trigger.providers: ['*']:对所有模型提供方(Claude、GPT、Gemini 等)通用,不区分具体厂商;
  • trigger.scope: system:触发作用域为系统级,即任何生成任务都可能在合适时机调用;
  • user_invocable: true:用户也可以主动要求加载该技能。

什么时候应该触发它

技能正文第一段定义了触发时机——任何可能渲染出零条数据的 UI 表面:

  • 列表、表格、看板(kanban)、收件箱视图;
  • 搜索与筛选结果面板;
  • 依赖数据的仪表盘与统计组件;
  • 通知、动态流、评论线程;
  • 任何可能发生网络或查询失败的界面。

也就是说,空状态不是"最后补一个占位图"的收尾工作,而是一类必须被提前设计的状态,任何数据驱动的界面都要覆盖。

技能文件在仓库中的组织方式

empty-states技能文件位于应用模板树中:

apps/desktop/resources/templates/skills/empty-states.md

根据 templates/README.md 的说明,skills/*.md是可编辑的 Markdown 方法技能,通过skill(name)加载,它们描述"如何工作"(布局、可访问性、图表、表单、响应式行为、工艺检查等)。整个resources/templates目录会在首次启动时被复制到用户的应用数据目录中,形成一棵用户可编辑的模板树,用户可以在<userData>/templates/skills/下看到并修改这些技能文件。

仓库中的技能全家桶(见 skills 目录)还包括form-layout、loading-skeleton、surface-elevation、cjk-typography、accessibility-states、responsive-layout、craft-polish等同级技能,empty-states是其中的 P0 级设计技能之一(见 apps/desktop/CHANGELOG.md 中 "5 new P0 design skills" 的发布记录)。

二、三条铁律:恰好三种空状态,绝不合并、绝不裸奔

技能的 Rules 部分确立了整个规范的核心——世界上恰好有三种空状态,每种有各自的文案模式,不能折叠成一个通用组件:

  1. 首次使用(First-use)——用户还没有创建第一条记录。
    • 一句话解释这个功能是做什么的;
    • 一个主 CTA——创建第一条记录的那个动作;
    • 一张与产物相关的示意插图(发票、图表、聊天气泡),不要用通用的剪贴板或放大镜图标。
  2. 无结果(No-results)——用户筛选或搜索后没有任何匹配。
    • 复述用户的查询:No tickets matched "urgnet",必须原样引用实际查询词;
    • 从以下四种补救动作中提供两个:清除筛选(clear-filter)、扩大搜索范围(broaden-search)、拼写建议(suggest-spelling)、最近结果(recent-results);
    • 绝不能复用首次使用的插图——否则用户会以为自己的数据丢失了。
  3. 错误(Error)——请求失败。
    • 用通俗语言说明原因:Network unreachable、Server returned 500;
    • 主 CTA:重试(Retry);
    • 次级链接:反馈问题(或打开调试详情面板);
    • 绝不能让整屏只显示一条堆栈跟踪。

另外还有两条补充规则:

  1. 统计占位:统计卡片没有数据时渲染一个长破折号—,而不是0。0是一个真实值(今天的销售额是零),—才表示"没有数据"。代码模式是{value ?? '—'}。
  2. 绝不允许上线一个只写着 "No data" 或 "Nothing here yet" 的界面——每一个空状态都必须回答"我接下来该做什么?"。

Do / Don't 速查

Do(应当)

  • 在无结果消息中原样引用用户的查询词;
  • 每个分类使用不同的插图,让用户能直观区分"第一次来"和"没有匹配";
  • 错误状态提供 Retry 按钮,并在重试时使用乐观 UI(optimistic UI);
  • 空状态文案与其他字符串一起进入本地化(i18n)目录。

Don't(禁止)

  • 不要把首次使用插图复用到无结果状态;
  • 不要在从未收到过数据的统计卡片上显示0;
  • 不要单独展示技术错误码(如Error 500),必须搭配人类可读的原因;
  • 不要让空状态被一个永远不结束的 spinner 遮住。

三、Code patterns:四段可直接落地的 TSX 模板

技能文件提供了四段可复制的 React/TSX 代码模式,全部基于 Tailwind 类名实现。

3.1 首次使用(First-use)

<div className="grid place-items-center gap-4 py-16 text-center"> <InvoiceIllustration className="w-32 h-32 opacity-80" /> <p className="max-w-sm text-sm text-muted-foreground"> Invoices you create will appear here. Send your first one to get paid. </p> <button className="h-11 px-4 rounded-md bg-blue-600 text-white"> Create invoice </button> </div>

关键点:一句功能说明 + 一个主 CTA + 与产物强相关的插图(发票示例)。插图用opacity-80弱化视觉重量,避免喧宾夺主。

3.2 无结果(No-results)

<div className="grid place-items-center gap-3 py-12 text-center"> <SearchIllustration className="w-24 h-24 opacity-70" /> <p className="text-sm">No tickets matched <strong>"{query}"</strong>.</p> <div className="flex gap-2"> <button onClick={clearFilters} className="h-9 px-3 text-sm rounded border">Clear filters</button> <button onClick={broaden} className="h-9 px-3 text-sm rounded border">Search all projects</button> </div> </div>

关键点:查询词用<strong>原样强调;提供两个补救动作(清除筛选 + 扩大搜索范围);插图换成了放大镜类(注意:它和首次使用的产物插图不同——首次使用禁止用放大镜,这里是"搜索"语义的合法场景,且不能复用首次使用插图)。

3.3 错误(Error)

<div className="grid place-items-center gap-3 py-12 text-center"> <AlertIllustration className="w-24 h-24 text-red-500" /> <p className="text-sm">Network unreachable. Check your connection and try again.</p> <button onClick={retry} className="h-10 px-4 rounded bg-blue-600 text-white">Retry</button> <a href="/support" className="text-xs underline text-muted-foreground">Report this problem</a> </div>

关键点:人类可读的原因说明(Network unreachable)+ Retry 主按钮 + "Report this problem" 次级链接。错误插图用text-red-500传达警示语义。

3.4 统计占位(Stats placeholder)

<dd className="text-2xl font-semibold">{value ?? '—'}</dd>

关键点:用空值合并运算符??——只有value为null/undefined时才显示—,真实的0值照常渲染。

四、从规范到实现:技能在 Open CoDesign 中如何被加载与调用

empty-states不只是一份给人看的规范,它是会被 agent 实际加载执行的"可运行规则"。理解其背后的加载机制,能让你真正掌握这类技能文件的编写方法。

4.1 Frontmatter 的 Schema 定义

技能 frontmatter 由 Zod schema SkillFrontmatterV1 严格校验,字段包括:

字段类型/默认值说明
schemaVersion字面量1版本标识
name字符串(必填)技能名,对应文件名 slug
description字符串(必填,≤1536 字符)给 agent 的能力描述
aliases字符串数组,默认[]别名,可用别名调用
dependencies字符串数组,默认[]依赖的其他技能
validationHints字符串数组,默认[]校验提示
trigger{providers: ['*'], scope: 'system' \| 'prefix'}触发条件:适用模型、作用域
disable_model_invocation布尔,默认false是否禁止模型主动调用
user_invocable布尔,默认true是否允许用户主动调用
allowed_tools字符串数组,可选技能可用的工具白名单

empty-states.md的 frontmatter 完全符合该 schema:providers: ['*']表示所有模型提供方通用,scope: system为系统级,disable_model_invocation: false+user_invocable: true意味着模型可以自动触发、用户也可以手动点名。

4.2 加载器与优先级

技能加载器位于 packages/core/src/skills/loader.ts,包含一套手写的轻量 YAML frontmatter 解析器(支持折叠标量>、字面量标量|、行内序列[a, b]、块序列- item等),然后通过SkillFrontmatterV1.safeParse校验,失败会抛出ERROR_CODES.SKILL_LOAD_FAILED。

加载分为三个层级,优先级为project > user > builtin(见loadAllSkills):

  • builtinDir:应用内置技能目录(即resources/templates/skills);
  • userDir:~/.config/open-codesign/skills之类的用户目录;
  • projectDir:<project>/.codesign/skills项目目录。

当多个层级存在同名技能时,高优先级覆盖低优先级——用户或项目可以改写内置技能的行为,这是技能体系可定制性的关键。

4.3 skill 工具:agent 如何"读规则"

packages/core/src/tools/skill.ts 中的makeSkillTool把技能暴露为 agent 的skill工具:

  • 入参name即技能 ID(如empty-states),描述中明确列举了empty-states等内置技能名;
  • invokeSkill先列出技能清单(listSkillManifest),按名字或别名匹配,再从模板树中读取 Markdown 正文返回给模型;
  • 每个会话对每个技能只加载一次,重复调用会返回简短的 "already loaded" 提示,避免重复注入整篇文本浪费上下文(dedup机制);
  • 读取路径经过resolveSafeManifestPath安全检查:拒绝符号链接穿越模板根目录("registered path escapes template root" / "registered path traverses symbolic link"),防止路径逃逸。

也就是说,当生成任务涉及列表、仪表盘、搜索等界面时,agent 会调用skill("empty-states")把这份规范注入上下文,再据此写代码。测试用例 packages/core/src/tools/skill.test.ts 和 packages/core/src/skills/loader.test.ts 均覆盖了empty-states的加载与依赖解析。

4.4 配套脚手架:empty-states.jsx

除方法技能外,仓库还提供了配套的可复制源码片段 empty-states.jsx,在 scaffolds/manifest.json 中登记为ui-primitive类别。它内置了五种空状态变体:搜索无结果(🔍)、收件箱清零(✉️)、图表无数据(📊)、看板为空(🗂)、出错重试(⚠️),每种都包含图标、标题、说明与 CTA 按钮,可作为scaffold(kind, destPath)复制的起点素材。注意区分:skills/*.md是"方法规则"(如何做),scaffolds/ui-primitives/*.jsx是"起点素材"(直接复制的代码),二者通过 manifest 分开管理。

五、把规范落进你自己的界面:一份 5 步检查清单

把empty-states技能提炼成可执行的设计流程:

  1. 盘点所有零数据场景:列表、搜索、仪表盘、通知、评论线程,逐个标注属于"首次使用 / 无结果 / 错误"中的哪一类——绝不合并,也绝不遗漏错误态。
  2. 按分类写文案:首次使用写"功能是什么 + 下一步动作";无结果原样引用查询词并给两个补救动作;错误用通俗语言说明原因并给 Retry 与反馈入口。
  3. 分配插图语义:首次使用用产物相关图(发票、图表、气泡),无结果用搜索语义图,两者必须不同;错误用警示语义图。统计卡片无数据一律—,不用0。
  4. 给每个空状态一个"下一步":主 CTA 指向能改变现状的动作(创建、清筛、重试、换关键词)。
  5. 本地化与重试体验:文案进 i18n 字符串目录;错误重试配合乐观 UI,避免用户卡在永不停歇的 spinner 前。

对照 Do / Don't 清单 逐项自检:是否复用了插图?是否显示了裸错误码?是否出现了裸 "No data"?

六、结语:空状态是一等公民,而不是事后补丁

empty-states技能的价值在于把"空状态设计"从可有可无的收尾工作提升为有明确分类、有固定文案模式、有代码模板、有落地机制的一等设计规则。在 Open CoDesign 中,它通过 frontmatter(SkillFrontmatterV1)+ Markdown 正文 + 加载器(loader.ts)+skill工具(skill.ts)这条完整链路进入每个生成会话,让任何模型在产出列表、仪表盘、搜索界面时都能遵守同一套高标准。

如果你正在 Open CoDesign 中编写自己的技能,或希望在自己的产品中推行空状态规范,可以直接把 empty-states.md 作为模板:写好 frontmatter(名称、描述、触发条件)、写清 Rules 与 Do/Don't、附上可复制的代码模式,然后放入skills目录即可被加载。记住它的核心判断:三种空状态,缺一不可;每个空状态都必须回答"下一步做什么"。

  • 人工智能
  • AI 应用
  • 桌面应用

【免费下载链接】open-codesign

Open-source Claude Design alternative. One-click import your Claude Code / Codex API key. Prompt → prototype / slides / PDF. Multi-model (Claude, GPT, Gemini, Kimi, GLM, Ollama). BYOK, local-first, MIT.

项目地址:https://gitcode.com/gh_mirrors/op/open-codesign
点击查看免费下载

相关推荐

上一篇:深度解析:AList 115 Open存储驱动Token格式错误的终极修复方案
下一篇:tmux-resurrect 程序恢复配置:吃透 ~、->、* 三大符号,10 分钟搞定自定义恢复列表

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

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

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

立即咨询