kitseed.

Subtic 提炼审查

记录什么值得提炼、如何分类,以及哪些职责应留在应用。

本次审查于 2026 年 10 月 23 日 对 Subtic Web 进行只读检查,基线提交为 6512eb109445b879fe8f82fb9d08885bd1172570。审查范围是 Web 前端,当前交付在 Kitseed 中建设组件体系,Subtic 没有迁移或替换。

2026-10-31 追加:Image Lightbox

0.3.0 将内容图片预览与反馈附件的全屏视图提取为 ImageLightbox,并同步接入 Subtic。通用层只消费 id/src/alt,提供缩放、平移、捏合、动态集合、焦点恢复与失败重试接口。ClientContentMedia、desktopMediaUrl、userViewResourceUrl、翻译、快捷键偏好和反馈已读逻辑保留在产品适配层。

此前“源项目只读”和 24 个家族为首期历史范围;随着 ImageLightbox 与跨项目统一的 Sidebar 应用侧边栏入库,当前为 26 个组件家族。附件缩略图网格仍为产品实现,不随预览视图入库。历史版本 Registry 保留,新增功能使用 v0.3.0 本地候选。

审查覆盖

区域扫描范围判断重点
components/ui19 个文件:16 TSX、2 TS、1 CSS样式基线、交互语义、基础依赖
components 顶层101 个 TSX可复用结构与业务耦合
components/route-states6 个文件状态展示与路由恢复职责
features165 个 TSX是否存在可提取的通用呈现层
路由118 个文件布局使用方式与应用边界

这些数字说明扫描覆盖,不代表所有文件都应成为组件。一个源文件可以拆成多个家族;同一家族也可能依赖多个源文件。

提炼的三个判断

直接复用视觉与语义。 Badge、Panel、Kbd、Segmented、Skeleton、Spinner、Tooltip 主要依赖 React、Base UI、tokens 和少量本地工具,适合作为设计基础。保留原有内容密度,补齐清晰文档。

保留成熟交互,移除应用环境。 Button、Menu、Field、Form、Copy Field、Confirm Dialog、Toast、Choice Picker、Time Picker 已有实际产品交互。提炼时移除应用翻译单例、权限、API 错误映射、桌面桥接与全局平台状态,改由公开 props、通用配置、文案和回调传入。

保留结构,重新定义输入。 Settings、Page、Navigation、States、Identity 与 Collection 有跨产品价值,但不应携带 Subtic 路由、模型与操作。提炼后的组件接收展示数据与插槽,由调用方提供导航、计数、菜单和行为。

组件归类

分类家族决策依据
操作与输入Button、Copy Field、Kbd、Field、Form、Choice Picker、Time Picker、Segmented、Selection完成动作、编辑与选择;以标签、值、验证和键盘为共同约定
浮层与反馈Menu、Tooltip、Confirm Dialog、Toast、States传递补充信息、风险和操作结果;以焦点与状态恢复为共同约定
布局与导航Panel、Settings、Page、Navigation、Sidebar建立空间、信息层级和位置感;内容与路由由调用方拥有
内容与展示Badge、Skeleton、Spinner、Identity、Data Display、Collection呈现身份、数据与集合;与具体领域模型分离

Selection 将搜索字段、开关、筛选条件和选项内容组织为通用呈现;原生复选与单选保留在 Field 的 ChoiceRow 中。Data Display 将定义项等内容展示能力独立记录。这些分类按用途组织,不要求与源文件一一对应。

需要留下的 Subtic 职责

领域典型来源留在应用的原因
订阅与投递delivery-fields、内容保存面板、集成授权依赖提供商、权限和后端契约
内容读取与编辑collection-reader、具体 collection card 内容依赖 Entry 类型、阅读状态与领域操作
管理与计费features/admin*、权益和销售面板权限、资金与运营规则属于应用
运行时恢复路由错误页、集合滚动恢复、未保存保护需要路由、持久化和平台桥接
品牌与资源Subtic 专属头像、Logo、插画不应成为其他产品默认身份

