每加一种画布节点,叫什么、长什么样、能不能自由拉伸要在 4-5 处各写一遍。 实际后果是节点标签出现三份且互相矛盾(NODE_DEFAULT_SIZE.title / 创建菜单 label / 搜索弹窗 nodeTypeLabel),canvas-node-size.ts 里还有第四份硬编码兜底。 新增 lib/canvas/node-registry/,镜像现有 tool-registry/ 的结构: 静态定义带 satisfies Record<CanvasNodeType, ...> 做编译期穷尽性检查 (往枚举加成员不补定义即编译失败),再注册进模块级 Map 并按 ownerId 归属, 为后续扩展留出隔离位。 尺寸与初始 metadata 的数据源仍是 constant/canvas.ts 的 NODE_SPECS,定义文件读它 而非复制,现有约 40 处布局计算未动;渲染层 nodeContentRenderers 已是查表结构, 本次不改。 标签刻意分三个字段各司其职,界面文案零变化: - defaultTitle 新建节点默认名(Note/Audio/未命名背板 原样保留) - label UI 短标签 - listLabel 列表标签,缺省派生为 label + 节点;背板显式钉住为背板 接入 3 处调用点:创建菜单标签与图标、搜索弹窗类型标签、canvas-node.tsx 的 minWidth/minHeight 与 keepRatio。导演台落在节点分区但开的是工作台、不是节点类型, 故不走注册表。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
30 lines
1.3 KiB
TypeScript
30 lines
1.3 KiB
TypeScript
import type { ReactNode } from "react";
|
||
|
||
import type { CanvasNodeData, CanvasNodeMetadata, CanvasNodeType } from "@/types/canvas";
|
||
|
||
/**
|
||
* 节点定义——注册表的基本单元。
|
||
*
|
||
* 一种画布节点类型的静态知识(叫什么、长什么样、能拉多小、是否锁比例)集中在这里,
|
||
* 避免同一份知识散落到创建菜单、搜索弹窗、拉伸逻辑等多处后各自漂移。
|
||
*/
|
||
export type CanvasNodeDefinition = {
|
||
type: CanvasNodeType;
|
||
/** UI 短标签——创建菜单等处显示,如「文本」 */
|
||
label: string;
|
||
/** 列表/搜索标签,缺省派生为 `${label}节点` */
|
||
listLabel?: string;
|
||
/** 不带 className——由渲染处用 [&_svg]:size-* 统一控制尺寸 */
|
||
icon: ReactNode;
|
||
/** 新建节点的默认标题(与 label 分开:菜单叫「文本」,新建出来的节点名是「Note」) */
|
||
defaultTitle: string;
|
||
defaultSize: { width: number; height: number };
|
||
defaultMetadata?: CanvasNodeMetadata;
|
||
/** 手动拉伸的最小尺寸 */
|
||
minSize: { width: number; height: number };
|
||
/** 拉伸时是否锁定宽高比,缺省不锁 */
|
||
keepAspectRatio?: (node: CanvasNodeData) => boolean;
|
||
/** 是否出现在添加节点菜单(技能、生成配置由其他入口创建) */
|
||
showInCreateMenu: boolean;
|
||
};
|