news 2026/9/11 21:43:30

Onyx 前端开发规范指南:基于 Opal 设计系统的 web/ 与 desktop/ 编码标准

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Onyx 前端开发规范指南:基于 Opal 设计系统的 web/ 与 desktop/ 编码标准

Onyx 前端开发规范指南:基于 Opal 设计系统的 web/ 与 desktop/ 编码标准

【免费下载链接】danswerOpen Source AI Platform - AI Chat with advanced features that works with every LLM项目地址: https://gitcode.com/GitHub_Trending/da/danswer

导读

本文基于 web/CLAUDE.md 整理而成,它定义了 Onyx 前端(web/目录的 Next.js 应用与desktop/目录的 Tauri 外壳)的统一开发标准。核心思想是:所有 UI 一律来自 Opal 设计系统(@opal/*)与refresh-components,禁止直接使用原生 HTML 控件、裸文本节点与旧组件库。读完本文,你将掌握组件来源的优先级选择、设计 Token 与暗色模式的正确用法、i18n 国际化与类型安全的强制约定,以及组件测试与 E2E 测试的执行方式,可直接套用到 Onyx 前端的日常开发中。

适用范围与文件约定

这些标准同时适用于web/desktop/。仓库约定:每个 Opal 组件与布局旁边都带有一个README.md,说明其架构、props 与用法示例(例如 Opal components 目录 中的组件级 README)。规范原文明确要求:"Read that README instead of guessing props"—— 在使用某个组件前,必须先读它旁边的 README,而不是靠猜 props。

从仓库根目录的 AGENTS.md 可以确认,前端技术栈为Next.js 16、React 19、TypeScript、Tailwind CSSweb/lib/opalweb/lib/shared以 workspace 形式作为本地包(@onyx-ai/opal@onyx-ai/shared,见 web/package.json)。web/AGENTS.md 是前端规范的完整入口,本文所依据的web/CLAUDE.md是其核心内容摘要。

组件来源:优先级顺序与禁用清单

规范的组件引入顺序(优先级从高到低)如下:

  1. web/lib/opal/src/@opal/*:设计系统本体,是 UI 的第一来源。
  2. web/src/refresh-components/:尚未沉淀进 Opal 的生产组件。
  3. web/src/sections/(功能组合件,实体卡片位于sections/cards/)与web/src/layouts/

严禁web/src/components/引入任何内容 —— 它是遗留代码且正在被删除。唯一的例外是src/components/icons/icons.tsx中的createLogoIcon(已在仓库中确认该文件存在)。

@opal/*内部又分两层,对应 core README 中"像 Rust 的corecrate 一样"的比喻:

  • @opal/core:最底层的原语(InteractiveAnimations等),用于构建组件,应用代码不应直接使用。
  • @opal/components@opal/layouts:基于 core 构建的高层组件,是应用代码的消费入口(如ButtonOpenButtonSelectButtonTag,见 components README)。

常见场景的标准组件选择

场景应使用的组件
管理页与设置页SettingsLayouts.{Root,Header,Body}(来自@opal/layouts
图标 + 标题 + 描述ContentContentAction@opal/layouts
空状态与错误页IllustrationContent
按钮Button@opal/components),禁用裸<button>
输入类Opal 或 refresh-components,禁用裸<input><textarea><select>
文本Text@opal/components),用fontcolorprops;禁止裸文本节点
图标仅限@opal/icons,禁止lucide-reactreact-icons
悬停显现Hoverable@opal/core);若必须手写,需加no-hover:opacity-100以兼容触屏设备

关于图标缺失的处理流程:若@opal/icons中缺少所需图标,应通过 Figma MCP 工具从 Figma 引入,并添加到lib/opal/src/icons/目录中(该目录已在仓库中确认存在)。

refresh-components 的覆盖范围很广,仓库中实际包含AreaChartCalendarChipCollapsibleDateRangePickerFrostedDivKeycapPreviewImageSimplePopoverSimpleTabs等组件,以及avatars/buttons/cards/form/inputs/messages/modals/texts/tiles/等子目录,每个组件旁通常伴随.stories.tsx.test.tsx文件(如DateRangePicker.test.tsx)。

有原因的规则:设计 Token、暗色模式与数据获取

禁止dark:Tailwind 修饰符

设计 Token 已同时定义明暗两套主题(仓库web/lib/shared/tokens/下即有semantic-light.jsonsemantic-dark.json),手动覆盖会破坏暗色模式。因此整个代码库禁止使用dark:修饰符,唯一允许使用的是createLogoIcon

禁止内置 Tailwind 颜色

不得使用bg-gray-100text-blue-600这类内置颜色类,必须使用 Token 类,包括:

  • text-0X
  • background-neutral-0X
  • background-tint-0X
  • border-0X
  • action-selection-0X
  • action-danger-0X
  • status-{info,success,warning,error}-0X
  • theme-*

Token 定义位于 web/lib/shared/tokens/,包含primitives.jsonsemantic-light.jsonsemantic-dark.jsonshadow.jsonsize.jsontypography-presets.jsontypography.json等文件,由 style-dictionary(style-dictionary.config.mjs)统一管理,确保明暗两套语义在同一套 Token 体系内联动。

文本 props 接受 Markdown

任何渲染为可见文本的 prop(titledescriptionlabel)应声明为string | RichStr(来自@opal/types),并用Text渲染。调用方通过markdown()@opal/utils)显式启用解析,纯字符串永远不会被当作 Markdown 解析

尺寸 props 默认"md"

当 prop 类型是@opal/typesSizeVariants(或其子集)时,默认值统一为"md"。从 types.ts 源码可见完整尺寸阶梯:"fit" | "full" | "xl" | "lg" | "md" | "sm" | "xs" | "2xs",并衍生出ContainerSizeVariants(排除fullxl)等便捷类型。

优先 padding,避免包 div

使用组件的paddingprop 而非在外面套一层<div>;若库组件没有该 prop,应优先给组件本身增加 prop,而不是添加 wrapper。

数据获取:useSWR

数据获取统一在客户端、需要数据的组件内部使用useSWR,加载期间展示 loader;禁止在页面顶层拉取数据再向下传递。这与 AGENTS.md 中"调用后端一律经由前端(如http://localhost:3000/api/persona而非http://localhost:8080/api/persona)"的约定配合使用。

代码风格约定

  • 绝对导入@/指向src/@opal/指向 Opal;禁止../相对路径
  • 函数声明:组件用function声明,不用箭头函数。
  • 类型组织:props 接口(FooProps)与组件放在同一文件;共享类型放入同目录的types.tsinterfaces.ts是旧命名,碰到时应改名。
  • 类名拼接:使用cn@opal/utils),禁止模板字符串拼接。
  • Hooks 归属:业务 feature hooks 放web/src/lib/<feature>/hooks.ts;不依赖应用知识的 UI hooks 放 Opal;web/src/hooks/是最后的选择。

i18n(next-intl)约定

  • 禁止硬编码面向用户的字符串src/下的裸文本会触发 oxlint 规则i18n/no-raw-jsx-text而失败。客户端用useTranslations("<namespace>"),服务端用await getTranslations(...)
  • 单一事实来源:web/src/i18n/messages/en.json 是英文源文件;新增或修改 key 时,必须为该目录下所有其他语言文件提供最佳翻译。缺失或多余的 key 会导致types:check失败;各语言之间的 ICU 结构必须一致(由 web/src/i18n/tests/catalog.test.ts 校验)。
  • Key 命名规范<namespace>.<section>.<element>.<role>,camelCase,例如settings.appearance.colorMode.title。英文文案的措辞修改不会改变 key。
  • ICU:参数与复数一律用 ICU 语法,禁止拼接翻译片段
  • 日期与数字:使用useFormatteruseLocale,禁止硬编码"en-US"
  • 逻辑属性:新样式使用ms-pe-start-等逻辑属性,而非ml-pr-left-

仓库中web/src/i18n/目录实际包含messages/config.tsconfig.test.tsrequest.tstypes.d.ts__tests__/,i18n 管道与类型生成均已就位。

测试约定

  • 组件测试(Jest + React Testing Library):规范见 web/tests/README.md。
  • E2E 测试(Playwright):硬性规则(Page Object Model、locator 优先级)见 web/tests/e2e/README.md。
  • 运行 E2E 测试:必须使用cd web && bun run playwright <TEST_NAME>不要使用bunxnpx,因为它们可能拉取未锁定版本的 Playwright。根目录 AGENTS.md 还提示,Playwright 全局 setup 会创建管理员账号admin_user@example.com/TestPassword123!(见 web/tests/e2e/constants.ts),应用运行于http://localhost:3000

相关 npm scripts 见 web/package.json:lint(oxlint)、types:checknext typegen+tsc --noEmit)、format(oxfmt)、test(jest)、playwright(playwright test)、storybook(Storybook dev server)等。

总结

Onyx 前端规范的核心可以浓缩为三句话:

  1. 组件来源有纪律:优先 Opal → refresh-components → sections/layouts,绝不触碰正在删除的旧components/
  2. 样式必须走 Token:不用dark:、不用内置 Tailwind 颜色,明暗主题由 Token 统一驱动。
  3. 国际化与类型检查是硬门槛:所有用户可见字符串走 next-intl 与en.json单一事实源,缺 key 或 ICU 结构不一致都会让 CI 失败。

对于任何 Opal 组件,先读它旁边的 README 再使用 —— 这是避免踩坑、保持前端代码库长期一致性的最佳实践。

【免费下载链接】danswerOpen Source AI Platform - AI Chat with advanced features that works with every LLM项目地址: https://gitcode.com/GitHub_Trending/da/danswer

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 21:40:32

【JAVA毕设源码分享】基于 Java 框架的酒店客房管理系统的设计与实现 基于 Java 的酒店预订管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/9/11 21:40:21

CAN自定义协议设计从入门到实战:ID规划、数据场布局与错误恢复

做CAN通信的工程师&#xff0c;几乎都会遇到这么一天&#xff1a;手头设备用的MCU带CAN控制器&#xff0c;总线也搭好了&#xff0c;收发器波形拿示波器看完全正常&#xff0c;但两边设备就是"各说各话"——A发的数据B收不到&#xff0c;或者收到了也解析得乱七八糟。…

作者头像 李华
网站建设 2026/9/11 21:39:10

2026年广州做小程序商城的公司有哪些:本地交付先问清责任

摘要&#xff1a;广州做小程序商城的公司有哪些背后不是单纯比较工具名称&#xff0c;而是判断本地资料整理、商品上架、同城配送、门店自提、支付审核、运营支持能否稳定落到实际岗位。CNNIC第54次报告显示&#xff0c;截至2024年6月&#xff0c;在线支付用户规模为9.69亿人&a…

作者头像 李华