这类功能可以使用 Kitseed 构造界面,但不会以完整业务模块进入 Registry。

提炼后的依赖边界

从源项目移除Kitseed 中的承接方式
isUserViewWindow、写权限与平台判断应用决定 disabled、只读状态与原因
translate、useUiLocale应用传入标签、提示与错误文案
presentError、API 响应通用错误节点、字段错误 map 与回调
桌面 dirty state 与桥接应用管理保存周期和未保存离开保护
固定路由、查询和业务模型链接、active 状态、展示数据与操作插槽

逐项依赖与交付映射

重新核对源项目 16 个 TSX 的实际 imports 后,可以按 7 个主要结构可迁移家族、9 个需要去除产品上下文的家族 分组。标准是是否导入 Subtic 的翻译单例、权限、API 错误处理、桌面或工作区状态;不以视觉是否简单判断。Choice Picker、Copy Field、Time Picker 即使主要是通用交互,也仍依赖应用 i18n,不能标成零去耦复制。

下表的源文件均位于 Subtic 的 apps/web/components/ui/;目标为 Kitseed 仓库路径。所有阶段均指 Kitseed 首期交付,不表示已迁移 Subtic。通用调整包括改为相对 imports、只提取 cn 所需的 clsx/tailwind-merge 工具、接入独立 tokens;Base UI imports 从源包路径 @base-ui-components/react 调整为本项目安装的 @base-ui/react。

主要结构可迁移:7 个家族

家族与源定位原依赖去耦原因与处理Kitseed 路径交付阶段
Badge · badge.tsx:1–3React 类型、CVA、@/lib/utils 的 cn没有产品上下文;保留 tone/variant,调用者负责业务状态到 tone 的映射registry/kitseed/ui/badge.tsx首期·结构迁移,已实现
Kbd · kbd.tsx:1–2React、cn;组件内读取浏览器 userAgent保留键帽和通用修饰键显示;userAgent 只决定 ⌘/Ctrl,不依赖桌面桥或产品快捷键注册registry/kitseed/ui/kbd.tsx首期·结构迁移,已实现
Panel · panel.tsx:1–2React 类型、cn只有表面和排布;迁移 tokens,不引入应用数据或页面状态registry/kitseed/ui/panel.tsx首期·结构迁移,已实现
Segmented · segmented.tsx:1React useId、原生 radio结构已受控;保留 radio 与键盘语义,补通用 disabled/density,不与链接导航合并registry/kitseed/ui/segmented.tsx首期·结构迁移,已实现
Skeleton · skeleton.tsx:1–2React 类型、cn仅占位视觉;具体内容的行数、比例和加载策略交给模式层registry/kitseed/ui/skeleton.tsx首期·结构迁移,已实现
Spinner · spinner.tsx:1cn、内联 SVG没有产品依赖;保留装饰性 SVG,并补 reduced-motion 处理registry/kitseed/ui/spinner.tsx首期·结构迁移,已实现
Tooltip · tooltip.tsx:1–16Base UI Tooltip、React、同层 Kbd、tooltip.module.css本体没有 i18n/API/权限 imports;保留焦点、截断检测和样式,将产品命令解析留在调用侧registry/kitseed/ui/tooltip.tsx、registry/kitseed/ui/tooltip.module.css首期·结构迁移,已实现

需要去除产品上下文:9 个家族

