@xbeeant/form-engine-designer 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/es/Canvas.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { jsxs as F, jsx as s, Fragment as Ee } from "react/jsx-runtime";
2
2
  import { isLayoutNode as Oe, isDataField as Se } from "@xbeeant/form-engine";
3
+ /* empty css */
3
4
  import { NexusField as Ie } from "./react/src/components/NexusField.js";
4
5
  import { NexusForm as ke } from "./react/src/components/NexusForm.js";
5
6
  import { NexusFormProvider as Fe } from "./react/src/components/NexusFormProvider.js";
@@ -271,7 +272,7 @@ const Be = Le(
271
272
  function Ge(e) {
272
273
  return e === null || e.type === "inside" ? null : U(e.path);
273
274
  }
274
- function it() {
275
+ function lt() {
275
276
  const {
276
277
  schema: e,
277
278
  selectedPath: t,
@@ -631,6 +632,6 @@ function it() {
631
632
  );
632
633
  }
633
634
  export {
634
- it as Canvas
635
+ lt as Canvas
635
636
  };
636
637
  //# sourceMappingURL=Canvas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Canvas.js","sources":["../../src/Canvas.tsx"],"sourcesContent":["// ============================================================================\n// @xbeeant/form-engine-designer — 中间画布面板\n// ============================================================================\n\nimport type { NexusSchema, SchemaNode } from '@xbeeant/form-engine';\nimport { isDataField, isLayoutNode } from '@xbeeant/form-engine';\nimport {\n GridContext,\n NexusField,\n NexusForm,\n type NexusFormConfig,\n NexusFormProvider,\n useForm,\n} from '@xbeeant/form-engine-react';\nimport { Button, Empty, Modal, Space, Tag, Typography } from 'antd';\nimport type React from 'react';\nimport { memo, useCallback, useEffect, useMemo, useState } from 'react';\nimport { useDesigner } from './DesignerContext';\nimport {\n generateKey,\n getNodeAtProperties,\n getNodeLabel,\n getPropertiesOf,\n moveNodeInSchema,\n removeNodeFromSchema,\n} from './schemaUtils';\nimport type { CatalogItem, FieldDef } from './types';\n\n// ── 拖拽数据载荷 ────────────────────────────────────────────────────────────\ninterface PaletteDragPayload {\n source: 'palette';\n catalogItem: CatalogItem;\n}\ninterface FieldDefDragPayload {\n source: 'fieldDef';\n fieldDef: FieldDef;\n}\ninterface CanvasDragPayload {\n source: 'canvas';\n fromPath: string[];\n}\ntype DragPayload = PaletteDragPayload | FieldDefDragPayload | CanvasDragPayload;\n\nconst DRAG_MIME = 'application/json';\n\n// ── Drop 目标类型 ───────────────────────────────────────────────────────────\ntype DropTarget =\n | { type: 'inside'; path: string[] } // 拖入容器内部(追加到末尾)\n | { type: 'before'; path: string[] } // 插入到某节点之前\n | { type: 'after'; path: string[] } // 插入到某节点之后\n | null;\n\nfunction pathEquals(a: string[] | null, b: string[]): boolean {\n if (!a) {\n return false;\n }\n if (a.length !== b.length) {\n return false;\n }\n return a.every((seg, i) => seg === b[i]);\n}\n\nfunction dropTargetEquals(a: DropTarget, b: DropTarget): boolean {\n if (a === null && b === null) {\n return true;\n }\n if (a === null || b === null) {\n return false;\n }\n return a.type === b.type && pathEquals(a.path, b.path);\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// 面板节点(tabPane / collapsePanel / step)与容器类型的映射\n// 面板只能放入对应的 tabs / collapse / steps 容器(否则渲染结构非法);\n// 普通节点直接拖入这些容器时自动包裹成新面板,保证运行时渲染结构合法。\n// ────────────────────────────────────────────────────────────────────────────\n\n/** 面板类型 → 唯一允许的父容器类型 */\nconst PANE_PARENT_TYPE: Record<string, string> = {\n tabPane: 'tabs',\n collapsePanel: 'collapse',\n step: 'steps',\n};\n\n/** 容器类型 → 默认面板类型 */\nconst CONTAINER_PANE_TYPE: Record<string, string> = {\n tabs: 'tabPane',\n collapse: 'collapsePanel',\n steps: 'step',\n};\n\n/** 面板默认标题 */\nconst PANE_DEFAULT_TITLE: Record<string, string> = {\n tabPane: '标签页',\n collapsePanel: '折叠面板',\n step: '步骤',\n};\n\n/** 获取路径终点节点的容器类型(根路径返回 undefined) */\nfunction getContainerTypeAt(\n schema: NexusSchema,\n path: string[],\n): string | undefined {\n if (path.length === 0) {\n return undefined;\n }\n const node = getNodeAtProperties(schema.properties, path);\n return node ? (node.type as string) : undefined;\n}\n\n/**\n * 解析一次「新增节点」插入所需的节点构造器:\n * - 面板节点(tabPane/collapsePanel/step):仅当目标父级是对应容器时放行,否则拒绝\n * - 普通节点拖入 tabs/collapse/steps 容器:自动包裹成新面板\n * - 其余情况:原样返回\n *\n * @param innerKey 外部字段拖入时使用的固定 key(作为包裹面板内部字段的 key)\n * @returns 插入用构造器;返回 null 表示本次插入被拒绝\n */\nfunction resolveInsertFactory(\n schema: NexusSchema,\n toParentPath: string[],\n createNode: () => SchemaNode,\n nodeType: string,\n innerKey?: string,\n): (() => SchemaNode) | null {\n const parentType = getContainerTypeAt(schema, toParentPath);\n\n const requiredParent = PANE_PARENT_TYPE[nodeType];\n if (requiredParent) {\n return parentType === requiredParent ? createNode : null;\n }\n\n const paneType = parentType ? CONTAINER_PANE_TYPE[parentType] : undefined;\n if (paneType) {\n return () =>\n ({\n type: paneType,\n title: PANE_DEFAULT_TITLE[paneType],\n properties: {\n [innerKey ?? generateKey({}, nodeType)]: createNode(),\n },\n }) as unknown as SchemaNode;\n }\n\n return createNode;\n}\n\n/**\n * 解析一次「移动已有节点」的落点:\n * - 移动面板节点:仅允许放入对应容器(否则返回 null)\n * - 普通节点移入 tabs/collapse/steps 容器:包裹成新面板\n *\n * @returns wrapped 为 true 时 node 是新建的包裹面板,需删除原节点\n */\nfunction resolveMoveNode(\n schema: NexusSchema,\n fromPath: string[],\n toParentPath: string[],\n): { node: SchemaNode; wrapped: boolean } | null {\n const node = getNodeAtProperties(schema.properties, fromPath);\n if (!node) {\n return null;\n }\n const parentType = getContainerTypeAt(schema, toParentPath);\n const nodeType = node.type as string;\n\n const requiredParent = PANE_PARENT_TYPE[nodeType];\n if (requiredParent) {\n return parentType === requiredParent ? { node, wrapped: false } : null;\n }\n\n const paneType = parentType ? CONTAINER_PANE_TYPE[parentType] : undefined;\n if (paneType) {\n return {\n wrapped: true,\n node: {\n type: paneType,\n title: PANE_DEFAULT_TITLE[paneType],\n properties: {\n [fromPath[fromPath.length - 1]]: node,\n },\n } as unknown as SchemaNode,\n };\n }\n\n return { node, wrapped: false };\n}\n\n// 判断 targetPath 是否是 fromPath 自身或其后代\nfunction isDescendantOrSelf(fromPath: string[], targetPath: string[]): boolean {\n if (fromPath.length <= targetPath.length) {\n return targetPath\n .slice(0, fromPath.length)\n .every((seg, i) => seg === fromPath[i]);\n }\n return false;\n}\n\n// 判断是否允许拖入(纯函数:不依赖组件作用域)\nfunction canDrop(fromPath: string[], targetPath: string[]): boolean {\n if (isDescendantOrSelf(fromPath, targetPath)) {\n return false;\n }\n const fromParent = fromPath.slice(0, -1);\n return !(\n fromParent.length === targetPath.length &&\n fromParent.every((seg, i) => seg === targetPath[i])\n );\n}\n\n// 计算 insertIndex:将节点移动/新增到目标位置(纯函数:不依赖组件作用域)\nfunction computeInsertIndex(\n target: DropTarget,\n schemaProps: Record<string, SchemaNode>,\n): { toParentPath: string[]; insertIndex: number } | null {\n if (!target || target.type === 'inside') {\n return null;\n }\n\n const nodeIndex = getIndexInParent(schemaProps, target.path);\n if (nodeIndex === -1) {\n return null;\n }\n\n const toParentPath = target.path.slice(0, -1);\n\n if (target.type === 'before') {\n return { toParentPath, insertIndex: nodeIndex };\n } else {\n // after\n return { toParentPath, insertIndex: nodeIndex + 1 };\n }\n}\n\nfunction resolveCatalogItem(\n payload: CatalogItem,\n widgetCatalog: CatalogItem[],\n layoutCatalog: CatalogItem[],\n): CatalogItem | undefined {\n if (payload.category === 'widget') {\n return widgetCatalog.find((c) => c.widget === payload.widget);\n }\n return layoutCatalog.find((c) => c.layoutType === payload.layoutType);\n}\n\n// 根据 widget 名推断 schema type(用于外部字段拖入时构造节点)\nfunction inferSchemaType(widget: string): string {\n if (['checkbox', 'switch'].includes(widget)) {\n return 'boolean';\n }\n if (['number', 'slider'].includes(widget)) {\n return 'number';\n }\n if (['checkboxes', 'multiSelect'].includes(widget)) {\n return 'array';\n }\n if (widget === 'object') {\n return 'object';\n }\n return 'string';\n}\n\n// 获取节点在其父级中的 index\nfunction getIndexInParent(\n schemaProps: Record<string, SchemaNode>,\n path: string[],\n): number {\n const parentPath = path.slice(0, -1);\n const key = path[path.length - 1];\n const parentProps =\n parentPath.length === 0\n ? schemaProps\n : getNodeAtProperties(schemaProps, parentPath) &&\n getPropertiesOf(getNodeAtProperties(schemaProps, parentPath)!);\n if (!parentProps) {\n return -1;\n }\n return Object.keys(parentProps).indexOf(key);\n}\n\n// 与 getParentProps 相同,但作用于指定 schema(用于在副本上定位 properties)\nfunction getPropsAtPath(\n targetSchema: NexusSchema,\n parentPath: string[],\n): Record<string, SchemaNode> | undefined {\n if (parentPath.length === 0) {\n return targetSchema.properties;\n }\n const parent = getNodeAtProperties(targetSchema.properties, parentPath);\n return parent ? getPropertiesOf(parent) : undefined;\n}\n\n// 从事件中计算 drop 目标(避免状态延迟)\nfunction computeDropTargetFromEvent(\n e: React.DragEvent,\n path: string[],\n): DropTarget {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const y = e.clientY - rect.top;\n const type: 'before' | 'after' = y < rect.height / 2 ? 'before' : 'after';\n return { type, path };\n}\n\n/** 路径数组 → 稳定字符串 key(JSON 序列化,任意 key 内容均安全) */\nfunction toPathKey(path: string[]): string {\n return JSON.stringify(path);\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// CanvasActions — 下发给 CanvasNode 的回调集合\n// 全部 useCallback 稳定化:schema/catalog 未变时引用不变,\n// 配合 React.memo 让拖拽热路径(dragOver → setDropTarget)只重渲染受影响节点\n// ────────────────────────────────────────────────────────────────────────────\n\ninterface CanvasActions {\n onSelect: (path: string[]) => void;\n onDelete: (path: string[]) => void;\n onReorder: (path: string[], direction: 'up' | 'down') => void;\n onDragStart: (e: React.DragEvent, path: string[]) => void;\n onDragOver: (e: React.DragEvent, path: string[]) => void;\n onNodeDrop: (e: React.DragEvent, path: string[]) => void;\n onContainerDragOver: (e: React.DragEvent) => void;\n onContainerDrop: (e: React.DragEvent, path: string[]) => void;\n}\n\ninterface CanvasNodeProps {\n node: SchemaNode;\n /** 节点在 schema 中的路径 key(JSON 字符串,跨渲染引用稳定) */\n pathKey: string;\n depth: number;\n /** 祖先数据路径(布局节点 key 不进入,与 SchemaParser 对齐) */\n parentDataPath: string;\n /** 父级计算好的派生值:仅本节点相关(boolean/string,参与 memo 比较) */\n isSelected: boolean;\n dropTargetType: 'before' | 'after' | null;\n /** 原始状态透传(供本节点计算其子节点的派生值;不参与 memo 比较) */\n selectedPathKey: string | null;\n dropTarget: DropTarget;\n actions: CanvasActions;\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// CanvasNode — 单个节点的递归渲染(memo 化,自定义比较器)\n// 比较器只对比派生值(isSelected / dropTargetType)与稳定引用(node / pathKey /\n// depth / parentDataPath / actions):拖拽过程中只有 drop 目标节点与选中节点\n// 的派生值变化 → 其余子树整体跳过重渲染,热路径从 O(N) 降为 O(1)\n// ────────────────────────────────────────────────────────────────────────────\n\nconst CanvasNode = memo(\n function CanvasNode({\n node,\n pathKey,\n depth,\n parentDataPath,\n isSelected,\n dropTargetType,\n selectedPathKey,\n dropTarget,\n actions,\n }: CanvasNodeProps) {\n const path = useMemo(() => JSON.parse(pathKey) as string[], [pathKey]);\n const childProps = getPropertiesOf(node);\n const hasChildren = childProps !== undefined;\n const label = getNodeLabel(node, path[path.length - 1]);\n const badge = node.widget || node.type;\n // 计算数据路径:布局节点 key 不进入数据路径(与 SchemaParser 对齐)\n const isLayout = isLayoutNode(node);\n const dataPath = isLayout\n ? parentDataPath\n : parentDataPath\n ? `${parentDataPath}.${path[path.length - 1]}`\n : path[path.length - 1];\n const childEntries = childProps ? Object.entries(childProps) : [];\n const isField = isDataField(node);\n\n return (\n <div\n key={pathKey}\n className='mb-1.5 relative'\n style={{ marginLeft: depth }}\n >\n {/* before 插入指示线 — 显示在容器上方 */}\n {dropTargetType === 'before' && (\n <div className='drop-indicator-line relative h-1 pointer-events-none z-10 -mt-0.5' />\n )}\n\n {/* 统一包裹容器:header + 预览/子节点 */}\n <div\n className={`relative rounded border bg-white transition-all ${\n isSelected\n ? 'border-[#1677ff] bg-[#e6f4ff] shadow-[0_0_0_2px_rgba(22,119,255,0.1)]'\n : 'border-[#e8e8e8] hover:border-[#1677ff]'\n }`}\n >\n {/* header 行:拖拽 + 信息 + 操作 */}\n <div\n className='flex items-center gap-1.5 px-2 py-1.5 cursor-grab'\n draggable\n onDragStart={(e) => actions.onDragStart(e, path)}\n onDragOver={(e) => actions.onDragOver(e, path)}\n onDragLeave={(e) => {\n e.stopPropagation();\n }}\n onDrop={(e) => actions.onNodeDrop(e, path)}\n onClick={(e) => {\n e.stopPropagation();\n actions.onSelect(path);\n }}\n >\n <Tag\n color={hasChildren || isLayout ? 'blue' : undefined}\n className='m-0! shrink-0'\n >\n {badge}\n </Tag>\n <Typography.Text className='flex-1 overflow-hidden text-ellipsis whitespace-nowrap'>\n {label}\n </Typography.Text>\n <Typography.Text className='text-[#bfbfbf] text-[11px] font-mono shrink-0'>\n {path[path.length - 1]}\n </Typography.Text>\n {isSelected && (\n <span className='inline-flex gap-1'>\n <Button\n size='small'\n onClick={(e) => {\n e.stopPropagation();\n actions.onReorder(path, 'up');\n }}\n >\n ↑\n </Button>\n <Button\n size='small'\n onClick={(e) => {\n e.stopPropagation();\n actions.onReorder(path, 'down');\n }}\n >\n ↓\n </Button>\n <Button\n size='small'\n danger\n onClick={(e) => {\n e.stopPropagation();\n actions.onDelete(path);\n }}\n >\n ×\n </Button>\n </span>\n )}\n </div>\n\n {/* 字段节点:通过 NexusField 渲染,复用引擎 reaction/联动 */}\n {isField && (\n <div className='px-2 pb-2'>\n <NexusField\n dataPath={dataPath}\n layoutKey={path[path.length - 1]}\n />\n </div>\n )}\n\n {/* 有子节点的容器:显示子节点 */}\n {!isField &&\n hasChildren &&\n (() => {\n const isGridNode = node.type === 'grid';\n const isFlexNode = node.type === 'flex';\n\n // 根据布局类型构建容器 CSS 样式\n let containerStyle: React.CSSProperties | undefined;\n let gridContextValue: { column: number } | null = null;\n\n if (isGridNode) {\n const column = Math.max(1, (node as any).column ?? 2);\n const gap = (node as any).gap ?? 12;\n containerStyle = {\n display: 'grid',\n gridTemplateColumns: `repeat(${column}, 1fr)`,\n gap: `${gap}px`,\n };\n gridContextValue = { column };\n } else if (isFlexNode) {\n const gap = (node as any).gap ?? 8;\n const direction = (node as any).direction ?? 'row';\n const flexAlign = (node as any).align ?? 'flex-start';\n const flexJustify = (node as any).justify ?? 'flex-start';\n const flexWrap = (node as any).wrap ?? false;\n containerStyle = {\n display: 'flex',\n flexDirection: direction === 'column' ? 'column' : 'row',\n alignItems: flexAlign,\n justifyContent: flexJustify,\n flexWrap: flexWrap ? 'wrap' : 'nowrap',\n gap: `${gap}px`,\n };\n }\n\n const innerContent = (\n <>\n {childEntries.map(([childKey, childNode]) => {\n const childPathKey = toPathKey([...path, childKey]);\n const childIsSelected = selectedPathKey === childPathKey;\n const childDropTargetType =\n dropTarget &&\n (dropTarget.type === 'before' ||\n dropTarget.type === 'after') &&\n dropTargetPathKey(dropTarget) === childPathKey\n ? dropTarget.type\n : null;\n return (\n <CanvasNode\n key={childPathKey}\n node={childNode}\n pathKey={childPathKey}\n depth={depth + 1}\n parentDataPath={dataPath}\n isSelected={childIsSelected}\n dropTargetType={childDropTargetType}\n selectedPathKey={selectedPathKey}\n dropTarget={dropTarget}\n actions={actions}\n />\n );\n })}\n {childEntries.length === 0 && (\n <div className='text-[#bfbfbf] text-xs text-center py-2'>\n 拖拽组件到此处\n </div>\n )}\n </>\n );\n\n const childDiv = (\n <div\n className='mx-2 mb-2 p-2 border border-dashed rounded min-h-8 bg-[rgba(250,250,250,0.6)] border-[#d9d9d9]'\n style={containerStyle}\n onClick={(e) => {\n e.stopPropagation();\n }}\n onDragOver={actions.onContainerDragOver}\n onDrop={(e) => actions.onContainerDrop(e, path)}\n >\n {innerContent}\n </div>\n );\n\n // grid 需要提供 GridContext 给子项中的 NexusField 解析 colSpan\n if (gridContextValue) {\n return (\n <GridContext.Provider value={gridContextValue}>\n {childDiv}\n </GridContext.Provider>\n );\n }\n\n return childDiv;\n })()}\n </div>\n\n {/* after 插入指示线 */}\n {dropTargetType === 'after' && (\n <div className='drop-indicator-line relative h-1 pointer-events-none z-10 -mb-0.5' />\n )}\n </div>\n );\n },\n (prev, next) =>\n prev.node === next.node &&\n prev.pathKey === next.pathKey &&\n prev.depth === next.depth &&\n prev.parentDataPath === next.parentDataPath &&\n prev.isSelected === next.isSelected &&\n prev.dropTargetType === next.dropTargetType &&\n prev.actions === next.actions,\n);\n\n/** 取 before/after 类型 drop 目标的路径 key(inside 目标无节点级指示) */\nfunction dropTargetPathKey(target: DropTarget): string | null {\n if (target === null || target.type === 'inside') {\n return null;\n }\n return toPathKey(target.path);\n}\n\nexport function Canvas() {\n const {\n schema,\n selectedPath,\n mode,\n selectNode,\n addNode,\n removeNode,\n setSchema,\n registerUI,\n widgetCatalog,\n layoutCatalog,\n } = useDesigner();\n // 设计/预览各持有一个独立的 form 实例(engine):\n // 设计态由下方 effect 手动 init,预览态由 <NexusForm> 内部 init,\n // 二者互不干扰,避免切换模式时 fieldState/data 相互污染。\n const [designForm] = useForm();\n const [previewForm] = useForm();\n const designEngine = designForm._getEngine();\n const previewEngine = previewForm._getEngine();\n const [dropTarget, setDropTarget] = useState<DropTarget>(null);\n const [previewResult, setPreviewResult] = useState<Record<\n string,\n unknown\n > | null>(null);\n\n // 注册 widgets/layouts:仅供引擎消费一次,避免每次渲染重复注册\n // registerUI 由使用方传入(如 registerAntdUI),解耦对具体 UI 库的依赖\n useEffect(() => {\n registerUI?.(designEngine);\n registerUI?.(previewEngine);\n }, [registerUI, designEngine, previewEngine]);\n\n // 编辑模式下初始化引擎,使 NexusField 能读取 fieldState 并触发 reactions(联动)\n // 预览模式由 <NexusForm> 内部负责 engine.init\n useEffect(() => {\n if (mode === 'preview') {\n return;\n }\n const currentData = designEngine.getFormData();\n designEngine.init(\n schema,\n Object.keys(currentData).length > 0 ? currentData : undefined,\n );\n }, [designEngine, schema, mode]);\n\n const formConfig = useMemo<NexusFormConfig>(\n () => ({\n displayType: schema.displayType ?? 'row',\n labelWidth: schema.labelWidth,\n colon: schema.colon,\n label: schema.label ?? true,\n readOnly: schema.readOnly ?? false,\n column: schema.column,\n }),\n [schema],\n );\n\n useEffect(() => {\n const handleDragEnd = () => setDropTarget(null);\n window.addEventListener('dragend', handleDragEnd);\n return () => window.removeEventListener('dragend', handleDragEnd);\n }, []);\n\n const getParentProps = useCallback(\n (parentPath: string[]) => {\n if (parentPath.length === 0) {\n return schema.properties;\n }\n const parent = getNodeAtProperties(schema.properties, parentPath);\n return parent ? getPropertiesOf(parent) : undefined;\n },\n [schema],\n );\n\n // 统一处理 drop(依赖 schema,schema 变化时重建;拖拽过程中保持稳定)\n const handleDrop = useCallback(\n (e: React.DragEvent, target: DropTarget) => {\n e.preventDefault();\n e.stopPropagation();\n setDropTarget(null);\n if (!target) {\n return;\n }\n\n const data = e.dataTransfer.getData(DRAG_MIME);\n if (!data) {\n return;\n }\n let payload: DragPayload;\n try {\n payload = JSON.parse(data) as DragPayload;\n } catch {\n return;\n }\n\n // ── 情况一:从画布拖动已有节点 ──\n if (payload.source === 'canvas') {\n const fromPath = payload.fromPath;\n\n if (target.type === 'inside') {\n // 拖入容器内部\n if (!canDrop(fromPath, target.path)) {\n return;\n }\n // 面板节点仅入对应容器;普通节点进 tabs/collapse/steps 时自动包裹\n const resolved = resolveMoveNode(schema, fromPath, target.path);\n if (!resolved) {\n return;\n }\n if (!resolved.wrapped) {\n setSchema(moveNodeInSchema(schema, fromPath, target.path));\n } else {\n let next = structuredClone(schema) as NexusSchema;\n const toProps = getPropsAtPath(next, target.path);\n if (!toProps) {\n return;\n }\n const paneKey = generateKey(toProps, 'panel');\n toProps[paneKey] = resolved.node;\n next = removeNodeFromSchema(next, fromPath);\n setSchema(next);\n }\n selectNode(null);\n return;\n }\n\n // before / after\n if (!canDrop(fromPath, target.path)) {\n return;\n }\n const result = computeInsertIndex(target, schema.properties);\n if (!result) {\n return;\n }\n\n // 同父级移动时调整 insertIndex\n const fromParent = fromPath.slice(0, -1);\n const sameParent =\n fromParent.length === result.toParentPath.length &&\n fromParent.every((seg, i) => seg === result.toParentPath[i]);\n\n let insertIndex = result.insertIndex;\n if (sameParent) {\n const fromIndex = getIndexInParent(schema.properties, fromPath);\n if (fromIndex !== -1 && fromIndex < insertIndex) {\n insertIndex -= 1;\n }\n }\n\n const resolved = resolveMoveNode(schema, fromPath, result.toParentPath);\n if (!resolved) {\n return;\n }\n if (!resolved.wrapped) {\n setSchema(\n moveNodeInSchema(\n schema,\n fromPath,\n result.toParentPath,\n insertIndex,\n ),\n );\n } else {\n let next = structuredClone(schema) as NexusSchema;\n const toProps = getPropsAtPath(next, result.toParentPath);\n if (!toProps) {\n return;\n }\n const paneKey = generateKey(toProps, 'panel');\n toProps[paneKey] = resolved.node;\n next = removeNodeFromSchema(next, fromPath);\n // 将包裹面板移动到目标插入位置\n setSchema(\n moveNodeInSchema(\n next,\n [...result.toParentPath, paneKey],\n result.toParentPath,\n insertIndex,\n ),\n );\n }\n selectNode(null);\n return;\n }\n\n // ── 情况二:从 palette 或 fieldDef 拖入新组件 ──\n let base: string;\n let createNode: () => SchemaNode;\n let fixedKey: string | undefined;\n\n if (payload.source === 'fieldDef') {\n // 外部字段:id 作为 key,name 作为 title,且不允许修改\n const fd = payload.fieldDef;\n base = fd.widget;\n fixedKey = fd.id;\n createNode = () =>\n ({\n type: inferSchemaType(fd.widget),\n widget: fd.widget,\n title: fd.name,\n // 锁定标记:禁止在设计器中修改 key 和 title\n _lockedKey: true,\n _lockedTitle: true,\n }) as unknown as SchemaNode;\n } else {\n // palette 组件目录\n const found = resolveCatalogItem(\n payload.catalogItem,\n widgetCatalog,\n layoutCatalog,\n );\n if (!found) {\n return;\n }\n base = found.widget || found.layoutType || 'field';\n createNode = () => found.createNode() as unknown as SchemaNode;\n }\n\n if (target.type === 'inside') {\n const parentProps = getParentProps(target.path);\n if (!parentProps) {\n return;\n }\n // 面板类型校验 / 普通节点进面板容器时自动包裹\n const factory = resolveInsertFactory(\n schema,\n target.path,\n createNode,\n base,\n fixedKey,\n );\n if (!factory) {\n return;\n }\n const key = fixedKey ?? generateKey(parentProps, base);\n // 若 fixedKey 已存在,则跳过\n if (fixedKey && key in parentProps) {\n return;\n }\n addNode(target.path, key, factory());\n return;\n }\n\n // before / after\n const result = computeInsertIndex(target, schema.properties);\n if (!result) {\n return;\n }\n // 面板类型校验 / 普通节点进面板容器时自动包裹\n const factory = resolveInsertFactory(\n schema,\n result.toParentPath,\n createNode,\n base,\n fixedKey,\n );\n if (!factory) {\n return;\n }\n\n // 在副本上操作:先 add 再 move\n const next = structuredClone(schema) as NexusSchema;\n const nextParentProps = getPropsAtPath(next, result.toParentPath);\n if (!nextParentProps) {\n return;\n }\n\n const newKey = fixedKey ?? generateKey(nextParentProps, base);\n if (fixedKey && newKey in nextParentProps) {\n return;\n }\n nextParentProps[newKey] = factory();\n\n const fullNewPath = [...result.toParentPath, newKey];\n setSchema(\n moveNodeInSchema(\n next,\n fullNewPath,\n result.toParentPath,\n result.insertIndex,\n ),\n );\n },\n [\n schema,\n widgetCatalog,\n layoutCatalog,\n addNode,\n getParentProps,\n setSchema,\n selectNode,\n ],\n );\n\n // 节点 header 拖拽源 + drop 目标(仅依赖 setDropTarget,拖拽过程中引用稳定)\n const handleNodeDragStart = useCallback(\n (e: React.DragEvent, path: string[]) => {\n e.stopPropagation();\n const payload: CanvasDragPayload = { source: 'canvas', fromPath: path };\n e.dataTransfer.setData(DRAG_MIME, JSON.stringify(payload));\n e.dataTransfer.effectAllowed = 'move';\n },\n [],\n );\n\n // 基于鼠标 Y 坐标判断 before/after(仅依赖 setDropTarget,引用稳定)\n const handleNodeDragOver = useCallback(\n (e: React.DragEvent, path: string[]) => {\n e.preventDefault();\n e.stopPropagation();\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const y = e.clientY - rect.top;\n const type: 'before' | 'after' = y < rect.height / 2 ? 'before' : 'after';\n const newTarget: DropTarget = { type, path };\n // 根据 effectAllowed 设置 dropEffect,避免 palette(copy) 与 canvas(move) 互斥\n e.dataTransfer.dropEffect =\n e.dataTransfer.effectAllowed === 'copy' ? 'copy' : 'move';\n setDropTarget((prev) => {\n if (dropTargetEquals(prev, newTarget)) {\n return prev;\n }\n return newTarget;\n });\n },\n [],\n );\n\n const handleNodeDrop = useCallback(\n (e: React.DragEvent, path: string[]) => {\n e.stopPropagation();\n const target = computeDropTargetFromEvent(e, path);\n handleDrop(e, target);\n },\n [handleDrop],\n );\n\n const handleDelete = useCallback(\n (path: string[]) => {\n removeNode(path);\n },\n [removeNode],\n );\n\n const handleSelect = useCallback(\n (path: string[]) => {\n selectNode(path);\n },\n [selectNode],\n );\n\n const handleReorder = useCallback(\n (path: string[], direction: 'up' | 'down') => {\n const parentPath = path.slice(0, -1);\n const key = path[path.length - 1];\n const parentProps = getParentProps(parentPath);\n if (!parentProps) {\n return;\n }\n const keys = Object.keys(parentProps);\n const idx = keys.indexOf(key);\n if (idx < 0) {\n return;\n }\n if (direction === 'up' && idx === 0) {\n return;\n }\n if (direction === 'down' && idx === keys.length - 1) {\n return;\n }\n const insertIndex = direction === 'up' ? idx - 1 : idx + 1;\n setSchema(moveNodeInSchema(schema, path, parentPath, insertIndex));\n selectNode(path);\n },\n [getParentProps, schema, setSchema, selectNode],\n );\n\n // 容器空白区 dragOver:清除节点上的 drop target 指示\n const handleContainerDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.dataTransfer.dropEffect =\n e.dataTransfer.effectAllowed === 'copy' ? 'copy' : 'move';\n setDropTarget((prev) => {\n if (prev === null) {\n return prev;\n }\n return null;\n });\n }, []);\n\n const handleContainerDrop = useCallback(\n (e: React.DragEvent, path: string[]) => {\n e.stopPropagation();\n handleDrop(e, { type: 'inside', path });\n },\n [handleDrop],\n );\n\n // 下发给 CanvasNode 的稳定回调集合:\n // 拖拽过程(dropTarget 变化)中所有回调引用不变 → 子节点 memo 生效\n const actions = useMemo<CanvasActions>(\n () => ({\n onSelect: handleSelect,\n onDelete: handleDelete,\n onReorder: handleReorder,\n onDragStart: handleNodeDragStart,\n onDragOver: handleNodeDragOver,\n onNodeDrop: handleNodeDrop,\n onContainerDragOver: handleContainerDragOver,\n onContainerDrop: handleContainerDrop,\n }),\n [\n handleSelect,\n handleDelete,\n handleReorder,\n handleNodeDragStart,\n handleNodeDragOver,\n handleNodeDrop,\n handleContainerDragOver,\n handleContainerDrop,\n ],\n );\n\n if (mode === 'preview') {\n return (\n <div className='flex-1 overflow-y-auto p-4 bg-[#f5f5f5] min-h-full border border-transparent box-border'>\n <NexusForm form={previewForm} schema={schema} />\n <div style={{ marginTop: 16, textAlign: 'center' }}>\n <Space>\n <Button\n type='primary'\n onClick={async () => {\n try {\n const errors = await previewForm.validateFields();\n if (errors.size > 0) {\n return;\n }\n const values = previewForm.getValues();\n setPreviewResult(values);\n } catch {\n // 校验失败,不弹窗\n }\n }}\n >\n 提交\n </Button>\n <Button onClick={() => previewForm.resetFields()}>重置</Button>\n </Space>\n </div>\n <Modal\n title='表单数据'\n open={previewResult !== null}\n onCancel={() => setPreviewResult(null)}\n footer={[\n <Button key='close' onClick={() => setPreviewResult(null)}>\n 关闭\n </Button>,\n ]}\n width={600}\n >\n <pre\n style={{\n maxHeight: 400,\n overflow: 'auto',\n background: '#f5f5f5',\n padding: 12,\n borderRadius: 6,\n fontSize: 13,\n margin: 0,\n }}\n >\n {JSON.stringify(previewResult, null, 2)}\n </pre>\n </Modal>\n </div>\n );\n }\n\n const rootEntries = Object.entries(schema.properties);\n\n return (\n <NexusFormProvider\n form={designForm}\n engine={designEngine}\n config={formConfig}\n >\n <div\n className='flex-1 overflow-y-auto p-4 bg-[#f5f5f5] min-h-full border border-transparent box-border'\n onClick={() => selectNode(null)}\n onDragOver={handleContainerDragOver}\n onDrop={(e) => handleContainerDrop(e, [])}\n >\n <div>\n {rootEntries.map(([key, node]) => (\n <CanvasNode\n key={toPathKey([key])}\n node={node}\n pathKey={toPathKey([key])}\n depth={0}\n parentDataPath=''\n isSelected={pathEquals(selectedPath, [key])}\n dropTargetType={\n dropTarget &&\n (dropTarget.type === 'before' || dropTarget.type === 'after') &&\n pathEquals(dropTarget.path, [key])\n ? dropTarget.type\n : null\n }\n selectedPathKey={selectedPath ? toPathKey(selectedPath) : null}\n dropTarget={dropTarget}\n actions={actions}\n />\n ))}\n {rootEntries.length === 0 && (\n <Empty description='拖拽组件到此处开始设计' />\n )}\n </div>\n </div>\n </NexusFormProvider>\n );\n}\n"],"names":["DRAG_MIME","pathEquals","a","b","seg","i","dropTargetEquals","PANE_PARENT_TYPE","CONTAINER_PANE_TYPE","PANE_DEFAULT_TITLE","getContainerTypeAt","schema","path","node","getNodeAtProperties","resolveInsertFactory","toParentPath","createNode","nodeType","innerKey","parentType","requiredParent","paneType","generateKey","resolveMoveNode","fromPath","isDescendantOrSelf","targetPath","canDrop","fromParent","computeInsertIndex","target","schemaProps","nodeIndex","getIndexInParent","resolveCatalogItem","payload","widgetCatalog","layoutCatalog","c","inferSchemaType","widget","parentPath","key","parentProps","getPropertiesOf","getPropsAtPath","targetSchema","parent","computeDropTargetFromEvent","rect","toPathKey","CanvasNode","memo","pathKey","depth","parentDataPath","isSelected","dropTargetType","selectedPathKey","dropTarget","actions","useMemo","childProps","hasChildren","label","getNodeLabel","badge","isLayout","isLayoutNode","dataPath","childEntries","isField","isDataField","jsxs","jsx","e","Tag","Typography","Button","NexusField","isGridNode","isFlexNode","containerStyle","gridContextValue","column","gap","direction","flexAlign","flexJustify","flexWrap","innerContent","Fragment","childKey","childNode","childPathKey","childIsSelected","childDropTargetType","dropTargetPathKey","childDiv","GridContext","prev","next","Canvas","selectedPath","mode","selectNode","addNode","removeNode","setSchema","registerUI","useDesigner","designForm","useForm","previewForm","designEngine","previewEngine","setDropTarget","useState","previewResult","setPreviewResult","useEffect","currentData","formConfig","handleDragEnd","getParentProps","useCallback","handleDrop","data","resolved","moveNodeInSchema","toProps","paneKey","removeNodeFromSchema","result","sameParent","insertIndex","fromIndex","base","fixedKey","fd","found","factory","nextParentProps","newKey","fullNewPath","handleNodeDragStart","handleNodeDragOver","newTarget","handleNodeDrop","handleDelete","handleSelect","handleReorder","keys","idx","handleContainerDragOver","handleContainerDrop","NexusForm","Space","values","Modal","rootEntries","NexusFormProvider","Empty"],"mappings":"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"}
1
+ {"version":3,"file":"Canvas.js","sources":["../../src/Canvas.tsx"],"sourcesContent":["// ============================================================================\n// @xbeeant/form-engine-designer — 中间画布面板\n// ============================================================================\n\nimport type { NexusSchema, SchemaNode } from '@xbeeant/form-engine';\nimport { isDataField, isLayoutNode } from '@xbeeant/form-engine';\nimport {\n GridContext,\n NexusField,\n NexusForm,\n type NexusFormConfig,\n NexusFormProvider,\n useForm,\n} from '@xbeeant/form-engine-react';\nimport { Button, Empty, Modal, Space, Tag, Typography } from 'antd';\nimport type React from 'react';\nimport { memo, useCallback, useEffect, useMemo, useState } from 'react';\nimport { useDesigner } from './DesignerContext';\nimport {\n generateKey,\n getNodeAtProperties,\n getNodeLabel,\n getPropertiesOf,\n moveNodeInSchema,\n removeNodeFromSchema,\n} from './schemaUtils';\nimport type { CatalogItem, FieldDef } from './types';\n\n// ── 拖拽数据载荷 ────────────────────────────────────────────────────────────\ninterface PaletteDragPayload {\n source: 'palette';\n catalogItem: CatalogItem;\n}\ninterface FieldDefDragPayload {\n source: 'fieldDef';\n fieldDef: FieldDef;\n}\ninterface CanvasDragPayload {\n source: 'canvas';\n fromPath: string[];\n}\ntype DragPayload = PaletteDragPayload | FieldDefDragPayload | CanvasDragPayload;\n\nconst DRAG_MIME = 'application/json';\n\n// ── Drop 目标类型 ───────────────────────────────────────────────────────────\ntype DropTarget =\n | { type: 'inside'; path: string[] } // 拖入容器内部(追加到末尾)\n | { type: 'before'; path: string[] } // 插入到某节点之前\n | { type: 'after'; path: string[] } // 插入到某节点之后\n | null;\n\nfunction pathEquals(a: string[] | null, b: string[]): boolean {\n if (!a) {\n return false;\n }\n if (a.length !== b.length) {\n return false;\n }\n return a.every((seg, i) => seg === b[i]);\n}\n\nfunction dropTargetEquals(a: DropTarget, b: DropTarget): boolean {\n if (a === null && b === null) {\n return true;\n }\n if (a === null || b === null) {\n return false;\n }\n return a.type === b.type && pathEquals(a.path, b.path);\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// 面板节点(tabPane / collapsePanel / step)与容器类型的映射\n// 面板只能放入对应的 tabs / collapse / steps 容器(否则渲染结构非法);\n// 普通节点直接拖入这些容器时自动包裹成新面板,保证运行时渲染结构合法。\n// ────────────────────────────────────────────────────────────────────────────\n\n/** 面板类型 → 唯一允许的父容器类型 */\nconst PANE_PARENT_TYPE: Record<string, string> = {\n tabPane: 'tabs',\n collapsePanel: 'collapse',\n step: 'steps',\n};\n\n/** 容器类型 → 默认面板类型 */\nconst CONTAINER_PANE_TYPE: Record<string, string> = {\n tabs: 'tabPane',\n collapse: 'collapsePanel',\n steps: 'step',\n};\n\n/** 面板默认标题 */\nconst PANE_DEFAULT_TITLE: Record<string, string> = {\n tabPane: '标签页',\n collapsePanel: '折叠面板',\n step: '步骤',\n};\n\n/** 获取路径终点节点的容器类型(根路径返回 undefined) */\nfunction getContainerTypeAt(\n schema: NexusSchema,\n path: string[],\n): string | undefined {\n if (path.length === 0) {\n return undefined;\n }\n const node = getNodeAtProperties(schema.properties, path);\n return node ? (node.type as string) : undefined;\n}\n\n/**\n * 解析一次「新增节点」插入所需的节点构造器:\n * - 面板节点(tabPane/collapsePanel/step):仅当目标父级是对应容器时放行,否则拒绝\n * - 普通节点拖入 tabs/collapse/steps 容器:自动包裹成新面板\n * - 其余情况:原样返回\n *\n * @param innerKey 外部字段拖入时使用的固定 key(作为包裹面板内部字段的 key)\n * @returns 插入用构造器;返回 null 表示本次插入被拒绝\n */\nfunction resolveInsertFactory(\n schema: NexusSchema,\n toParentPath: string[],\n createNode: () => SchemaNode,\n nodeType: string,\n innerKey?: string,\n): (() => SchemaNode) | null {\n const parentType = getContainerTypeAt(schema, toParentPath);\n\n const requiredParent = PANE_PARENT_TYPE[nodeType];\n if (requiredParent) {\n return parentType === requiredParent ? createNode : null;\n }\n\n const paneType = parentType ? CONTAINER_PANE_TYPE[parentType] : undefined;\n if (paneType) {\n return () =>\n ({\n type: paneType,\n title: PANE_DEFAULT_TITLE[paneType],\n properties: {\n [innerKey ?? generateKey({}, nodeType)]: createNode(),\n },\n }) as unknown as SchemaNode;\n }\n\n return createNode;\n}\n\n/**\n * 解析一次「移动已有节点」的落点:\n * - 移动面板节点:仅允许放入对应容器(否则返回 null)\n * - 普通节点移入 tabs/collapse/steps 容器:包裹成新面板\n *\n * @returns wrapped 为 true 时 node 是新建的包裹面板,需删除原节点\n */\nfunction resolveMoveNode(\n schema: NexusSchema,\n fromPath: string[],\n toParentPath: string[],\n): { node: SchemaNode; wrapped: boolean } | null {\n const node = getNodeAtProperties(schema.properties, fromPath);\n if (!node) {\n return null;\n }\n const parentType = getContainerTypeAt(schema, toParentPath);\n const nodeType = node.type as string;\n\n const requiredParent = PANE_PARENT_TYPE[nodeType];\n if (requiredParent) {\n return parentType === requiredParent ? { node, wrapped: false } : null;\n }\n\n const paneType = parentType ? CONTAINER_PANE_TYPE[parentType] : undefined;\n if (paneType) {\n return {\n wrapped: true,\n node: {\n type: paneType,\n title: PANE_DEFAULT_TITLE[paneType],\n properties: {\n [fromPath[fromPath.length - 1]]: node,\n },\n } as unknown as SchemaNode,\n };\n }\n\n return { node, wrapped: false };\n}\n\n// 判断 targetPath 是否是 fromPath 自身或其后代\nfunction isDescendantOrSelf(fromPath: string[], targetPath: string[]): boolean {\n if (fromPath.length <= targetPath.length) {\n return targetPath\n .slice(0, fromPath.length)\n .every((seg, i) => seg === fromPath[i]);\n }\n return false;\n}\n\n// 判断是否允许拖入(纯函数:不依赖组件作用域)\nfunction canDrop(fromPath: string[], targetPath: string[]): boolean {\n if (isDescendantOrSelf(fromPath, targetPath)) {\n return false;\n }\n const fromParent = fromPath.slice(0, -1);\n return !(\n fromParent.length === targetPath.length &&\n fromParent.every((seg, i) => seg === targetPath[i])\n );\n}\n\n// 计算 insertIndex:将节点移动/新增到目标位置(纯函数:不依赖组件作用域)\nfunction computeInsertIndex(\n target: DropTarget,\n schemaProps: Record<string, SchemaNode>,\n): { toParentPath: string[]; insertIndex: number } | null {\n if (!target || target.type === 'inside') {\n return null;\n }\n\n const nodeIndex = getIndexInParent(schemaProps, target.path);\n if (nodeIndex === -1) {\n return null;\n }\n\n const toParentPath = target.path.slice(0, -1);\n\n if (target.type === 'before') {\n return { toParentPath, insertIndex: nodeIndex };\n } else {\n // after\n return { toParentPath, insertIndex: nodeIndex + 1 };\n }\n}\n\nfunction resolveCatalogItem(\n payload: CatalogItem,\n widgetCatalog: CatalogItem[],\n layoutCatalog: CatalogItem[],\n): CatalogItem | undefined {\n if (payload.category === 'widget') {\n return widgetCatalog.find((c) => c.widget === payload.widget);\n }\n return layoutCatalog.find((c) => c.layoutType === payload.layoutType);\n}\n\n// 根据 widget 名推断 schema type(用于外部字段拖入时构造节点)\nfunction inferSchemaType(widget: string): string {\n if (['checkbox', 'switch'].includes(widget)) {\n return 'boolean';\n }\n if (['number', 'slider'].includes(widget)) {\n return 'number';\n }\n if (['checkboxes', 'multiSelect'].includes(widget)) {\n return 'array';\n }\n if (widget === 'object') {\n return 'object';\n }\n return 'string';\n}\n\n// 获取节点在其父级中的 index\nfunction getIndexInParent(\n schemaProps: Record<string, SchemaNode>,\n path: string[],\n): number {\n const parentPath = path.slice(0, -1);\n const key = path[path.length - 1];\n const parentProps =\n parentPath.length === 0\n ? schemaProps\n : getNodeAtProperties(schemaProps, parentPath) &&\n getPropertiesOf(getNodeAtProperties(schemaProps, parentPath)!);\n if (!parentProps) {\n return -1;\n }\n return Object.keys(parentProps).indexOf(key);\n}\n\n// 与 getParentProps 相同,但作用于指定 schema(用于在副本上定位 properties)\nfunction getPropsAtPath(\n targetSchema: NexusSchema,\n parentPath: string[],\n): Record<string, SchemaNode> | undefined {\n if (parentPath.length === 0) {\n return targetSchema.properties;\n }\n const parent = getNodeAtProperties(targetSchema.properties, parentPath);\n return parent ? getPropertiesOf(parent) : undefined;\n}\n\n// 从事件中计算 drop 目标(避免状态延迟)\nfunction computeDropTargetFromEvent(\n e: React.DragEvent,\n path: string[],\n): DropTarget {\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const y = e.clientY - rect.top;\n const type: 'before' | 'after' = y < rect.height / 2 ? 'before' : 'after';\n return { type, path };\n}\n\n/** 路径数组 → 稳定字符串 key(JSON 序列化,任意 key 内容均安全) */\nfunction toPathKey(path: string[]): string {\n return JSON.stringify(path);\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// CanvasActions — 下发给 CanvasNode 的回调集合\n// 全部 useCallback 稳定化:schema/catalog 未变时引用不变,\n// 配合 React.memo 让拖拽热路径(dragOver → setDropTarget)只重渲染受影响节点\n// ────────────────────────────────────────────────────────────────────────────\n\ninterface CanvasActions {\n onSelect: (path: string[]) => void;\n onDelete: (path: string[]) => void;\n onReorder: (path: string[], direction: 'up' | 'down') => void;\n onDragStart: (e: React.DragEvent, path: string[]) => void;\n onDragOver: (e: React.DragEvent, path: string[]) => void;\n onNodeDrop: (e: React.DragEvent, path: string[]) => void;\n onContainerDragOver: (e: React.DragEvent) => void;\n onContainerDrop: (e: React.DragEvent, path: string[]) => void;\n}\n\ninterface CanvasNodeProps {\n node: SchemaNode;\n /** 节点在 schema 中的路径 key(JSON 字符串,跨渲染引用稳定) */\n pathKey: string;\n depth: number;\n /** 祖先数据路径(布局节点 key 不进入,与 SchemaParser 对齐) */\n parentDataPath: string;\n /** 父级计算好的派生值:仅本节点相关(boolean/string,参与 memo 比较) */\n isSelected: boolean;\n dropTargetType: 'before' | 'after' | null;\n /** 原始状态透传(供本节点计算其子节点的派生值;不参与 memo 比较) */\n selectedPathKey: string | null;\n dropTarget: DropTarget;\n actions: CanvasActions;\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// CanvasNode — 单个节点的递归渲染(memo 化,自定义比较器)\n// 比较器只对比派生值(isSelected / dropTargetType)与稳定引用(node / pathKey /\n// depth / parentDataPath / actions):拖拽过程中只有 drop 目标节点与选中节点\n// 的派生值变化 → 其余子树整体跳过重渲染,热路径从 O(N) 降为 O(1)\n// ────────────────────────────────────────────────────────────────────────────\n\nconst CanvasNode = memo(\n function CanvasNode({\n node,\n pathKey,\n depth,\n parentDataPath,\n isSelected,\n dropTargetType,\n selectedPathKey,\n dropTarget,\n actions,\n }: CanvasNodeProps) {\n const path = useMemo(() => JSON.parse(pathKey) as string[], [pathKey]);\n const childProps = getPropertiesOf(node);\n const hasChildren = childProps !== undefined;\n const label = getNodeLabel(node, path[path.length - 1]);\n const badge = node.widget || node.type;\n // 计算数据路径:布局节点 key 不进入数据路径(与 SchemaParser 对齐)\n const isLayout = isLayoutNode(node);\n const dataPath = isLayout\n ? parentDataPath\n : parentDataPath\n ? `${parentDataPath}.${path[path.length - 1]}`\n : path[path.length - 1];\n const childEntries = childProps ? Object.entries(childProps) : [];\n const isField = isDataField(node);\n\n return (\n <div\n key={pathKey}\n className='mb-1.5 relative'\n style={{ marginLeft: depth }}\n >\n {/* before 插入指示线 — 显示在容器上方 */}\n {dropTargetType === 'before' && (\n <div className='drop-indicator-line relative h-1 pointer-events-none z-10 -mt-0.5' />\n )}\n\n {/* 统一包裹容器:header + 预览/子节点 */}\n <div\n className={`relative rounded border bg-white transition-all ${\n isSelected\n ? 'border-[#1677ff] bg-[#e6f4ff] shadow-[0_0_0_2px_rgba(22,119,255,0.1)]'\n : 'border-[#e8e8e8] hover:border-[#1677ff]'\n }`}\n >\n {/* header 行:拖拽 + 信息 + 操作 */}\n <div\n className='flex items-center gap-1.5 px-2 py-1.5 cursor-grab'\n draggable\n onDragStart={(e) => actions.onDragStart(e, path)}\n onDragOver={(e) => actions.onDragOver(e, path)}\n onDragLeave={(e) => {\n e.stopPropagation();\n }}\n onDrop={(e) => actions.onNodeDrop(e, path)}\n onClick={(e) => {\n e.stopPropagation();\n actions.onSelect(path);\n }}\n >\n <Tag\n color={hasChildren || isLayout ? 'blue' : undefined}\n className='m-0! shrink-0'\n >\n {badge}\n </Tag>\n <Typography.Text className='flex-1 overflow-hidden text-ellipsis whitespace-nowrap'>\n {label}\n </Typography.Text>\n <Typography.Text className='text-[#bfbfbf] text-[11px] font-mono shrink-0'>\n {path[path.length - 1]}\n </Typography.Text>\n {isSelected && (\n <span className='inline-flex gap-1'>\n <Button\n size='small'\n onClick={(e) => {\n e.stopPropagation();\n actions.onReorder(path, 'up');\n }}\n >\n ↑\n </Button>\n <Button\n size='small'\n onClick={(e) => {\n e.stopPropagation();\n actions.onReorder(path, 'down');\n }}\n >\n ↓\n </Button>\n <Button\n size='small'\n danger\n onClick={(e) => {\n e.stopPropagation();\n actions.onDelete(path);\n }}\n >\n ×\n </Button>\n </span>\n )}\n </div>\n\n {/* 字段节点:通过 NexusField 渲染,复用引擎 reaction/联动 */}\n {isField && (\n <div className='px-2 pb-2'>\n <NexusField\n dataPath={dataPath}\n layoutKey={path[path.length - 1]}\n />\n </div>\n )}\n\n {/* 有子节点的容器:显示子节点 */}\n {!isField &&\n hasChildren &&\n (() => {\n const isGridNode = node.type === 'grid';\n const isFlexNode = node.type === 'flex';\n\n // 根据布局类型构建容器 CSS 样式\n let containerStyle: React.CSSProperties | undefined;\n let gridContextValue: { column: number } | null = null;\n\n if (isGridNode) {\n const column = Math.max(1, (node as any).column ?? 2);\n const gap = (node as any).gap ?? 12;\n containerStyle = {\n display: 'grid',\n gridTemplateColumns: `repeat(${column}, 1fr)`,\n gap: `${gap}px`,\n };\n gridContextValue = { column };\n } else if (isFlexNode) {\n const gap = (node as any).gap ?? 8;\n const direction = (node as any).direction ?? 'row';\n const flexAlign = (node as any).align ?? 'flex-start';\n const flexJustify = (node as any).justify ?? 'flex-start';\n const flexWrap = (node as any).wrap ?? false;\n containerStyle = {\n display: 'flex',\n flexDirection: direction === 'column' ? 'column' : 'row',\n alignItems: flexAlign,\n justifyContent: flexJustify,\n flexWrap: flexWrap ? 'wrap' : 'nowrap',\n gap: `${gap}px`,\n };\n }\n\n const innerContent = (\n <>\n {childEntries.map(([childKey, childNode]) => {\n const childPathKey = toPathKey([...path, childKey]);\n const childIsSelected = selectedPathKey === childPathKey;\n const childDropTargetType =\n dropTarget &&\n (dropTarget.type === 'before' ||\n dropTarget.type === 'after') &&\n dropTargetPathKey(dropTarget) === childPathKey\n ? dropTarget.type\n : null;\n return (\n <CanvasNode\n key={childPathKey}\n node={childNode}\n pathKey={childPathKey}\n depth={depth + 1}\n parentDataPath={dataPath}\n isSelected={childIsSelected}\n dropTargetType={childDropTargetType}\n selectedPathKey={selectedPathKey}\n dropTarget={dropTarget}\n actions={actions}\n />\n );\n })}\n {childEntries.length === 0 && (\n <div className='text-[#bfbfbf] text-xs text-center py-2'>\n 拖拽组件到此处\n </div>\n )}\n </>\n );\n\n const childDiv = (\n <div\n className='mx-2 mb-2 p-2 border border-dashed rounded min-h-8 bg-[rgba(250,250,250,0.6)] border-[#d9d9d9]'\n style={containerStyle}\n onClick={(e) => {\n e.stopPropagation();\n }}\n onDragOver={actions.onContainerDragOver}\n onDrop={(e) => actions.onContainerDrop(e, path)}\n >\n {innerContent}\n </div>\n );\n\n // grid 需要提供 GridContext 给子项中的 NexusField 解析 colSpan\n if (gridContextValue) {\n return (\n <GridContext.Provider value={gridContextValue}>\n {childDiv}\n </GridContext.Provider>\n );\n }\n\n return childDiv;\n })()}\n </div>\n\n {/* after 插入指示线 */}\n {dropTargetType === 'after' && (\n <div className='drop-indicator-line relative h-1 pointer-events-none z-10 -mb-0.5' />\n )}\n </div>\n );\n },\n (prev, next) =>\n prev.node === next.node &&\n prev.pathKey === next.pathKey &&\n prev.depth === next.depth &&\n prev.parentDataPath === next.parentDataPath &&\n prev.isSelected === next.isSelected &&\n prev.dropTargetType === next.dropTargetType &&\n prev.actions === next.actions,\n);\n\n/** 取 before/after 类型 drop 目标的路径 key(inside 目标无节点级指示) */\nfunction dropTargetPathKey(target: DropTarget): string | null {\n if (target === null || target.type === 'inside') {\n return null;\n }\n return toPathKey(target.path);\n}\n\nexport function Canvas() {\n const {\n schema,\n selectedPath,\n mode,\n selectNode,\n addNode,\n removeNode,\n setSchema,\n registerUI,\n widgetCatalog,\n layoutCatalog,\n } = useDesigner();\n // 设计/预览各持有一个独立的 form 实例(engine):\n // 设计态由下方 effect 手动 init,预览态由 <NexusForm> 内部 init,\n // 二者互不干扰,避免切换模式时 fieldState/data 相互污染。\n const [designForm] = useForm();\n const [previewForm] = useForm();\n const designEngine = designForm._getEngine();\n const previewEngine = previewForm._getEngine();\n const [dropTarget, setDropTarget] = useState<DropTarget>(null);\n const [previewResult, setPreviewResult] = useState<Record<\n string,\n unknown\n > | null>(null);\n\n // 注册 widgets/layouts:仅供引擎消费一次,避免每次渲染重复注册\n // registerUI 由使用方传入(如 registerAntdUI),解耦对具体 UI 库的依赖\n useEffect(() => {\n registerUI?.(designEngine);\n registerUI?.(previewEngine);\n }, [registerUI, designEngine, previewEngine]);\n\n // 编辑模式下初始化引擎,使 NexusField 能读取 fieldState 并触发 reactions(联动)\n // 预览模式由 <NexusForm> 内部负责 engine.init\n useEffect(() => {\n if (mode === 'preview') {\n return;\n }\n const currentData = designEngine.getFormData();\n designEngine.init(\n schema,\n Object.keys(currentData).length > 0 ? currentData : undefined,\n );\n }, [designEngine, schema, mode]);\n\n const formConfig = useMemo<NexusFormConfig>(\n () => ({\n displayType: schema.displayType ?? 'row',\n labelWidth: schema.labelWidth,\n colon: schema.colon,\n label: schema.label ?? true,\n readOnly: schema.readOnly ?? false,\n column: schema.column,\n }),\n [schema],\n );\n\n useEffect(() => {\n const handleDragEnd = () => setDropTarget(null);\n window.addEventListener('dragend', handleDragEnd);\n return () => window.removeEventListener('dragend', handleDragEnd);\n }, []);\n\n const getParentProps = useCallback(\n (parentPath: string[]) => {\n if (parentPath.length === 0) {\n return schema.properties;\n }\n const parent = getNodeAtProperties(schema.properties, parentPath);\n return parent ? getPropertiesOf(parent) : undefined;\n },\n [schema],\n );\n\n // 统一处理 drop(依赖 schema,schema 变化时重建;拖拽过程中保持稳定)\n const handleDrop = useCallback(\n (e: React.DragEvent, target: DropTarget) => {\n e.preventDefault();\n e.stopPropagation();\n setDropTarget(null);\n if (!target) {\n return;\n }\n\n const data = e.dataTransfer.getData(DRAG_MIME);\n if (!data) {\n return;\n }\n let payload: DragPayload;\n try {\n payload = JSON.parse(data) as DragPayload;\n } catch {\n return;\n }\n\n // ── 情况一:从画布拖动已有节点 ──\n if (payload.source === 'canvas') {\n const fromPath = payload.fromPath;\n\n if (target.type === 'inside') {\n // 拖入容器内部\n if (!canDrop(fromPath, target.path)) {\n return;\n }\n // 面板节点仅入对应容器;普通节点进 tabs/collapse/steps 时自动包裹\n const resolved = resolveMoveNode(schema, fromPath, target.path);\n if (!resolved) {\n return;\n }\n if (!resolved.wrapped) {\n setSchema(moveNodeInSchema(schema, fromPath, target.path));\n } else {\n let next = structuredClone(schema) as NexusSchema;\n const toProps = getPropsAtPath(next, target.path);\n if (!toProps) {\n return;\n }\n const paneKey = generateKey(toProps, 'panel');\n toProps[paneKey] = resolved.node;\n next = removeNodeFromSchema(next, fromPath);\n setSchema(next);\n }\n selectNode(null);\n return;\n }\n\n // before / after\n if (!canDrop(fromPath, target.path)) {\n return;\n }\n const result = computeInsertIndex(target, schema.properties);\n if (!result) {\n return;\n }\n\n // 同父级移动时调整 insertIndex\n const fromParent = fromPath.slice(0, -1);\n const sameParent =\n fromParent.length === result.toParentPath.length &&\n fromParent.every((seg, i) => seg === result.toParentPath[i]);\n\n let insertIndex = result.insertIndex;\n if (sameParent) {\n const fromIndex = getIndexInParent(schema.properties, fromPath);\n if (fromIndex !== -1 && fromIndex < insertIndex) {\n insertIndex -= 1;\n }\n }\n\n const resolved = resolveMoveNode(schema, fromPath, result.toParentPath);\n if (!resolved) {\n return;\n }\n if (!resolved.wrapped) {\n setSchema(\n moveNodeInSchema(\n schema,\n fromPath,\n result.toParentPath,\n insertIndex,\n ),\n );\n } else {\n let next = structuredClone(schema) as NexusSchema;\n const toProps = getPropsAtPath(next, result.toParentPath);\n if (!toProps) {\n return;\n }\n const paneKey = generateKey(toProps, 'panel');\n toProps[paneKey] = resolved.node;\n next = removeNodeFromSchema(next, fromPath);\n // 将包裹面板移动到目标插入位置\n setSchema(\n moveNodeInSchema(\n next,\n [...result.toParentPath, paneKey],\n result.toParentPath,\n insertIndex,\n ),\n );\n }\n selectNode(null);\n return;\n }\n\n // ── 情况二:从 palette 或 fieldDef 拖入新组件 ──\n let base: string;\n let createNode: () => SchemaNode;\n let fixedKey: string | undefined;\n\n if (payload.source === 'fieldDef') {\n // 外部字段:id 作为 key,name 作为 title,且不允许修改\n const fd = payload.fieldDef;\n base = fd.widget;\n fixedKey = fd.id;\n createNode = () =>\n ({\n type: inferSchemaType(fd.widget),\n widget: fd.widget,\n title: fd.name,\n // 锁定标记:禁止在设计器中修改 key 和 title\n _lockedKey: true,\n _lockedTitle: true,\n }) as unknown as SchemaNode;\n } else {\n // palette 组件目录\n const found = resolveCatalogItem(\n payload.catalogItem,\n widgetCatalog,\n layoutCatalog,\n );\n if (!found) {\n return;\n }\n base = found.widget || found.layoutType || 'field';\n createNode = () => found.createNode() as unknown as SchemaNode;\n }\n\n if (target.type === 'inside') {\n const parentProps = getParentProps(target.path);\n if (!parentProps) {\n return;\n }\n // 面板类型校验 / 普通节点进面板容器时自动包裹\n const factory = resolveInsertFactory(\n schema,\n target.path,\n createNode,\n base,\n fixedKey,\n );\n if (!factory) {\n return;\n }\n const key = fixedKey ?? generateKey(parentProps, base);\n // 若 fixedKey 已存在,则跳过\n if (fixedKey && key in parentProps) {\n return;\n }\n addNode(target.path, key, factory());\n return;\n }\n\n // before / after\n const result = computeInsertIndex(target, schema.properties);\n if (!result) {\n return;\n }\n // 面板类型校验 / 普通节点进面板容器时自动包裹\n const factory = resolveInsertFactory(\n schema,\n result.toParentPath,\n createNode,\n base,\n fixedKey,\n );\n if (!factory) {\n return;\n }\n\n // 在副本上操作:先 add 再 move\n const next = structuredClone(schema) as NexusSchema;\n const nextParentProps = getPropsAtPath(next, result.toParentPath);\n if (!nextParentProps) {\n return;\n }\n\n const newKey = fixedKey ?? generateKey(nextParentProps, base);\n if (fixedKey && newKey in nextParentProps) {\n return;\n }\n nextParentProps[newKey] = factory();\n\n const fullNewPath = [...result.toParentPath, newKey];\n setSchema(\n moveNodeInSchema(\n next,\n fullNewPath,\n result.toParentPath,\n result.insertIndex,\n ),\n );\n },\n [\n schema,\n widgetCatalog,\n layoutCatalog,\n addNode,\n getParentProps,\n setSchema,\n selectNode,\n ],\n );\n\n // 节点 header 拖拽源 + drop 目标(仅依赖 setDropTarget,拖拽过程中引用稳定)\n const handleNodeDragStart = useCallback(\n (e: React.DragEvent, path: string[]) => {\n e.stopPropagation();\n const payload: CanvasDragPayload = { source: 'canvas', fromPath: path };\n e.dataTransfer.setData(DRAG_MIME, JSON.stringify(payload));\n e.dataTransfer.effectAllowed = 'move';\n },\n [],\n );\n\n // 基于鼠标 Y 坐标判断 before/after(仅依赖 setDropTarget,引用稳定)\n const handleNodeDragOver = useCallback(\n (e: React.DragEvent, path: string[]) => {\n e.preventDefault();\n e.stopPropagation();\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const y = e.clientY - rect.top;\n const type: 'before' | 'after' = y < rect.height / 2 ? 'before' : 'after';\n const newTarget: DropTarget = { type, path };\n // 根据 effectAllowed 设置 dropEffect,避免 palette(copy) 与 canvas(move) 互斥\n e.dataTransfer.dropEffect =\n e.dataTransfer.effectAllowed === 'copy' ? 'copy' : 'move';\n setDropTarget((prev) => {\n if (dropTargetEquals(prev, newTarget)) {\n return prev;\n }\n return newTarget;\n });\n },\n [],\n );\n\n const handleNodeDrop = useCallback(\n (e: React.DragEvent, path: string[]) => {\n e.stopPropagation();\n const target = computeDropTargetFromEvent(e, path);\n handleDrop(e, target);\n },\n [handleDrop],\n );\n\n const handleDelete = useCallback(\n (path: string[]) => {\n removeNode(path);\n },\n [removeNode],\n );\n\n const handleSelect = useCallback(\n (path: string[]) => {\n selectNode(path);\n },\n [selectNode],\n );\n\n const handleReorder = useCallback(\n (path: string[], direction: 'up' | 'down') => {\n const parentPath = path.slice(0, -1);\n const key = path[path.length - 1];\n const parentProps = getParentProps(parentPath);\n if (!parentProps) {\n return;\n }\n const keys = Object.keys(parentProps);\n const idx = keys.indexOf(key);\n if (idx < 0) {\n return;\n }\n if (direction === 'up' && idx === 0) {\n return;\n }\n if (direction === 'down' && idx === keys.length - 1) {\n return;\n }\n const insertIndex = direction === 'up' ? idx - 1 : idx + 1;\n setSchema(moveNodeInSchema(schema, path, parentPath, insertIndex));\n selectNode(path);\n },\n [getParentProps, schema, setSchema, selectNode],\n );\n\n // 容器空白区 dragOver:清除节点上的 drop target 指示\n const handleContainerDragOver = useCallback((e: React.DragEvent) => {\n e.preventDefault();\n e.dataTransfer.dropEffect =\n e.dataTransfer.effectAllowed === 'copy' ? 'copy' : 'move';\n setDropTarget((prev) => {\n if (prev === null) {\n return prev;\n }\n return null;\n });\n }, []);\n\n const handleContainerDrop = useCallback(\n (e: React.DragEvent, path: string[]) => {\n e.stopPropagation();\n handleDrop(e, { type: 'inside', path });\n },\n [handleDrop],\n );\n\n // 下发给 CanvasNode 的稳定回调集合:\n // 拖拽过程(dropTarget 变化)中所有回调引用不变 → 子节点 memo 生效\n const actions = useMemo<CanvasActions>(\n () => ({\n onSelect: handleSelect,\n onDelete: handleDelete,\n onReorder: handleReorder,\n onDragStart: handleNodeDragStart,\n onDragOver: handleNodeDragOver,\n onNodeDrop: handleNodeDrop,\n onContainerDragOver: handleContainerDragOver,\n onContainerDrop: handleContainerDrop,\n }),\n [\n handleSelect,\n handleDelete,\n handleReorder,\n handleNodeDragStart,\n handleNodeDragOver,\n handleNodeDrop,\n handleContainerDragOver,\n handleContainerDrop,\n ],\n );\n\n if (mode === 'preview') {\n return (\n <div className='flex-1 overflow-y-auto p-4 bg-[#f5f5f5] min-h-full border border-transparent box-border'>\n <NexusForm form={previewForm} schema={schema} />\n <div style={{ marginTop: 16, textAlign: 'center' }}>\n <Space>\n <Button\n type='primary'\n onClick={async () => {\n try {\n const errors = await previewForm.validateFields();\n if (errors.size > 0) {\n return;\n }\n const values = previewForm.getValues();\n setPreviewResult(values);\n } catch {\n // 校验失败,不弹窗\n }\n }}\n >\n 提交\n </Button>\n <Button onClick={() => previewForm.resetFields()}>重置</Button>\n </Space>\n </div>\n <Modal\n title='表单数据'\n open={previewResult !== null}\n onCancel={() => setPreviewResult(null)}\n footer={[\n <Button key='close' onClick={() => setPreviewResult(null)}>\n 关闭\n </Button>,\n ]}\n width={600}\n >\n <pre\n style={{\n maxHeight: 400,\n overflow: 'auto',\n background: '#f5f5f5',\n padding: 12,\n borderRadius: 6,\n fontSize: 13,\n margin: 0,\n }}\n >\n {JSON.stringify(previewResult, null, 2)}\n </pre>\n </Modal>\n </div>\n );\n }\n\n const rootEntries = Object.entries(schema.properties);\n\n return (\n <NexusFormProvider\n form={designForm}\n engine={designEngine}\n config={formConfig}\n >\n <div\n className='flex-1 overflow-y-auto p-4 bg-[#f5f5f5] min-h-full border border-transparent box-border'\n onClick={() => selectNode(null)}\n onDragOver={handleContainerDragOver}\n onDrop={(e) => handleContainerDrop(e, [])}\n >\n <div>\n {rootEntries.map(([key, node]) => (\n <CanvasNode\n key={toPathKey([key])}\n node={node}\n pathKey={toPathKey([key])}\n depth={0}\n parentDataPath=''\n isSelected={pathEquals(selectedPath, [key])}\n dropTargetType={\n dropTarget &&\n (dropTarget.type === 'before' || dropTarget.type === 'after') &&\n pathEquals(dropTarget.path, [key])\n ? dropTarget.type\n : null\n }\n selectedPathKey={selectedPath ? toPathKey(selectedPath) : null}\n dropTarget={dropTarget}\n actions={actions}\n />\n ))}\n {rootEntries.length === 0 && (\n <Empty description='拖拽组件到此处开始设计' />\n )}\n </div>\n </div>\n </NexusFormProvider>\n );\n}\n"],"names":["DRAG_MIME","pathEquals","a","b","seg","i","dropTargetEquals","PANE_PARENT_TYPE","CONTAINER_PANE_TYPE","PANE_DEFAULT_TITLE","getContainerTypeAt","schema","path","node","getNodeAtProperties","resolveInsertFactory","toParentPath","createNode","nodeType","innerKey","parentType","requiredParent","paneType","generateKey","resolveMoveNode","fromPath","isDescendantOrSelf","targetPath","canDrop","fromParent","computeInsertIndex","target","schemaProps","nodeIndex","getIndexInParent","resolveCatalogItem","payload","widgetCatalog","layoutCatalog","c","inferSchemaType","widget","parentPath","key","parentProps","getPropertiesOf","getPropsAtPath","targetSchema","parent","computeDropTargetFromEvent","rect","toPathKey","CanvasNode","memo","pathKey","depth","parentDataPath","isSelected","dropTargetType","selectedPathKey","dropTarget","actions","useMemo","childProps","hasChildren","label","getNodeLabel","badge","isLayout","isLayoutNode","dataPath","childEntries","isField","isDataField","jsxs","jsx","e","Tag","Typography","Button","NexusField","isGridNode","isFlexNode","containerStyle","gridContextValue","column","gap","direction","flexAlign","flexJustify","flexWrap","innerContent","Fragment","childKey","childNode","childPathKey","childIsSelected","childDropTargetType","dropTargetPathKey","childDiv","GridContext","prev","next","Canvas","selectedPath","mode","selectNode","addNode","removeNode","setSchema","registerUI","useDesigner","designForm","useForm","previewForm","designEngine","previewEngine","setDropTarget","useState","previewResult","setPreviewResult","useEffect","currentData","formConfig","handleDragEnd","getParentProps","useCallback","handleDrop","data","resolved","moveNodeInSchema","toProps","paneKey","removeNodeFromSchema","result","sameParent","insertIndex","fromIndex","base","fixedKey","fd","found","factory","nextParentProps","newKey","fullNewPath","handleNodeDragStart","handleNodeDragOver","newTarget","handleNodeDrop","handleDelete","handleSelect","handleReorder","keys","idx","handleContainerDragOver","handleContainerDrop","NexusForm","Space","values","Modal","rootEntries","NexusFormProvider","Empty"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { jsxs as a, jsx as o } from "react/jsx-runtime";
2
+ /* empty css */
2
3
  import { NexusForm as S } from "./react/src/components/NexusForm.js";
3
4
  import { useForm as V } from "./react/src/hooks/useForm.js";
4
5
  import { registerAntdUI as W } from "@xbeeant/form-engine-ui";
@@ -134,7 +135,7 @@ function Q({ oldKey: n, locked: e, onRename: r }) {
134
135
  /* @__PURE__ */ o("div", { className: "mt-1 text-[11px] text-[#c0c4cc]", children: "用于数据路径与联动引用,修改后自动迁移子节点" })
135
136
  ] });
136
137
  }
137
- function ce() {
138
+ function ae() {
138
139
  const {
139
140
  schema: n,
140
141
  selectedPath: e,
@@ -289,6 +290,6 @@ function ce() {
289
290
  ] });
290
291
  }
291
292
  export {
292
- ce as PropertyPanel
293
+ ae as PropertyPanel
293
294
  };
294
295
  //# sourceMappingURL=PropertyPanel.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"PropertyPanel.js","sources":["../../src/PropertyPanel.tsx"],"sourcesContent":["// ============================================================================\n// @xbeeant/form-engine-designer — 右侧属性配置面板\n// 属性定义采用「描述符驱动」:\n// - 组件(widget)属性来自外部传入的 propertySchemaMap(key 为 widget 名,\n// 值为该组件的属性字段定义,示例见 @xbeeant/form-engine-ui/src/schema/*-schema.ts)\n// - 通用 / 校验 / 依赖分区在 ./property/basic-property.ts 中定义\n// - 布局节点与表单级属性在下方 formLevelProps / layoutBasicProps 内联定义\n//\n// 编辑流程(与 schemaUtils 的读/写通路对应):\n// flattenNodeForPropertyEditor → 节点 → 扁平 initialValues(读)\n// updateNodeWithNesting → 扁平 patch → 节点(写,split schema级/props级)\n// PropertyForm 通过 NexusForm 渲染 propertySchema 描述符驱动的表单\n// ============================================================================\n\nimport type { NexusSchema, SchemaNode } from '@xbeeant/form-engine';\nimport { NexusForm, useForm } from '@xbeeant/form-engine-react';\nimport { registerAntdUI } from '@xbeeant/form-engine-ui';\nimport { Input } from 'antd';\nimport { useCallback, useMemo, useRef, useState } from 'react';\nimport { useDesigner } from './DesignerContext';\nimport {\n commonPropertyFields,\n dependencyPropertyFields,\n reactionPropertyFields,\n validationPropertyFields,\n} from './property/basic-property.ts';\nimport {\n diffPropertyPatch,\n extractFormLevelConfig,\n flattenNodeForPropertyEditor,\n getNodeAtProperties,\n} from './schemaUtils';\nimport { propertyWidgets } from './widgets';\n\n// ────────────────────────────────────────────────────────────────────────────\n// PropertyForm — 属性表单容器\n// Designer 的自定义属性编辑器独立于 form-engine 的渲染系统\n// ────────────────────────────────────────────────────────────────────────────\n\ninterface PropertyFormProps {\n schema: NexusSchema;\n initialValues: Record<string, unknown>;\n onValuesChange: (\n allValues: Record<string, unknown>,\n changedFields: ReadonlySet<string>,\n ) => void;\n}\n\nfunction PropertyForm({\n schema,\n initialValues,\n onValuesChange,\n}: PropertyFormProps) {\n const [form] = useForm();\n const engine = form._getEngine();\n\n // 注册 antd 基础 widget(select/input/switch/number/textarea/collapse/collapsePanel)\n registerAntdUI(engine);\n // 记录本表单实例中用户实际改动过的字段(组件随 formKey 重建,节点切换时自动重置)。\n // 用于区分「未触碰的字符串默认值 ''」与「用户主动清空」——\n // 后者需要回写 schema(删除属性),前者写回会污染 schema(如 bind:'' 导致数据 key 丢失)。\n const changedFieldsRef = useRef<Set<string>>(new Set());\n // '#' 全局 watcher 由 FormController._onFieldValueChange 调用,\n // 前两个参数为 (globalData, globalData),第三参为本次实际变更的字段路径\n const handleWatch = useCallback(\n (value: unknown, _allValues: unknown, changedPath?: string) => {\n if (changedPath) {\n changedFieldsRef.current.add(changedPath);\n }\n onValuesChange(\n value as Record<string, unknown>,\n changedFieldsRef.current,\n );\n },\n [onValuesChange],\n );\n\n return (\n <NexusForm\n footer={false}\n form={form}\n schema={schema}\n initialValues={initialValues}\n watch={{ '#': handleWatch }}\n widgets={propertyWidgets}\n />\n );\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// 表单级属性(未选中节点时编辑 NexusSchema 顶层配置)\n// ────────────────────────────────────────────────────────────────────────────\n\nconst formLevelProps: Record<string, SchemaNode> = {\n displayType: {\n widget: 'select',\n type: 'string',\n title: '表单布局方向(displayType)',\n props: {\n options: [\n { label: '水平(row)', value: 'row' },\n { label: '垂直(column)', value: 'column' },\n { label: '行内(inline)', value: 'inline' },\n ],\n },\n },\n labelWidth: {\n widget: 'input',\n type: 'string',\n title: 'label 宽度(labelWidth)',\n placeholder: '如 120 或 20%',\n },\n colon: {\n widget: 'switch',\n type: 'boolean',\n title: '显示冒号(colon)',\n default: true,\n },\n label: {\n widget: 'switch',\n type: 'boolean',\n title: '显示 label(label)',\n default: true,\n },\n readOnly: {\n widget: 'switch',\n type: 'boolean',\n title: '整个表单只读(readOnly)',\n default: false,\n },\n column: {\n widget: 'number',\n type: 'number',\n title: '每行显示列数(column)',\n default: 1,\n },\n};\n\n// ────────────────────────────────────────────────────────────────────────────\n// 布局节点基础属性(layout nodes 不在 propertySchemaMap 中,单独定义)\n// ────────────────────────────────────────────────────────────────────────────\n\nconst layoutBasicProps: Record<string, SchemaNode> = {\n column: { widget: 'number', type: 'number', title: '列数(column)' },\n gap: { widget: 'number', type: 'number', title: '间距(gap)' },\n direction: {\n widget: 'select',\n type: 'string',\n title: '方向(direction)',\n props: {\n options: [\n { label: '水平', value: 'row' },\n { label: '垂直', value: 'column' },\n ],\n },\n },\n};\n\n// ────────────────────────────────────────────────────────────────────────────\n// collapseSection — 将一组扁平字段包裹成单个 collapse 分区\n// collapse / collapsePanel 均为布局节点,key 不进入数据路径,\n// 因此其内部字段(title / validate / bind 等)会被扁平地暴露给属性表单。\n// ────────────────────────────────────────────────────────────────────────────\n\nfunction collapseSection(\n key: string,\n title: string,\n fields: Record<string, SchemaNode>,\n): Record<string, SchemaNode> {\n // @ts-expect-error\n return {\n [key]: {\n type: 'collapsePanel',\n title,\n properties: fields,\n },\n } as unknown as SchemaNode;\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// KeyEditor — 单独处理 key 的编辑器\n// key 不是 SchemaNode 的属性,而是 properties 的索引键\n// 修改 key = schema 结构级操作:删除旧 key + 添加新 key + 更新选中路径\n// ────────────────────────────────────────────────────────────────────────────\n\ninterface KeyEditorProps {\n oldKey: string;\n locked?: boolean;\n onRename: (newKey: string) => void;\n}\n\nfunction KeyEditor({ oldKey, locked, onRename }: KeyEditorProps) {\n const [value, setValue] = useState(oldKey);\n\n if (locked) {\n return (\n <div className='mb-3 flex items-center justify-between gap-2 rounded-lg border border-[#f0f0f0] bg-[#fafafa] px-3 py-2'>\n <div className='min-w-0'>\n <div className='mb-0.5 text-[11px] text-[#999]'>字段标识(key)</div>\n <code className='break-all font-mono text-[13px] text-[#333]'>\n {oldKey}\n </code>\n </div>\n <span className='shrink-0 rounded bg-[#f0f0f0] px-1.5 py-0.5 text-[11px] text-[#999]'>\n 🔒 锁定\n </span>\n </div>\n );\n }\n\n const onChange = (v: string) => {\n setValue(v);\n onRename(v);\n };\n\n return (\n <div className='mb-3'>\n <div className='mb-1.5 text-[11px] text-[#999]'>字段标识(key)</div>\n <Input\n size='small'\n value={value}\n onChange={(e) => {\n const trimmed = (e.target.value || '').trim();\n onChange(trimmed);\n }}\n autoFocus\n className='nexus-key-input'\n />\n <div className='mt-1 text-[11px] text-[#c0c4cc]'>\n 用于数据路径与联动引用,修改后自动迁移子节点\n </div>\n </div>\n );\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// PropertyPanel — 主组件\n// ────────────────────────────────────────────────────────────────────────────\n\nexport function PropertyPanel() {\n const {\n schema,\n selectedPath,\n updateNode,\n renameNode,\n selectNode,\n setSchema,\n propertySchemaMap,\n } = useDesigner();\n\n const selectedNode =\n selectedPath && selectedPath.length > 0\n ? getNodeAtProperties(schema.properties, selectedPath)\n : undefined;\n\n const isFormLevel = !selectedPath || selectedPath.length === 0;\n\n // 选择变化时强制重建引擎(nodeVersion bump)\n const formKey = `node_${(selectedPath || []).join('_')}_${(selectedNode as { type?: string } | undefined)?.type || 'root'}`;\n\n // key 的特殊性:从 path 最后一段提取,不通过 NexusForm 管理\n const currentKey = selectedPath?.[selectedPath.length - 1] ?? '';\n const keyLocked =\n (selectedNode as unknown as Record<string, unknown> | undefined)\n ?._lockedKey === true;\n\n // 选中节点的 widget/type:决定属性面板使用哪组组件属性;\n // 仅在切换节点(widget/type 改变)时重新计算,避免每次输入都重建 schema\n // (selectedNode 的 object identity 会随每次 edit 变化,不能直接依赖)\n const selectedWidgetKey = selectedNode\n ? (selectedNode.widget as string | undefined) ||\n (selectedNode.type as string)\n : null;\n\n // 构建属性表单 schema:\n // - 未选中节点(form-level):formLevelProps(NexusSchema 顶层配置)\n // - 选中节点:4 个 collapse 分区(通用属性 / 组件属性 / 校验配置 / 依赖配置)\n // collapse 与 collapsePanel 均为布局节点,key 不进入数据路径,\n // 各分区内部字段会被扁平暴露给属性表单。\n // 注意:不依赖 selectedNode 对象本身(每次 edit 都是新引用),\n // 只依赖 isFormLevel 和 selectedWidgetKey,避免无谓 re-init。\n const formSchema = useMemo<NexusSchema>(() => {\n if (isFormLevel) {\n return {\n type: 'object',\n properties: formLevelProps,\n displayType: 'column',\n } as NexusSchema;\n }\n\n const widgetProps =\n propertySchemaMap[selectedWidgetKey as string] || layoutBasicProps;\n\n return {\n type: 'object',\n properties: {\n sectionProperty: {\n widget: 'collapse',\n props: {\n defaultActiveKey: [\n 'sectionCommon',\n 'sectionFieldProps',\n 'sectionValidation',\n 'sectionReaction',\n 'sectionDependency',\n ],\n },\n type: 'collapse',\n properties: {\n ...collapseSection(\n 'sectionCommon',\n '通用属性',\n commonPropertyFields,\n ),\n ...collapseSection(\n 'sectionFieldProps',\n '组件属性',\n widgetProps as Record<string, SchemaNode>,\n ),\n ...collapseSection(\n 'sectionValidation',\n '校验配置',\n validationPropertyFields,\n ),\n ...collapseSection(\n 'sectionReaction',\n '联动配置',\n reactionPropertyFields,\n ),\n ...collapseSection(\n 'sectionDependency',\n '依赖配置',\n dependencyPropertyFields,\n ),\n },\n },\n },\n displayType: 'column',\n } as NexusSchema;\n }, [isFormLevel, selectedWidgetKey, propertySchemaMap]);\n\n // 表单级属性面板的取值来源:只提取 NexusSchema 顶层的表单配置键,\n // 而非整个 schema 对象(schema 含 properties 与嵌套字段,不是表单级配置)\n const formLevelConfig = useMemo<Record<string, unknown>>(\n () =>\n extractFormLevelConfig(\n schema as unknown as Record<string, unknown>,\n Object.keys(formLevelProps),\n ),\n [schema],\n );\n\n const handleValuesChange = useCallback(\n (\n allValues: Record<string, unknown>,\n changedFields: ReadonlySet<string>,\n ) => {\n // 只写回「真正变化」的值:未触碰的空字符串(''/undefined/null)视为未赋值,\n // 不写回 Schema(否则 bind:'' / hidden:'' / required:'' 会导致 key 丢失 / 空联动);\n // 用户主动清空的字段(changedFields 命中)以 undefined 回写,由\n // updateNodeWithNesting 从节点删除对应属性(详见 diffPropertyPatch)\n const initial = selectedNode\n ? flattenNodeForPropertyEditor(\n selectedNode as unknown as Record<string, any>,\n )\n : formLevelConfig;\n\n const patch = diffPropertyPatch(initial, allValues, changedFields);\n if (Object.keys(patch).length === 0) {\n return;\n }\n\n if (!selectedPath || selectedPath.length === 0) {\n // form-level:修改 NexusSchema 顶层属性(undefined 表示清空,删除该键)\n const next = { ...(schema as unknown as Record<string, unknown>) };\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined) {\n delete next[key];\n } else {\n next[key] = value;\n }\n }\n setSchema(next as unknown as NexusSchema);\n return;\n }\n\n // 节点级:key 已由 KeyEditor 单独处理,此处跳过\n const { key: _key, ...rest } = patch;\n if (Object.keys(rest).length > 0) {\n updateNode(selectedPath, rest);\n }\n },\n [\n selectedPath,\n updateNode,\n setSchema,\n schema,\n selectedNode,\n formLevelConfig,\n ],\n );\n\n const handleRename = useCallback(\n (newKey: string) => {\n if (!selectedPath || selectedPath.length === 0) {\n return;\n }\n renameNode(selectedPath, newKey);\n },\n [selectedPath, renameNode],\n );\n\n // 节点类型徽标:字段取 widget,布局/对象取 type\n const nodeKind = selectedNode\n ? (\n (selectedNode.widget as string) ||\n (selectedNode.type as string) ||\n ''\n ).toLowerCase()\n : '';\n\n return (\n <div className='flex h-full flex-col border-l border-[#f0f0f0] bg-white'>\n {/* 导航头 */}\n <div className='flex items-center justify-between border-b border-[#f0f0f0] px-4 py-2.5'>\n <div className='pl-5 flex min-w-0 items-center gap-1 h-6'>\n {!isFormLevel && (\n <button\n type='button'\n onClick={() => selectNode(null)}\n className='-ml-1 mr-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-[#999] transition-colors hover:bg-[#f0f0f0] hover:text-[#333]'\n title='返回表单属性'\n >\n <svg\n width='12'\n height='12'\n viewBox='0 0 24 24'\n fill='none'\n stroke='currentColor'\n strokeWidth='2.5'\n strokeLinecap='round'\n strokeLinejoin='round'\n aria-hidden='true'\n >\n <polyline points='15 18 9 12 15 6' />\n </svg>\n </button>\n )}\n <span className='truncate text-[13px] font-semibold text-[#333]'>\n {isFormLevel ? '表单属性' : '节点属性'}\n </span>\n </div>\n {!isFormLevel && nodeKind && (\n <span className='ml-2 shrink-0 rounded-md bg-[#e8f1ff] px-1.5 py-0.5 text-[11px] text-[#1677ff]'>\n {nodeKind}\n </span>\n )}\n </div>\n\n <div className='nexus-property-body flex-1 overflow-y-auto px-4 py-3'>\n {/* key 特殊性处理:key 不是 SchemaNode 属性,而是 properties 索引键 */}\n {!isFormLevel && currentKey && (\n <KeyEditor\n oldKey={currentKey}\n locked={keyLocked}\n onRename={handleRename}\n />\n )}\n\n {/* 属性表单:完全基于 descriptor 驱动 */}\n <PropertyForm\n key={formKey}\n schema={formSchema}\n initialValues={\n selectedNode\n ? flattenNodeForPropertyEditor(\n selectedNode as unknown as Record<string, any>,\n )\n : formLevelConfig\n }\n onValuesChange={handleValuesChange}\n />\n </div>\n </div>\n );\n}\n"],"names":["PropertyForm","schema","initialValues","onValuesChange","form","useForm","engine","registerAntdUI","changedFieldsRef","useRef","handleWatch","useCallback","value","_allValues","changedPath","jsx","NexusForm","propertyWidgets","formLevelProps","layoutBasicProps","collapseSection","key","title","fields","KeyEditor","oldKey","locked","onRename","setValue","useState","jsxs","onChange","v","Input","e","trimmed","PropertyPanel","selectedPath","updateNode","renameNode","selectNode","setSchema","propertySchemaMap","useDesigner","selectedNode","getNodeAtProperties","isFormLevel","formKey","currentKey","keyLocked","selectedWidgetKey","formSchema","useMemo","widgetProps","commonPropertyFields","validationPropertyFields","reactionPropertyFields","dependencyPropertyFields","formLevelConfig","extractFormLevelConfig","handleValuesChange","allValues","changedFields","initial","flattenNodeForPropertyEditor","patch","diffPropertyPatch","next","_key","rest","handleRename","newKey","nodeKind"],"mappings":"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"}
1
+ {"version":3,"file":"PropertyPanel.js","sources":["../../src/PropertyPanel.tsx"],"sourcesContent":["// ============================================================================\n// @xbeeant/form-engine-designer — 右侧属性配置面板\n// 属性定义采用「描述符驱动」:\n// - 组件(widget)属性来自外部传入的 propertySchemaMap(key 为 widget 名,\n// 值为该组件的属性字段定义,示例见 @xbeeant/form-engine-ui/src/schema/*-schema.ts)\n// - 通用 / 校验 / 依赖分区在 ./property/basic-property.ts 中定义\n// - 布局节点与表单级属性在下方 formLevelProps / layoutBasicProps 内联定义\n//\n// 编辑流程(与 schemaUtils 的读/写通路对应):\n// flattenNodeForPropertyEditor → 节点 → 扁平 initialValues(读)\n// updateNodeWithNesting → 扁平 patch → 节点(写,split schema级/props级)\n// PropertyForm 通过 NexusForm 渲染 propertySchema 描述符驱动的表单\n// ============================================================================\n\nimport type { NexusSchema, SchemaNode } from '@xbeeant/form-engine';\nimport { NexusForm, useForm } from '@xbeeant/form-engine-react';\nimport { registerAntdUI } from '@xbeeant/form-engine-ui';\nimport { Input } from 'antd';\nimport { useCallback, useMemo, useRef, useState } from 'react';\nimport { useDesigner } from './DesignerContext';\nimport {\n commonPropertyFields,\n dependencyPropertyFields,\n reactionPropertyFields,\n validationPropertyFields,\n} from './property/basic-property.ts';\nimport {\n diffPropertyPatch,\n extractFormLevelConfig,\n flattenNodeForPropertyEditor,\n getNodeAtProperties,\n} from './schemaUtils';\nimport { propertyWidgets } from './widgets';\n\n// ────────────────────────────────────────────────────────────────────────────\n// PropertyForm — 属性表单容器\n// Designer 的自定义属性编辑器独立于 form-engine 的渲染系统\n// ────────────────────────────────────────────────────────────────────────────\n\ninterface PropertyFormProps {\n schema: NexusSchema;\n initialValues: Record<string, unknown>;\n onValuesChange: (\n allValues: Record<string, unknown>,\n changedFields: ReadonlySet<string>,\n ) => void;\n}\n\nfunction PropertyForm({\n schema,\n initialValues,\n onValuesChange,\n}: PropertyFormProps) {\n const [form] = useForm();\n const engine = form._getEngine();\n\n // 注册 antd 基础 widget(select/input/switch/number/textarea/collapse/collapsePanel)\n registerAntdUI(engine);\n // 记录本表单实例中用户实际改动过的字段(组件随 formKey 重建,节点切换时自动重置)。\n // 用于区分「未触碰的字符串默认值 ''」与「用户主动清空」——\n // 后者需要回写 schema(删除属性),前者写回会污染 schema(如 bind:'' 导致数据 key 丢失)。\n const changedFieldsRef = useRef<Set<string>>(new Set());\n // '#' 全局 watcher 由 FormController._onFieldValueChange 调用,\n // 前两个参数为 (globalData, globalData),第三参为本次实际变更的字段路径\n const handleWatch = useCallback(\n (value: unknown, _allValues: unknown, changedPath?: string) => {\n if (changedPath) {\n changedFieldsRef.current.add(changedPath);\n }\n onValuesChange(\n value as Record<string, unknown>,\n changedFieldsRef.current,\n );\n },\n [onValuesChange],\n );\n\n return (\n <NexusForm\n footer={false}\n form={form}\n schema={schema}\n initialValues={initialValues}\n watch={{ '#': handleWatch }}\n widgets={propertyWidgets}\n />\n );\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// 表单级属性(未选中节点时编辑 NexusSchema 顶层配置)\n// ────────────────────────────────────────────────────────────────────────────\n\nconst formLevelProps: Record<string, SchemaNode> = {\n displayType: {\n widget: 'select',\n type: 'string',\n title: '表单布局方向(displayType)',\n props: {\n options: [\n { label: '水平(row)', value: 'row' },\n { label: '垂直(column)', value: 'column' },\n { label: '行内(inline)', value: 'inline' },\n ],\n },\n },\n labelWidth: {\n widget: 'input',\n type: 'string',\n title: 'label 宽度(labelWidth)',\n placeholder: '如 120 或 20%',\n },\n colon: {\n widget: 'switch',\n type: 'boolean',\n title: '显示冒号(colon)',\n default: true,\n },\n label: {\n widget: 'switch',\n type: 'boolean',\n title: '显示 label(label)',\n default: true,\n },\n readOnly: {\n widget: 'switch',\n type: 'boolean',\n title: '整个表单只读(readOnly)',\n default: false,\n },\n column: {\n widget: 'number',\n type: 'number',\n title: '每行显示列数(column)',\n default: 1,\n },\n};\n\n// ────────────────────────────────────────────────────────────────────────────\n// 布局节点基础属性(layout nodes 不在 propertySchemaMap 中,单独定义)\n// ────────────────────────────────────────────────────────────────────────────\n\nconst layoutBasicProps: Record<string, SchemaNode> = {\n column: { widget: 'number', type: 'number', title: '列数(column)' },\n gap: { widget: 'number', type: 'number', title: '间距(gap)' },\n direction: {\n widget: 'select',\n type: 'string',\n title: '方向(direction)',\n props: {\n options: [\n { label: '水平', value: 'row' },\n { label: '垂直', value: 'column' },\n ],\n },\n },\n};\n\n// ────────────────────────────────────────────────────────────────────────────\n// collapseSection — 将一组扁平字段包裹成单个 collapse 分区\n// collapse / collapsePanel 均为布局节点,key 不进入数据路径,\n// 因此其内部字段(title / validate / bind 等)会被扁平地暴露给属性表单。\n// ────────────────────────────────────────────────────────────────────────────\n\nfunction collapseSection(\n key: string,\n title: string,\n fields: Record<string, SchemaNode>,\n): Record<string, SchemaNode> {\n // @ts-expect-error\n return {\n [key]: {\n type: 'collapsePanel',\n title,\n properties: fields,\n },\n } as unknown as SchemaNode;\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// KeyEditor — 单独处理 key 的编辑器\n// key 不是 SchemaNode 的属性,而是 properties 的索引键\n// 修改 key = schema 结构级操作:删除旧 key + 添加新 key + 更新选中路径\n// ────────────────────────────────────────────────────────────────────────────\n\ninterface KeyEditorProps {\n oldKey: string;\n locked?: boolean;\n onRename: (newKey: string) => void;\n}\n\nfunction KeyEditor({ oldKey, locked, onRename }: KeyEditorProps) {\n const [value, setValue] = useState(oldKey);\n\n if (locked) {\n return (\n <div className='mb-3 flex items-center justify-between gap-2 rounded-lg border border-[#f0f0f0] bg-[#fafafa] px-3 py-2'>\n <div className='min-w-0'>\n <div className='mb-0.5 text-[11px] text-[#999]'>字段标识(key)</div>\n <code className='break-all font-mono text-[13px] text-[#333]'>\n {oldKey}\n </code>\n </div>\n <span className='shrink-0 rounded bg-[#f0f0f0] px-1.5 py-0.5 text-[11px] text-[#999]'>\n 🔒 锁定\n </span>\n </div>\n );\n }\n\n const onChange = (v: string) => {\n setValue(v);\n onRename(v);\n };\n\n return (\n <div className='mb-3'>\n <div className='mb-1.5 text-[11px] text-[#999]'>字段标识(key)</div>\n <Input\n size='small'\n value={value}\n onChange={(e) => {\n const trimmed = (e.target.value || '').trim();\n onChange(trimmed);\n }}\n autoFocus\n className='nexus-key-input'\n />\n <div className='mt-1 text-[11px] text-[#c0c4cc]'>\n 用于数据路径与联动引用,修改后自动迁移子节点\n </div>\n </div>\n );\n}\n\n// ────────────────────────────────────────────────────────────────────────────\n// PropertyPanel — 主组件\n// ────────────────────────────────────────────────────────────────────────────\n\nexport function PropertyPanel() {\n const {\n schema,\n selectedPath,\n updateNode,\n renameNode,\n selectNode,\n setSchema,\n propertySchemaMap,\n } = useDesigner();\n\n const selectedNode =\n selectedPath && selectedPath.length > 0\n ? getNodeAtProperties(schema.properties, selectedPath)\n : undefined;\n\n const isFormLevel = !selectedPath || selectedPath.length === 0;\n\n // 选择变化时强制重建引擎(nodeVersion bump)\n const formKey = `node_${(selectedPath || []).join('_')}_${(selectedNode as { type?: string } | undefined)?.type || 'root'}`;\n\n // key 的特殊性:从 path 最后一段提取,不通过 NexusForm 管理\n const currentKey = selectedPath?.[selectedPath.length - 1] ?? '';\n const keyLocked =\n (selectedNode as unknown as Record<string, unknown> | undefined)\n ?._lockedKey === true;\n\n // 选中节点的 widget/type:决定属性面板使用哪组组件属性;\n // 仅在切换节点(widget/type 改变)时重新计算,避免每次输入都重建 schema\n // (selectedNode 的 object identity 会随每次 edit 变化,不能直接依赖)\n const selectedWidgetKey = selectedNode\n ? (selectedNode.widget as string | undefined) ||\n (selectedNode.type as string)\n : null;\n\n // 构建属性表单 schema:\n // - 未选中节点(form-level):formLevelProps(NexusSchema 顶层配置)\n // - 选中节点:4 个 collapse 分区(通用属性 / 组件属性 / 校验配置 / 依赖配置)\n // collapse 与 collapsePanel 均为布局节点,key 不进入数据路径,\n // 各分区内部字段会被扁平暴露给属性表单。\n // 注意:不依赖 selectedNode 对象本身(每次 edit 都是新引用),\n // 只依赖 isFormLevel 和 selectedWidgetKey,避免无谓 re-init。\n const formSchema = useMemo<NexusSchema>(() => {\n if (isFormLevel) {\n return {\n type: 'object',\n properties: formLevelProps,\n displayType: 'column',\n } as NexusSchema;\n }\n\n const widgetProps =\n propertySchemaMap[selectedWidgetKey as string] || layoutBasicProps;\n\n return {\n type: 'object',\n properties: {\n sectionProperty: {\n widget: 'collapse',\n props: {\n defaultActiveKey: [\n 'sectionCommon',\n 'sectionFieldProps',\n 'sectionValidation',\n 'sectionReaction',\n 'sectionDependency',\n ],\n },\n type: 'collapse',\n properties: {\n ...collapseSection(\n 'sectionCommon',\n '通用属性',\n commonPropertyFields,\n ),\n ...collapseSection(\n 'sectionFieldProps',\n '组件属性',\n widgetProps as Record<string, SchemaNode>,\n ),\n ...collapseSection(\n 'sectionValidation',\n '校验配置',\n validationPropertyFields,\n ),\n ...collapseSection(\n 'sectionReaction',\n '联动配置',\n reactionPropertyFields,\n ),\n ...collapseSection(\n 'sectionDependency',\n '依赖配置',\n dependencyPropertyFields,\n ),\n },\n },\n },\n displayType: 'column',\n } as NexusSchema;\n }, [isFormLevel, selectedWidgetKey, propertySchemaMap]);\n\n // 表单级属性面板的取值来源:只提取 NexusSchema 顶层的表单配置键,\n // 而非整个 schema 对象(schema 含 properties 与嵌套字段,不是表单级配置)\n const formLevelConfig = useMemo<Record<string, unknown>>(\n () =>\n extractFormLevelConfig(\n schema as unknown as Record<string, unknown>,\n Object.keys(formLevelProps),\n ),\n [schema],\n );\n\n const handleValuesChange = useCallback(\n (\n allValues: Record<string, unknown>,\n changedFields: ReadonlySet<string>,\n ) => {\n // 只写回「真正变化」的值:未触碰的空字符串(''/undefined/null)视为未赋值,\n // 不写回 Schema(否则 bind:'' / hidden:'' / required:'' 会导致 key 丢失 / 空联动);\n // 用户主动清空的字段(changedFields 命中)以 undefined 回写,由\n // updateNodeWithNesting 从节点删除对应属性(详见 diffPropertyPatch)\n const initial = selectedNode\n ? flattenNodeForPropertyEditor(\n selectedNode as unknown as Record<string, any>,\n )\n : formLevelConfig;\n\n const patch = diffPropertyPatch(initial, allValues, changedFields);\n if (Object.keys(patch).length === 0) {\n return;\n }\n\n if (!selectedPath || selectedPath.length === 0) {\n // form-level:修改 NexusSchema 顶层属性(undefined 表示清空,删除该键)\n const next = { ...(schema as unknown as Record<string, unknown>) };\n for (const [key, value] of Object.entries(patch)) {\n if (value === undefined) {\n delete next[key];\n } else {\n next[key] = value;\n }\n }\n setSchema(next as unknown as NexusSchema);\n return;\n }\n\n // 节点级:key 已由 KeyEditor 单独处理,此处跳过\n const { key: _key, ...rest } = patch;\n if (Object.keys(rest).length > 0) {\n updateNode(selectedPath, rest);\n }\n },\n [\n selectedPath,\n updateNode,\n setSchema,\n schema,\n selectedNode,\n formLevelConfig,\n ],\n );\n\n const handleRename = useCallback(\n (newKey: string) => {\n if (!selectedPath || selectedPath.length === 0) {\n return;\n }\n renameNode(selectedPath, newKey);\n },\n [selectedPath, renameNode],\n );\n\n // 节点类型徽标:字段取 widget,布局/对象取 type\n const nodeKind = selectedNode\n ? (\n (selectedNode.widget as string) ||\n (selectedNode.type as string) ||\n ''\n ).toLowerCase()\n : '';\n\n return (\n <div className='flex h-full flex-col border-l border-[#f0f0f0] bg-white'>\n {/* 导航头 */}\n <div className='flex items-center justify-between border-b border-[#f0f0f0] px-4 py-2.5'>\n <div className='pl-5 flex min-w-0 items-center gap-1 h-6'>\n {!isFormLevel && (\n <button\n type='button'\n onClick={() => selectNode(null)}\n className='-ml-1 mr-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-[#999] transition-colors hover:bg-[#f0f0f0] hover:text-[#333]'\n title='返回表单属性'\n >\n <svg\n width='12'\n height='12'\n viewBox='0 0 24 24'\n fill='none'\n stroke='currentColor'\n strokeWidth='2.5'\n strokeLinecap='round'\n strokeLinejoin='round'\n aria-hidden='true'\n >\n <polyline points='15 18 9 12 15 6' />\n </svg>\n </button>\n )}\n <span className='truncate text-[13px] font-semibold text-[#333]'>\n {isFormLevel ? '表单属性' : '节点属性'}\n </span>\n </div>\n {!isFormLevel && nodeKind && (\n <span className='ml-2 shrink-0 rounded-md bg-[#e8f1ff] px-1.5 py-0.5 text-[11px] text-[#1677ff]'>\n {nodeKind}\n </span>\n )}\n </div>\n\n <div className='nexus-property-body flex-1 overflow-y-auto px-4 py-3'>\n {/* key 特殊性处理:key 不是 SchemaNode 属性,而是 properties 索引键 */}\n {!isFormLevel && currentKey && (\n <KeyEditor\n oldKey={currentKey}\n locked={keyLocked}\n onRename={handleRename}\n />\n )}\n\n {/* 属性表单:完全基于 descriptor 驱动 */}\n <PropertyForm\n key={formKey}\n schema={formSchema}\n initialValues={\n selectedNode\n ? flattenNodeForPropertyEditor(\n selectedNode as unknown as Record<string, any>,\n )\n : formLevelConfig\n }\n onValuesChange={handleValuesChange}\n />\n </div>\n </div>\n );\n}\n"],"names":["PropertyForm","schema","initialValues","onValuesChange","form","useForm","engine","registerAntdUI","changedFieldsRef","useRef","handleWatch","useCallback","value","_allValues","changedPath","jsx","NexusForm","propertyWidgets","formLevelProps","layoutBasicProps","collapseSection","key","title","fields","KeyEditor","oldKey","locked","onRename","setValue","useState","jsxs","onChange","v","Input","e","trimmed","PropertyPanel","selectedPath","updateNode","renameNode","selectNode","setSchema","propertySchemaMap","useDesigner","selectedNode","getNodeAtProperties","isFormLevel","formKey","currentKey","keyLocked","selectedWidgetKey","formSchema","useMemo","widgetProps","commonPropertyFields","validationPropertyFields","reactionPropertyFields","dependencyPropertyFields","formLevelConfig","extractFormLevelConfig","handleValuesChange","allValues","changedFields","initial","flattenNodeForPropertyEditor","patch","diffPropertyPatch","next","_key","rest","handleRename","newKey","nodeKind"],"mappings":"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"}
@@ -214,7 +214,8 @@ const e = [
214
214
  createNode: () => ({
215
215
  type: "string",
216
216
  widget: "voidTitle",
217
- title: "标题文字"
217
+ title: "标题文字",
218
+ label: !1
218
219
  })
219
220
  },
220
221
  {
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.js","sources":["../../src/catalog.ts"],"sourcesContent":["// ============================================================================\n// @xbeeant/form-engine-designer — 组件目录\n// ============================================================================\n\nimport type { CatalogItem } from './types';\n\n/**\n * 表单组件目录\n * 每个项创建一个 DataFieldSchema 节点\n * widget 名对齐 @xbeeant/form-engine-ui 中 antdWidgets 实际注册的 key\n */\nexport const widgetCatalog: CatalogItem[] = [\n {\n label: '输入框',\n icon: '📝',\n category: 'widget',\n widget: 'input',\n createNode: () => ({ type: 'string', widget: 'input', title: '输入框' }),\n },\n {\n label: '密码框',\n icon: '🔑',\n category: 'widget',\n widget: 'password',\n createNode: () => ({ type: 'string', widget: 'password', title: '密码框' }),\n },\n {\n label: '数字输入',\n icon: '🔢',\n category: 'widget',\n widget: 'number',\n createNode: () => ({ type: 'number', widget: 'number', title: '数字输入' }),\n },\n {\n label: '文本域',\n icon: '📄',\n category: 'widget',\n widget: 'textarea',\n createNode: () => ({ type: 'string', widget: 'textarea', title: '文本域' }),\n },\n {\n label: '下拉选择',\n icon: '📋',\n category: 'widget',\n widget: 'select',\n createNode: () => ({\n type: 'string',\n widget: 'select',\n title: '下拉选择',\n enum: ['option1', 'option2'],\n enumNames: ['选项1', '选项2'],\n }),\n },\n {\n label: '下拉选择(远程)',\n icon: '📡',\n category: 'widget',\n widget: 'selectWithRemote',\n createNode: () => ({\n type: 'string',\n widget: 'selectWithRemote',\n title: '下拉选择(远程)',\n remoteData: {\n url: '/api/options',\n method: 'GET',\n responseField: { data: 'data.list', value: 'id', label: 'name' },\n params: { page: 1, pageSize: 50 },\n },\n }),\n },\n {\n label: '单选',\n icon: '🔘',\n category: 'widget',\n widget: 'radio',\n createNode: () => ({\n type: 'string',\n widget: 'radio',\n title: '单选',\n enum: ['a', 'b'],\n enumNames: ['选项A', '选项B'],\n }),\n },\n {\n label: '复选框',\n icon: '☑️',\n category: 'widget',\n widget: 'checkbox',\n createNode: () => ({\n type: 'boolean',\n widget: 'checkbox',\n title: '复选框',\n }),\n },\n {\n label: '多选',\n icon: '☒',\n category: 'widget',\n widget: 'checkboxes',\n createNode: () => ({\n type: 'array',\n widget: 'checkboxes',\n title: '多选',\n enum: ['a', 'b'],\n enumNames: ['选项A', '选项B'],\n }),\n },\n {\n label: '多选下拉',\n icon: '📊',\n category: 'widget',\n widget: 'multiSelect',\n createNode: () => ({\n type: 'array',\n widget: 'multiSelect',\n title: '多选下拉',\n enum: ['a', 'b'],\n enumNames: ['选项A', '选项B'],\n }),\n },\n {\n label: '多选下拉(远程)',\n icon: '📡',\n category: 'widget',\n widget: 'multiSelectWithRemote',\n createNode: () => ({\n type: 'array',\n widget: 'multiSelectWithRemote',\n title: '多选下拉(远程)',\n remoteData: {\n url: '/api/multi-options',\n method: 'GET',\n responseField: { data: 'data.list', value: 'id', label: 'name' },\n params: { page: 1, pageSize: 50 },\n },\n }),\n },\n {\n label: '开关',\n icon: '🔀',\n category: 'widget',\n widget: 'switch',\n createNode: () => ({ type: 'boolean', widget: 'switch', title: '开关' }),\n },\n {\n label: '日期选择',\n icon: '📅',\n category: 'widget',\n widget: 'date',\n createNode: () => ({ type: 'string', widget: 'date', title: '日期选择' }),\n },\n {\n label: '日期范围',\n icon: '📅',\n category: 'widget',\n widget: 'dateRange',\n createNode: () => ({\n type: 'string',\n widget: 'dateRange',\n title: '日期范围',\n }),\n },\n {\n label: '时间选择',\n icon: '⏰',\n category: 'widget',\n widget: 'time',\n createNode: () => ({ type: 'string', widget: 'time', title: '时间选择' }),\n },\n {\n label: '时间范围',\n icon: '⏰',\n category: 'widget',\n widget: 'timeRange',\n createNode: () => ({\n type: 'string',\n widget: 'timeRange',\n title: '时间范围',\n }),\n },\n {\n label: '滑块',\n icon: '🎚️',\n category: 'widget',\n widget: 'slider',\n createNode: () => ({ type: 'number', widget: 'slider', title: '滑块' }),\n },\n {\n label: '颜色选择',\n icon: '🎨',\n category: 'widget',\n widget: 'color',\n createNode: () => ({ type: 'string', widget: 'color', title: '颜色选择' }),\n },\n {\n label: 'URL输入',\n icon: '🔗',\n category: 'widget',\n widget: 'urlInput',\n createNode: () => ({\n type: 'string',\n widget: 'urlInput',\n title: 'URL输入',\n }),\n },\n {\n label: '图片上传',\n icon: '🖼️',\n category: 'widget',\n widget: 'image',\n createNode: () => ({ type: 'string', widget: 'image', title: '图片上传' }),\n },\n {\n label: 'HTML展示',\n icon: '📄',\n category: 'widget',\n widget: 'html',\n createNode: () => ({ type: 'string', widget: 'html', title: 'HTML展示' }),\n },\n {\n label: '标题文字',\n icon: '🏷️',\n category: 'widget',\n widget: 'voidTitle',\n createNode: () => ({\n type: 'string',\n widget: 'voidTitle',\n title: '标题文字',\n }),\n },\n {\n label: '树选择',\n icon: '🌲',\n category: 'widget',\n widget: 'treeSelect',\n createNode: () => ({\n type: 'string',\n widget: 'treeSelect',\n title: '树选择',\n }),\n },\n {\n label: '自动完成',\n icon: '🔎',\n category: 'widget',\n widget: 'autoComplete',\n createNode: () => ({\n type: 'string',\n widget: 'autoComplete',\n title: '自动完成',\n enum: ['option1', 'option2'],\n enumNames: ['选项1', '选项2'],\n }),\n },\n {\n label: '自动完成(远程)',\n icon: '📡',\n category: 'widget',\n widget: 'autoCompleteWithRemote',\n createNode: () => ({\n type: 'string',\n widget: 'autoCompleteWithRemote',\n title: '自动完成(远程)',\n remoteData: {\n url: '/api/suggestions',\n method: 'GET',\n responseField: { data: 'data.suggestions', value: 'id', label: 'name' },\n params: { keyword: '' },\n },\n }),\n },\n {\n label: '级联选择',\n icon: '🌳',\n category: 'widget',\n widget: 'cascader',\n createNode: () => ({\n type: 'array',\n widget: 'cascader',\n title: '级联选择',\n enum: ['a', 'b'],\n enumNames: ['选项A', '选项B'],\n }),\n },\n {\n label: '级联选择(远程)',\n icon: '📡',\n category: 'widget',\n widget: 'cascaderWithRemote',\n createNode: () => ({\n type: 'array',\n widget: 'cascaderWithRemote',\n title: '级联选择(远程)',\n remoteData: {\n url: '/api/cascader/nodes',\n method: 'GET',\n responseField: {\n data: 'data.children',\n value: 'id',\n label: 'name',\n parentIdKey: 'parentId',\n },\n params: { parentId: null },\n },\n }),\n },\n {\n label: '提及',\n icon: '💬',\n category: 'widget',\n widget: 'mentions',\n createNode: () => ({\n type: 'string',\n widget: 'mentions',\n title: '提及',\n enum: ['alice', 'bob'],\n enumNames: ['Alice', 'Bob'],\n }),\n },\n {\n label: '提及(远程)',\n icon: '📡',\n category: 'widget',\n widget: 'mentionsWithRemote',\n createNode: () => ({\n type: 'string',\n widget: 'mentionsWithRemote',\n title: '提及(远程)',\n remoteData: {\n url: '/api/users/suggestions',\n method: 'GET',\n responseField: { data: 'data.users', value: 'id', label: 'name' },\n params: { keyword: '' },\n },\n }),\n },\n {\n label: '分段控制器',\n icon: '🎚️',\n category: 'widget',\n widget: 'segmented',\n createNode: () => ({\n type: 'string',\n widget: 'segmented',\n title: '分段控制器',\n enum: ['a', 'b'],\n enumNames: ['选项A', '选项B'],\n }),\n },\n {\n label: '穿梭框',\n icon: '⇄',\n category: 'widget',\n widget: 'transfer',\n createNode: () => ({\n type: 'array',\n widget: 'transfer',\n title: '穿梭框',\n }),\n },\n {\n label: '文件上传',\n icon: '📎',\n category: 'widget',\n widget: 'file',\n createNode: () => ({ type: 'array', widget: 'file', title: '文件上传' }),\n },\n {\n label: '数据对象',\n icon: '🗂️',\n category: 'widget',\n widget: 'object',\n createNode: () => ({ type: 'object', title: '数据对象', properties: {} }),\n },\n {\n label: '常规列表',\n icon: '📋',\n category: 'widget',\n widget: 'list',\n createNode: () => ({\n type: 'array',\n widget: 'list',\n title: '常规列表',\n items: {\n type: 'object',\n properties: {},\n },\n }),\n },\n {\n label: '简单列表',\n icon: '📃',\n category: 'widget',\n widget: 'simpleList',\n createNode: () => ({\n type: 'array',\n widget: 'simpleList',\n title: '简单列表',\n items: {\n type: 'object',\n properties: {},\n },\n }),\n },\n {\n label: '表格列表',\n icon: '📊',\n category: 'widget',\n widget: 'tableList',\n createNode: () => ({\n type: 'array',\n widget: 'tableList',\n title: '表格列表',\n items: {\n type: 'object',\n properties: {},\n },\n }),\n },\n];\n\n/**\n * 布局组件目录\n * 每个项创建一个 LayoutContainerSchema 节点\n */\nexport const layoutCatalog: CatalogItem[] = [\n {\n label: '卡片',\n icon: '📦',\n category: 'layout',\n layoutType: 'card',\n createNode: () => ({ type: 'card', title: '卡片', properties: {} }),\n },\n {\n label: '栅格',\n icon: '🔲',\n category: 'layout',\n layoutType: 'grid',\n createNode: () => ({ type: 'grid', column: 2, properties: {} }),\n },\n {\n label: '标签页',\n icon: '📑',\n category: 'layout',\n layoutType: 'tabs',\n createNode: () => ({\n type: 'tabs',\n title: '标签页',\n properties: {\n pane1: { type: 'tabPane', title: '标签页签 1', properties: {} },\n },\n }),\n },\n {\n label: '标签页签',\n icon: '📑',\n category: 'layout',\n layoutType: 'tabPane',\n createNode: () => ({ type: 'tabPane', title: '标签页签', properties: {} }),\n },\n {\n label: '折叠面板',\n icon: '📂',\n category: 'layout',\n layoutType: 'collapse',\n createNode: () => ({\n type: 'collapse',\n title: '折叠面板',\n properties: {\n panel1: { type: 'collapsePanel', title: '折叠面板 1', properties: {} },\n },\n }),\n },\n {\n label: '折叠面板项',\n icon: '📂',\n category: 'layout',\n layoutType: 'collapsePanel',\n createNode: () => ({\n type: 'collapsePanel',\n title: '折叠面板项',\n properties: {},\n }),\n },\n {\n label: '步骤条',\n icon: '📝',\n category: 'layout',\n layoutType: 'steps',\n createNode: () => ({\n type: 'steps',\n title: '步骤条',\n properties: {\n step1: { type: 'step', title: '步骤 1', properties: {} },\n },\n }),\n },\n {\n label: '步骤项',\n icon: '📝',\n category: 'layout',\n layoutType: 'step',\n createNode: () => ({ type: 'step', title: '步骤项', properties: {} }),\n },\n {\n label: '分割线',\n icon: '➖',\n category: 'layout',\n layoutType: 'divider',\n createNode: () => ({ type: 'divider', properties: {} }),\n },\n {\n label: '弹性布局',\n icon: '📐',\n category: 'layout',\n layoutType: 'flex',\n createNode: () => ({ type: 'flex', properties: {} }),\n },\n {\n label: '间距布局',\n icon: '↔️',\n category: 'layout',\n layoutType: 'space',\n createNode: () => ({ type: 'space', properties: {} }),\n },\n];\n"],"names":["widgetCatalog","layoutCatalog"],"mappings":"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"}
1
+ {"version":3,"file":"catalog.js","sources":["../../src/catalog.ts"],"sourcesContent":["// ============================================================================\n// @xbeeant/form-engine-designer — 组件目录\n// ============================================================================\n\nimport type { CatalogItem } from './types';\n\n/**\n * 表单组件目录\n * 每个项创建一个 DataFieldSchema 节点\n * widget 名对齐 @xbeeant/form-engine-ui 中 antdWidgets 实际注册的 key\n */\nexport const widgetCatalog: CatalogItem[] = [\n {\n label: '输入框',\n icon: '📝',\n category: 'widget',\n widget: 'input',\n createNode: () => ({ type: 'string', widget: 'input', title: '输入框' }),\n },\n {\n label: '密码框',\n icon: '🔑',\n category: 'widget',\n widget: 'password',\n createNode: () => ({ type: 'string', widget: 'password', title: '密码框' }),\n },\n {\n label: '数字输入',\n icon: '🔢',\n category: 'widget',\n widget: 'number',\n createNode: () => ({ type: 'number', widget: 'number', title: '数字输入' }),\n },\n {\n label: '文本域',\n icon: '📄',\n category: 'widget',\n widget: 'textarea',\n createNode: () => ({ type: 'string', widget: 'textarea', title: '文本域' }),\n },\n {\n label: '下拉选择',\n icon: '📋',\n category: 'widget',\n widget: 'select',\n createNode: () => ({\n type: 'string',\n widget: 'select',\n title: '下拉选择',\n enum: ['option1', 'option2'],\n enumNames: ['选项1', '选项2'],\n }),\n },\n {\n label: '下拉选择(远程)',\n icon: '📡',\n category: 'widget',\n widget: 'selectWithRemote',\n createNode: () => ({\n type: 'string',\n widget: 'selectWithRemote',\n title: '下拉选择(远程)',\n remoteData: {\n url: '/api/options',\n method: 'GET',\n responseField: { data: 'data.list', value: 'id', label: 'name' },\n params: { page: 1, pageSize: 50 },\n },\n }),\n },\n {\n label: '单选',\n icon: '🔘',\n category: 'widget',\n widget: 'radio',\n createNode: () => ({\n type: 'string',\n widget: 'radio',\n title: '单选',\n enum: ['a', 'b'],\n enumNames: ['选项A', '选项B'],\n }),\n },\n {\n label: '复选框',\n icon: '☑️',\n category: 'widget',\n widget: 'checkbox',\n createNode: () => ({\n type: 'boolean',\n widget: 'checkbox',\n title: '复选框',\n }),\n },\n {\n label: '多选',\n icon: '☒',\n category: 'widget',\n widget: 'checkboxes',\n createNode: () => ({\n type: 'array',\n widget: 'checkboxes',\n title: '多选',\n enum: ['a', 'b'],\n enumNames: ['选项A', '选项B'],\n }),\n },\n {\n label: '多选下拉',\n icon: '📊',\n category: 'widget',\n widget: 'multiSelect',\n createNode: () => ({\n type: 'array',\n widget: 'multiSelect',\n title: '多选下拉',\n enum: ['a', 'b'],\n enumNames: ['选项A', '选项B'],\n }),\n },\n {\n label: '多选下拉(远程)',\n icon: '📡',\n category: 'widget',\n widget: 'multiSelectWithRemote',\n createNode: () => ({\n type: 'array',\n widget: 'multiSelectWithRemote',\n title: '多选下拉(远程)',\n remoteData: {\n url: '/api/multi-options',\n method: 'GET',\n responseField: { data: 'data.list', value: 'id', label: 'name' },\n params: { page: 1, pageSize: 50 },\n },\n }),\n },\n {\n label: '开关',\n icon: '🔀',\n category: 'widget',\n widget: 'switch',\n createNode: () => ({ type: 'boolean', widget: 'switch', title: '开关' }),\n },\n {\n label: '日期选择',\n icon: '📅',\n category: 'widget',\n widget: 'date',\n createNode: () => ({ type: 'string', widget: 'date', title: '日期选择' }),\n },\n {\n label: '日期范围',\n icon: '📅',\n category: 'widget',\n widget: 'dateRange',\n createNode: () => ({\n type: 'string',\n widget: 'dateRange',\n title: '日期范围',\n }),\n },\n {\n label: '时间选择',\n icon: '⏰',\n category: 'widget',\n widget: 'time',\n createNode: () => ({ type: 'string', widget: 'time', title: '时间选择' }),\n },\n {\n label: '时间范围',\n icon: '⏰',\n category: 'widget',\n widget: 'timeRange',\n createNode: () => ({\n type: 'string',\n widget: 'timeRange',\n title: '时间范围',\n }),\n },\n {\n label: '滑块',\n icon: '🎚️',\n category: 'widget',\n widget: 'slider',\n createNode: () => ({ type: 'number', widget: 'slider', title: '滑块' }),\n },\n {\n label: '颜色选择',\n icon: '🎨',\n category: 'widget',\n widget: 'color',\n createNode: () => ({ type: 'string', widget: 'color', title: '颜色选择' }),\n },\n {\n label: 'URL输入',\n icon: '🔗',\n category: 'widget',\n widget: 'urlInput',\n createNode: () => ({\n type: 'string',\n widget: 'urlInput',\n title: 'URL输入',\n }),\n },\n {\n label: '图片上传',\n icon: '🖼️',\n category: 'widget',\n widget: 'image',\n createNode: () => ({ type: 'string', widget: 'image', title: '图片上传' }),\n },\n {\n label: 'HTML展示',\n icon: '📄',\n category: 'widget',\n widget: 'html',\n createNode: () => ({ type: 'string', widget: 'html', title: 'HTML展示' }),\n },\n {\n label: '标题文字',\n icon: '🏷️',\n category: 'widget',\n widget: 'voidTitle',\n createNode: () => ({\n type: 'string',\n widget: 'voidTitle',\n title: '标题文字',\n label: false,\n }),\n },\n {\n label: '树选择',\n icon: '🌲',\n category: 'widget',\n widget: 'treeSelect',\n createNode: () => ({\n type: 'string',\n widget: 'treeSelect',\n title: '树选择',\n }),\n },\n {\n label: '自动完成',\n icon: '🔎',\n category: 'widget',\n widget: 'autoComplete',\n createNode: () => ({\n type: 'string',\n widget: 'autoComplete',\n title: '自动完成',\n enum: ['option1', 'option2'],\n enumNames: ['选项1', '选项2'],\n }),\n },\n {\n label: '自动完成(远程)',\n icon: '📡',\n category: 'widget',\n widget: 'autoCompleteWithRemote',\n createNode: () => ({\n type: 'string',\n widget: 'autoCompleteWithRemote',\n title: '自动完成(远程)',\n remoteData: {\n url: '/api/suggestions',\n method: 'GET',\n responseField: { data: 'data.suggestions', value: 'id', label: 'name' },\n params: { keyword: '' },\n },\n }),\n },\n {\n label: '级联选择',\n icon: '🌳',\n category: 'widget',\n widget: 'cascader',\n createNode: () => ({\n type: 'array',\n widget: 'cascader',\n title: '级联选择',\n enum: ['a', 'b'],\n enumNames: ['选项A', '选项B'],\n }),\n },\n {\n label: '级联选择(远程)',\n icon: '📡',\n category: 'widget',\n widget: 'cascaderWithRemote',\n createNode: () => ({\n type: 'array',\n widget: 'cascaderWithRemote',\n title: '级联选择(远程)',\n remoteData: {\n url: '/api/cascader/nodes',\n method: 'GET',\n responseField: {\n data: 'data.children',\n value: 'id',\n label: 'name',\n parentIdKey: 'parentId',\n },\n params: { parentId: null },\n },\n }),\n },\n {\n label: '提及',\n icon: '💬',\n category: 'widget',\n widget: 'mentions',\n createNode: () => ({\n type: 'string',\n widget: 'mentions',\n title: '提及',\n enum: ['alice', 'bob'],\n enumNames: ['Alice', 'Bob'],\n }),\n },\n {\n label: '提及(远程)',\n icon: '📡',\n category: 'widget',\n widget: 'mentionsWithRemote',\n createNode: () => ({\n type: 'string',\n widget: 'mentionsWithRemote',\n title: '提及(远程)',\n remoteData: {\n url: '/api/users/suggestions',\n method: 'GET',\n responseField: { data: 'data.users', value: 'id', label: 'name' },\n params: { keyword: '' },\n },\n }),\n },\n {\n label: '分段控制器',\n icon: '🎚️',\n category: 'widget',\n widget: 'segmented',\n createNode: () => ({\n type: 'string',\n widget: 'segmented',\n title: '分段控制器',\n enum: ['a', 'b'],\n enumNames: ['选项A', '选项B'],\n }),\n },\n {\n label: '穿梭框',\n icon: '⇄',\n category: 'widget',\n widget: 'transfer',\n createNode: () => ({\n type: 'array',\n widget: 'transfer',\n title: '穿梭框',\n }),\n },\n {\n label: '文件上传',\n icon: '📎',\n category: 'widget',\n widget: 'file',\n createNode: () => ({ type: 'array', widget: 'file', title: '文件上传' }),\n },\n {\n label: '数据对象',\n icon: '🗂️',\n category: 'widget',\n widget: 'object',\n createNode: () => ({ type: 'object', title: '数据对象', properties: {} }),\n },\n {\n label: '常规列表',\n icon: '📋',\n category: 'widget',\n widget: 'list',\n createNode: () => ({\n type: 'array',\n widget: 'list',\n title: '常规列表',\n items: {\n type: 'object',\n properties: {},\n },\n }),\n },\n {\n label: '简单列表',\n icon: '📃',\n category: 'widget',\n widget: 'simpleList',\n createNode: () => ({\n type: 'array',\n widget: 'simpleList',\n title: '简单列表',\n items: {\n type: 'object',\n properties: {},\n },\n }),\n },\n {\n label: '表格列表',\n icon: '📊',\n category: 'widget',\n widget: 'tableList',\n createNode: () => ({\n type: 'array',\n widget: 'tableList',\n title: '表格列表',\n items: {\n type: 'object',\n properties: {},\n },\n }),\n },\n];\n\n/**\n * 布局组件目录\n * 每个项创建一个 LayoutContainerSchema 节点\n */\nexport const layoutCatalog: CatalogItem[] = [\n {\n label: '卡片',\n icon: '📦',\n category: 'layout',\n layoutType: 'card',\n createNode: () => ({ type: 'card', title: '卡片', properties: {} }),\n },\n {\n label: '栅格',\n icon: '🔲',\n category: 'layout',\n layoutType: 'grid',\n createNode: () => ({ type: 'grid', column: 2, properties: {} }),\n },\n {\n label: '标签页',\n icon: '📑',\n category: 'layout',\n layoutType: 'tabs',\n createNode: () => ({\n type: 'tabs',\n title: '标签页',\n properties: {\n pane1: { type: 'tabPane', title: '标签页签 1', properties: {} },\n },\n }),\n },\n {\n label: '标签页签',\n icon: '📑',\n category: 'layout',\n layoutType: 'tabPane',\n createNode: () => ({ type: 'tabPane', title: '标签页签', properties: {} }),\n },\n {\n label: '折叠面板',\n icon: '📂',\n category: 'layout',\n layoutType: 'collapse',\n createNode: () => ({\n type: 'collapse',\n title: '折叠面板',\n properties: {\n panel1: { type: 'collapsePanel', title: '折叠面板 1', properties: {} },\n },\n }),\n },\n {\n label: '折叠面板项',\n icon: '📂',\n category: 'layout',\n layoutType: 'collapsePanel',\n createNode: () => ({\n type: 'collapsePanel',\n title: '折叠面板项',\n properties: {},\n }),\n },\n {\n label: '步骤条',\n icon: '📝',\n category: 'layout',\n layoutType: 'steps',\n createNode: () => ({\n type: 'steps',\n title: '步骤条',\n properties: {\n step1: { type: 'step', title: '步骤 1', properties: {} },\n },\n }),\n },\n {\n label: '步骤项',\n icon: '📝',\n category: 'layout',\n layoutType: 'step',\n createNode: () => ({ type: 'step', title: '步骤项', properties: {} }),\n },\n {\n label: '分割线',\n icon: '➖',\n category: 'layout',\n layoutType: 'divider',\n createNode: () => ({ type: 'divider', properties: {} }),\n },\n {\n label: '弹性布局',\n icon: '📐',\n category: 'layout',\n layoutType: 'flex',\n createNode: () => ({ type: 'flex', properties: {} }),\n },\n {\n label: '间距布局',\n icon: '↔️',\n category: 'layout',\n layoutType: 'space',\n createNode: () => ({ type: 'space', properties: {} }),\n },\n];\n"],"names":["widgetCatalog","layoutCatalog"],"mappings":"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"}