家族与源定位原依赖去耦原因与处理Kitseed 路径交付阶段
Button · button.tsx:1–8Base UI useRender、CVA、React、cn、Tooltip;useMobileWorkspace、isUserViewWindow、translate不能让其他产品读取 Subtic 窗口或权限;去 requiresWrite 策略,改为调用者传 disabled/disabledReason,通用 provider 提供 densityregistry/kitseed/ui/button.tsx首期·去耦实现,已实现
Choice Picker · choice-picker.tsx:1–19Base UI Combobox/Select、Phosphor、React、cn、FieldContext/Field/picker-styles;translate/useUiLocale/uiLocale选项、过滤与浮层可复用,但文案刷新绑应用语言单例;改用 props/messages,保留字段关联和焦点,options 由调用者提供registry/kitseed/ui/choice-picker.tsx、registry/kitseed/ui/picker-styles.ts首期·去耦实现,已实现
Copy Field · copy-field.tsx:1–6Phosphor、React、cn、Button、Toast;translate/useUiLocale保留复制与显示/隐藏反馈;去应用翻译,改通用 messages;复制拒绝时保留可选文本和明确失败提示registry/kitseed/ui/copy-field.tsx首期·去耦实现,已实现
Dialog / Confirm Dialog · dialog.tsx:1–8Base UI AlertDialog、React、Button/Input;translate/useUiLocale、presentError、产品 ErrorFeedback原错误组件会解释 API 与权益;改用 renderError/通用消息,保留 onPrepare/onConfirm、pending 和焦点,应用自行解释业务异常registry/kitseed/ui/dialog.tsx首期·去耦实现,已实现
Field · field.tsx:1–12React、cn、FieldContext/FormErrorContext;useMobileWorkspace、translate/useUiLocale,支持文件 validationMessage 也调用 translate去工作区和语言单例;通用 messages 生成原生约束提示,provider 提供 density,保留 label/hint/error 关联,不接服务端协议registry/kitseed/ui/field.tsx、registry/kitseed/ui/form-context.ts首期·去耦实现,已实现
Form · form.tsx:1–20React/ReactDOM、cn、form-context;i18n、presentError、ErrorFeedback、isUserViewWindow、canMutate/subscribePlatform、DesktopFormChanges/desktop dirty state去账户写权限、平台订阅和原生未保存状态;公开 fieldErrors/error/pending 与回调,保留原生校验/摘要/错误聚焦;离开保护和保存周期留应用registry/kitseed/ui/form.tsx、registry/kitseed/ui/form-context.ts首期·去耦实现,已实现
Menu · menu.tsx:1–12Base UI Menu、React、Tooltip、cn、picker-styles;isUserViewWindow、translate去产品只读权限判断;由调用者传 disabled/disabledReason/tooltip,保留菜单层级、选择项和键盘操作registry/kitseed/ui/menu.tsx首期·去耦实现,已实现
Time Picker · time-picker.tsx:1–6React、Input、SearchPicker、cn;translate/useUiLocale/uiLocale、@/lib/time-picker 的 normalizeTimeInput/quickTimes去应用语言单例;将通用时间解析和快捷时段迁成本地 helper,提示来自 messages,不携带 DigestSchedule、时区投递或计划 APIregistry/kitseed/ui/time-picker.tsx、registry/kitseed/lib/time-utils.ts首期·去耦实现,已实现
Toast · toast.tsx:1–5Base UI Toast、Phosphor、React;translate/useUiLocale、API 模块的 safeErrorText原通知会净化应用错误;去 API/翻译依赖,调用者传已整理内容,组件保留队列、去重、持续时间与关闭语义registry/kitseed/ui/toast.tsx首期·去耦实现,已实现

lib/provider.tsx 是独立、可选的 Kitseed 配置,提供 density 与默认中文 messages;不是 Subtic i18n 或权限 provider 的复制。上面 7/9 是来源依赖分类,不意味着只有 9 个组件需要工程调整,也不把子导出与支持文件重复计数。

发布与验证边界

每个家族应同时具备独立预览、安装条目、关键 Props、状态说明和来源。Registry 产物声明直接依赖,并以版本路径分发;文档不把原 Subtic 的历史验收记录算作 Kitseed 的当前测试结果。

本仓库的类型、构建、交互、可访问性与消费项目检查,以实际交付结果为准。文档完成不代表已经部署,也不代表 Subtic 已采用新组件。

来源与许可

源项目为 /Users/cbq926/Program/Project/subtic,组件页记录 repo-relative 来源路径。Subtic 为私有应用,其开源授权尚未确认;Kitseed 首期保持私有,不默认添加 MIT 等源码许可证。第三方依赖与 Geist 字体继续遵循各自许可。

本页内容