@xbeeant/form-engine-designer 0.0.3 → 0.0.4
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 +42 -47
- package/dist/es/Canvas.js.map +1 -1
- package/dist/es/Designer.js +121 -98
- package/dist/es/Designer.js.map +1 -1
- package/dist/es/DesignerContext.js +86 -73
- package/dist/es/DesignerContext.js.map +1 -1
- package/dist/es/Palette.js +3 -3
- package/dist/es/Palette.js.map +1 -1
- package/dist/es/PropertyPanel.js +99 -100
- package/dist/es/PropertyPanel.js.map +1 -1
- package/dist/es/catalog.js +17 -10
- package/dist/es/catalog.js.map +1 -1
- package/dist/es/designer-context.js +110 -0
- package/dist/es/designer-context.js.map +1 -0
- package/dist/es/history.js +73 -0
- package/dist/es/history.js.map +1 -0
- package/dist/es/index.css +1 -1
- package/dist/es/index.js +3 -3
- package/dist/es/property/basic-property.js +6 -0
- package/dist/es/property/basic-property.js.map +1 -1
- package/dist/es/property-panel.js +294 -0
- package/dist/es/property-panel.js.map +1 -0
- package/dist/es/resizable-panel.js +103 -0
- package/dist/es/resizable-panel.js.map +1 -0
- package/dist/es/schema-utils.js +286 -0
- package/dist/es/schema-utils.js.map +1 -0
- package/dist/es/widgets/BindEditor.js +60 -49
- package/dist/es/widgets/BindEditor.js.map +1 -1
- package/dist/es/widgets/CodeEditor.js +41 -49
- package/dist/es/widgets/CodeEditor.js.map +1 -1
- package/dist/es/widgets/DefaultEditor.js +25 -30
- package/dist/es/widgets/DefaultEditor.js.map +1 -1
- package/dist/es/widgets/DependenciesEditor.js +21 -21
- package/dist/es/widgets/DependenciesEditor.js.map +1 -1
- package/dist/es/widgets/EnumEditor.js +25 -31
- package/dist/es/widgets/EnumEditor.js.map +1 -1
- package/dist/es/widgets/ExpressionSwitch.js +32 -30
- package/dist/es/widgets/ExpressionSwitch.js.map +1 -1
- package/dist/es/widgets/ReactionsEditor.js +103 -103
- package/dist/es/widgets/ReactionsEditor.js.map +1 -1
- package/dist/es/widgets/RemoteDataEditor.js +63 -63
- package/dist/es/widgets/RemoteDataEditor.js.map +1 -1
- package/dist/es/widgets/ValidateEditor.js +49 -49
- package/dist/es/widgets/ValidateEditor.js.map +1 -1
- package/dist/es/widgets/bind-editor.js +78 -0
- package/dist/es/widgets/bind-editor.js.map +1 -0
- package/dist/es/widgets/code-editor.js +76 -0
- package/dist/es/widgets/code-editor.js.map +1 -0
- package/dist/es/widgets/default-editor.js +50 -0
- package/dist/es/widgets/default-editor.js.map +1 -0
- package/dist/es/widgets/dependencies-editor.js +36 -0
- package/dist/es/widgets/dependencies-editor.js.map +1 -0
- package/dist/es/widgets/enum-editor.js +43 -0
- package/dist/es/widgets/enum-editor.js.map +1 -0
- package/dist/es/widgets/expression-builder.js +367 -0
- package/dist/es/widgets/expression-builder.js.map +1 -0
- package/dist/es/widgets/expression-model.js +340 -0
- package/dist/es/widgets/expression-model.js.map +1 -0
- package/dist/es/widgets/expression-switch.js +49 -0
- package/dist/es/widgets/expression-switch.js.map +1 -0
- package/dist/es/widgets/index.js +13 -13
- package/dist/es/widgets/index.js.map +1 -1
- package/dist/es/widgets/options-editor.js +102 -0
- package/dist/es/widgets/options-editor.js.map +1 -0
- package/dist/es/widgets/reactions-editor.js +401 -0
- package/dist/es/widgets/reactions-editor.js.map +1 -0
- package/dist/es/widgets/reactions-model.js +107 -0
- package/dist/es/widgets/reactions-model.js.map +1 -0
- package/dist/es/widgets/remote-data-editor.js +314 -0
- package/dist/es/widgets/remote-data-editor.js.map +1 -0
- package/dist/es/widgets/use-form-data-fields.js +16 -0
- package/dist/es/widgets/use-form-data-fields.js.map +1 -0
- package/dist/es/widgets/validate-editor.js +118 -0
- package/dist/es/widgets/validate-editor.js.map +1 -0
- package/package.json +4 -5
- package/dist/es/react/src/components/FormController.js +0 -160
- package/dist/es/react/src/components/FormController.js.map +0 -1
- package/dist/es/react/src/components/NexusField.js +0 -98
- package/dist/es/react/src/components/NexusField.js.map +0 -1
- package/dist/es/react/src/components/NexusForm.js +0 -128
- package/dist/es/react/src/components/NexusForm.js.map +0 -1
- package/dist/es/react/src/components/NexusFormProvider.js +0 -19
- package/dist/es/react/src/components/NexusFormProvider.js.map +0 -1
- package/dist/es/react/src/components/NexusLayout.js +0 -49
- package/dist/es/react/src/components/NexusLayout.js.map +0 -1
- package/dist/es/react/src/components/NexusObject.js +0 -65
- package/dist/es/react/src/components/NexusObject.js.map +0 -1
- package/dist/es/react/src/contexts/FieldInheritContext.js +0 -6
- package/dist/es/react/src/contexts/FieldInheritContext.js.map +0 -1
- package/dist/es/react/src/contexts/GridContext.js +0 -6
- package/dist/es/react/src/contexts/GridContext.js.map +0 -1
- package/dist/es/react/src/contexts/LayoutConfigContext.js +0 -6
- package/dist/es/react/src/contexts/LayoutConfigContext.js.map +0 -1
- package/dist/es/react/src/contexts/NexusContext.js +0 -13
- package/dist/es/react/src/contexts/NexusContext.js.map +0 -1
- package/dist/es/react/src/hooks/useForm.js +0 -13
- package/dist/es/react/src/hooks/useForm.js.map +0 -1
- package/dist/es/react/src/utils/renderTreeNode.js +0 -18
- package/dist/es/react/src/utils/renderTreeNode.js.map +0 -1
- package/dist/es/react/src/utils/resolveColSpan.js +0 -10
- package/dist/es/react/src/utils/resolveColSpan.js.map +0 -1
- package/src/Canvas.tsx +0 -1111
- package/src/Designer.css +0 -206
- package/src/Designer.tsx +0 -254
- package/src/DesignerContext.tsx +0 -192
- package/src/Palette.tsx +0 -261
- package/src/PropertyPanel.tsx +0 -486
- package/src/ResizablePanel.tsx +0 -210
- package/src/catalog.ts +0 -527
- package/src/index.ts +0 -25
- package/src/property/basic-property.ts +0 -126
- package/src/schemaUtils.test.ts +0 -261
- package/src/schemaUtils.ts +0 -627
- package/src/types.ts +0 -38
- package/src/vite-env.d.ts +0 -1
- package/src/widgets/BindEditor.tsx +0 -105
- package/src/widgets/CodeEditor.tsx +0 -114
- package/src/widgets/DefaultEditor.tsx +0 -73
- package/src/widgets/DependenciesEditor.tsx +0 -56
- package/src/widgets/EnumEditor.tsx +0 -66
- package/src/widgets/ExpressionBuilder.tsx +0 -509
- package/src/widgets/ExpressionSwitch.tsx +0 -62
- package/src/widgets/OptionsEditor.tsx +0 -141
- package/src/widgets/ReactionsEditor.tsx +0 -532
- package/src/widgets/RemoteDataEditor.tsx +0 -382
- package/src/widgets/ValidateEditor.tsx +0 -162
- package/src/widgets/expressionModel.test.ts +0 -262
- package/src/widgets/expressionModel.ts +0 -573
- package/src/widgets/index.ts +0 -45
- package/src/widgets/reactionsModel.ts +0 -190
- package/src/widgets/useFormDataFields.ts +0 -21
package/dist/es/Palette.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Palette.js","sources":["../../src/Palette.tsx"],"sourcesContent":["// ============================================================================\n// @xbeeant/form-engine-designer — 左侧组件目录面板\n// ============================================================================\n\nimport type { SchemaNode } from '@xbeeant/form-engine';\nimport { Collapse, Input } from 'antd';\nimport type { DragEvent } from 'react';\nimport { useCallback, useMemo, useState } from 'react';\nimport { useDesigner } from './DesignerContext';\nimport {\n generateKey,\n getNodeAtProperties,\n getPropertiesOf,\n} from './schemaUtils';\nimport type { CatalogItem, FieldDef } from './types';\n\n// 拖拽负载:palette 组件目录项 or 外部字段定义\nexport interface PaletteDragPayload {\n source: 'palette';\n catalogItem: CatalogItem;\n}\nexport interface FieldDefDragPayload {\n source: 'fieldDef';\n fieldDef: FieldDef;\n}\nexport type PaletteDragData = PaletteDragPayload | FieldDefDragPayload;\n\n// 面板类型 → 允许的唯一父容器类型(面板不能直接添加到根或普通容器)\nconst PANE_PARENT_TYPE: Record<string, string> = {\n tabPane: 'tabs',\n collapsePanel: 'collapse',\n step: 'steps',\n};\n\nconst isPaneItem = (item: CatalogItem): boolean =>\n item.category === 'layout' && !!PANE_PARENT_TYPE[item.layoutType ?? ''];\n\nfunction PaletteItem({\n item,\n onAdd,\n}: {\n item: CatalogItem;\n onAdd: (item: CatalogItem) => void;\n}) {\n const handleDragStart = (e: DragEvent<HTMLDivElement>) => {\n const payload: PaletteDragPayload = {\n source: 'palette',\n catalogItem: item,\n };\n e.dataTransfer.setData('application/json', JSON.stringify(payload));\n e.dataTransfer.effectAllowed = 'copy';\n };\n\n // 面板类组件只能放入对应容器,点击/拖拽提示差异化\n const paneParent = isPaneItem(item)\n ? PANE_PARENT_TYPE[item.layoutType ?? '']\n : undefined;\n const title = paneParent\n ? `拖拽「${item.label}」到「${paneParent}」容器中,或选中容器后点击`\n : `点击添加或拖拽「${item.label}」到画布`;\n\n return (\n <div\n className='group flex flex-col items-center gap-1 rounded-lg border border-[#f0f0f0] bg-white px-1 py-2 cursor-grab select-none transition-all hover:-translate-y-px hover:border-[#1677ff] hover:shadow-[0_2px_8px_rgba(22,119,255,0.12)] active:cursor-grabbing'\n draggable\n onDragStart={handleDragStart}\n onClick={() => onAdd(item)}\n title={title}\n >\n <span className='flex h-7 w-7 items-center justify-center rounded-md bg-[#f5f7fa] text-[15px] transition-colors group-hover:bg-[#e8f1ff]'>\n {item.icon}\n </span>\n <span className='w-full truncate text-center text-xs text-[#666] transition-colors group-hover:text-[#1677ff]'>\n {item.label}\n </span>\n </div>\n );\n}\n\nfunction FieldDefItem({ field }: { field: FieldDef }) {\n const handleDragStart = (e: DragEvent<HTMLDivElement>) => {\n const payload: FieldDefDragPayload = {\n source: 'fieldDef',\n fieldDef: field,\n };\n e.dataTransfer.setData('application/json', JSON.stringify(payload));\n e.dataTransfer.effectAllowed = 'copy';\n };\n\n return (\n <div\n className='flex items-center gap-2 rounded-lg border border-[#f0f0f0] bg-white px-2 py-1.5 cursor-grab select-none transition-all hover:-translate-y-px hover:border-[#1677ff] hover:shadow-[0_2px_8px_rgba(22,119,255,0.12)] active:cursor-grabbing'\n draggable\n onDragStart={handleDragStart}\n title={`id: ${field.id} · widget: ${field.widget}`}\n >\n <span className='flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-md bg-[#f5f7fa] text-[13px]'>\n 🔧\n </span>\n <span className='truncate text-xs text-[#666]'>{field.name}</span>\n </div>\n );\n}\n\nexport function Palette() {\n const {\n schema,\n selectedPath,\n addNode,\n fields,\n widgetCatalog,\n layoutCatalog,\n } = useDesigner();\n const [keyword, setKeyword] = useState('');\n\n const handleAdd = useCallback(\n (item: CatalogItem) => {\n const base = item.widget || item.layoutType || 'field';\n // 面板类组件只能放入对应容器:点击时若已选中匹配容器则加入,否则忽略\n const paneParentType = isPaneItem(item)\n ? PANE_PARENT_TYPE[item.layoutType ?? '']\n : undefined;\n if (paneParentType) {\n if (!selectedPath || selectedPath.length === 0) {\n return;\n }\n const parent = getNodeAtProperties(schema.properties, selectedPath);\n if (!parent || parent.type !== paneParentType) {\n return;\n }\n const parentProps = getPropertiesOf(parent);\n if (!parentProps) {\n return;\n }\n const key = generateKey(parentProps, base);\n addNode(selectedPath, key, item.createNode() as unknown as SchemaNode);\n return;\n }\n const key = generateKey(schema.properties, base);\n const node = item.createNode() as unknown as SchemaNode;\n addNode([], key, node);\n },\n [schema, addNode, selectedPath],\n );\n\n const kw = keyword.trim().toLowerCase();\n\n const widgetItems = useMemo(\n () =>\n widgetCatalog\n .filter((item) => item.label.toLowerCase().includes(kw))\n .map((item) => (\n <PaletteItem key={item.widget} item={item} onAdd={handleAdd} />\n )),\n [widgetCatalog, kw, handleAdd],\n );\n\n const layoutItems = useMemo(\n () =>\n layoutCatalog\n .filter((item) => item.label.toLowerCase().includes(kw))\n .map((item) => (\n <PaletteItem key={item.layoutType} item={item} onAdd={handleAdd} />\n )),\n [layoutCatalog, kw, handleAdd],\n );\n\n const fieldItems = useMemo(\n () =>\n (fields ?? [])\n .filter((field) => field.name.toLowerCase().includes(kw))\n .map((field) => <FieldDefItem key={field.id} field={field} />),\n [fields, kw],\n );\n\n const sectionGrid = (items: React.ReactNode[], hasMore: boolean) =>\n items.length > 0 ? (\n <div className='grid grid-cols-2 gap-1.5 px-1 pb-2'>{items}</div>\n ) : (\n <div className='py-3 text-center text-xs text-[#c0c4cc]'>\n {hasMore ? '无匹配组件' : '暂无组件'}\n </div>\n );\n\n const collapseItems = [\n {\n key: 'widgets',\n label: (\n <span className='flex w-full items-center justify-between pr-1'>\n <span>表单组件</span>\n <span className='rounded-full bg-[#f0f0f0] px-1.5 py-px text-[11px] text-[#999]'>\n {widgetItems.length}\n </span>\n </span>\n ),\n children: sectionGrid(widgetItems, true),\n },\n {\n key: 'layouts',\n label: (\n <span className='flex w-full items-center justify-between pr-1'>\n <span>布局组件</span>\n <span className='rounded-full bg-[#f0f0f0] px-1.5 py-px text-[11px] text-[#999]'>\n {layoutItems.length}\n </span>\n </span>\n ),\n children: sectionGrid(layoutItems, true),\n },\n ];\n\n // 仅当传入 fields 时显示「字段列表」分组\n if (fields && fields.length > 0) {\n collapseItems.push({\n key: 'fieldList',\n label: (\n <span className='flex w-full items-center justify-between pr-1'>\n <span>字段列表</span>\n <span className='rounded-full bg-[#f0f0f0] px-1.5 py-px text-[11px] text-[#999]'>\n {fieldItems.length}\n </span>\n </span>\n ),\n children: (\n <div className='flex flex-col gap-1.5 px-1 pb-2'>\n {fieldItems.length > 0 ? (\n fieldItems\n ) : (\n <div className='py-3 text-center text-xs text-[#c0c4cc]'>\n 无匹配字段\n </div>\n )}\n </div>\n ),\n });\n }\n\n return (\n <div className='flex h-full flex-col border-r border-[#f0f0f0] bg-[#f7f8fa]'>\n <div className='px-3 pb-2 pt-3'>\n <Input\n size='small'\n allowClear\n prefix={<span className='text-xs text-[#bbb]'>🔍</span>}\n placeholder='搜索组件…'\n value={keyword}\n onChange={(e) => setKeyword(e.target.value)}\n className='nexus-palette-search'\n />\n </div>\n <div className='flex-1 overflow-y-auto px-2 pb-3'>\n <Collapse\n className='nexus-palette-collapse'\n expandIconPlacement='end'\n defaultActiveKey={['widgets', 'layouts']}\n items={collapseItems}\n />\n </div>\n </div>\n );\n}\n"],"names":["PANE_PARENT_TYPE","isPaneItem","item","PaletteItem","onAdd","handleDragStart","e","payload","paneParent","title","jsxs","jsx","FieldDefItem","field","Palette","schema","selectedPath","addNode","fields","widgetCatalog","layoutCatalog","useDesigner","keyword","setKeyword","useState","handleAdd","useCallback","paneParentType","parent","getNodeAtProperties","parentProps","getPropertiesOf","key","generateKey","node","kw","widgetItems","useMemo","layoutItems","fieldItems","sectionGrid","items","hasMore","collapseItems","Input","Collapse"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"palette.js","sources":["../../src/palette.tsx"],"sourcesContent":["// ============================================================================\n// @xbeeant/form-engine-designer — 左侧组件目录面板\n// ============================================================================\n\nimport type { SchemaNode } from '@xbeeant/form-engine';\nimport { Collapse, Input } from 'antd';\nimport type { DragEvent } from 'react';\nimport { useCallback, useMemo, useState } from 'react';\nimport { useDesigner } from './designer-context';\nimport {\n generateKey,\n getNodeAtProperties,\n getPropertiesOf,\n} from './schema-utils';\nimport type { CatalogItem, FieldDef } from './types';\n\n// 拖拽负载:palette 组件目录项 or 外部字段定义\nexport interface PaletteDragPayload {\n source: 'palette';\n catalogItem: CatalogItem;\n}\nexport interface FieldDefDragPayload {\n source: 'fieldDef';\n fieldDef: FieldDef;\n}\nexport type PaletteDragData = PaletteDragPayload | FieldDefDragPayload;\n\n// 面板类型 → 允许的唯一父容器类型(面板不能直接添加到根或普通容器)\nconst PANE_PARENT_TYPE: Record<string, string> = {\n tabPane: 'tabs',\n collapsePanel: 'collapse',\n step: 'steps',\n};\n\nconst isPaneItem = (item: CatalogItem): boolean =>\n item.category === 'layout' && !!PANE_PARENT_TYPE[item.layoutType ?? ''];\n\nfunction PaletteItem({\n item,\n onAdd,\n}: {\n item: CatalogItem;\n onAdd: (item: CatalogItem) => void;\n}) {\n const handleDragStart = (e: DragEvent<HTMLDivElement>) => {\n const payload: PaletteDragPayload = {\n source: 'palette',\n catalogItem: item,\n };\n e.dataTransfer.setData('application/json', JSON.stringify(payload));\n e.dataTransfer.effectAllowed = 'copy';\n };\n\n // 面板类组件只能放入对应容器,点击/拖拽提示差异化\n const paneParent = isPaneItem(item)\n ? PANE_PARENT_TYPE[item.layoutType ?? '']\n : undefined;\n const title = paneParent\n ? `拖拽「${item.label}」到「${paneParent}」容器中,或选中容器后点击`\n : `点击添加或拖拽「${item.label}」到画布`;\n\n return (\n <div\n className='group flex flex-col items-center gap-1 rounded-lg border border-[#f0f0f0] bg-white px-1 py-2 cursor-grab select-none transition-all hover:-translate-y-px hover:border-[#1677ff] hover:shadow-[0_2px_8px_rgba(22,119,255,0.12)] active:cursor-grabbing'\n draggable\n onDragStart={handleDragStart}\n onClick={() => onAdd(item)}\n title={title}\n >\n <span className='flex h-7 w-7 items-center justify-center rounded-md bg-[#f5f7fa] text-[15px] transition-colors group-hover:bg-[#e8f1ff]'>\n {item.icon}\n </span>\n <span className='w-full truncate text-center text-xs text-[#666] transition-colors group-hover:text-[#1677ff]'>\n {item.label}\n </span>\n </div>\n );\n}\n\nfunction FieldDefItem({ field }: { field: FieldDef }) {\n const handleDragStart = (e: DragEvent<HTMLDivElement>) => {\n const payload: FieldDefDragPayload = {\n source: 'fieldDef',\n fieldDef: field,\n };\n e.dataTransfer.setData('application/json', JSON.stringify(payload));\n e.dataTransfer.effectAllowed = 'copy';\n };\n\n return (\n <div\n className='flex items-center gap-2 rounded-lg border border-[#f0f0f0] bg-white px-2 py-1.5 cursor-grab select-none transition-all hover:-translate-y-px hover:border-[#1677ff] hover:shadow-[0_2px_8px_rgba(22,119,255,0.12)] active:cursor-grabbing'\n draggable\n onDragStart={handleDragStart}\n title={`id: ${field.id} · widget: ${field.widget}`}\n >\n <span className='flex h-6 w-6 flex-shrink-0 items-center justify-center rounded-md bg-[#f5f7fa] text-[13px]'>\n 🔧\n </span>\n <span className='truncate text-xs text-[#666]'>{field.name}</span>\n </div>\n );\n}\n\nexport function Palette() {\n const {\n schema,\n selectedPath,\n addNode,\n fields,\n widgetCatalog,\n layoutCatalog,\n } = useDesigner();\n const [keyword, setKeyword] = useState('');\n\n const handleAdd = useCallback(\n (item: CatalogItem) => {\n const base = item.widget || item.layoutType || 'field';\n // 面板类组件只能放入对应容器:点击时若已选中匹配容器则加入,否则忽略\n const paneParentType = isPaneItem(item)\n ? PANE_PARENT_TYPE[item.layoutType ?? '']\n : undefined;\n if (paneParentType) {\n if (!selectedPath || selectedPath.length === 0) {\n return;\n }\n const parent = getNodeAtProperties(schema.properties, selectedPath);\n if (!parent || parent.type !== paneParentType) {\n return;\n }\n const parentProps = getPropertiesOf(parent);\n if (!parentProps) {\n return;\n }\n const key = generateKey(parentProps, base);\n addNode(selectedPath, key, item.createNode() as unknown as SchemaNode);\n return;\n }\n const key = generateKey(schema.properties, base);\n const node = item.createNode() as unknown as SchemaNode;\n addNode([], key, node);\n },\n [schema, addNode, selectedPath],\n );\n\n const kw = keyword.trim().toLowerCase();\n\n const widgetItems = useMemo(\n () =>\n widgetCatalog\n .filter((item) => item.label.toLowerCase().includes(kw))\n .map((item) => (\n <PaletteItem key={item.widget} item={item} onAdd={handleAdd} />\n )),\n [widgetCatalog, kw, handleAdd],\n );\n\n const layoutItems = useMemo(\n () =>\n layoutCatalog\n .filter((item) => item.label.toLowerCase().includes(kw))\n .map((item) => (\n <PaletteItem key={item.layoutType} item={item} onAdd={handleAdd} />\n )),\n [layoutCatalog, kw, handleAdd],\n );\n\n const fieldItems = useMemo(\n () =>\n (fields ?? [])\n .filter((field) => field.name.toLowerCase().includes(kw))\n .map((field) => <FieldDefItem key={field.id} field={field} />),\n [fields, kw],\n );\n\n const sectionGrid = (items: React.ReactNode[], hasMore: boolean) =>\n items.length > 0 ? (\n <div className='grid grid-cols-2 gap-1.5 px-1 pb-2'>{items}</div>\n ) : (\n <div className='py-3 text-center text-xs text-[#c0c4cc]'>\n {hasMore ? '无匹配组件' : '暂无组件'}\n </div>\n );\n\n const collapseItems = [\n {\n key: 'widgets',\n label: (\n <span className='flex w-full items-center justify-between pr-1'>\n <span>表单组件</span>\n <span className='rounded-full bg-[#f0f0f0] px-1.5 py-px text-[11px] text-[#999]'>\n {widgetItems.length}\n </span>\n </span>\n ),\n children: sectionGrid(widgetItems, true),\n },\n {\n key: 'layouts',\n label: (\n <span className='flex w-full items-center justify-between pr-1'>\n <span>布局组件</span>\n <span className='rounded-full bg-[#f0f0f0] px-1.5 py-px text-[11px] text-[#999]'>\n {layoutItems.length}\n </span>\n </span>\n ),\n children: sectionGrid(layoutItems, true),\n },\n ];\n\n // 仅当传入 fields 时显示「字段列表」分组\n if (fields && fields.length > 0) {\n collapseItems.push({\n key: 'fieldList',\n label: (\n <span className='flex w-full items-center justify-between pr-1'>\n <span>字段列表</span>\n <span className='rounded-full bg-[#f0f0f0] px-1.5 py-px text-[11px] text-[#999]'>\n {fieldItems.length}\n </span>\n </span>\n ),\n children: (\n <div className='flex flex-col gap-1.5 px-1 pb-2'>\n {fieldItems.length > 0 ? (\n fieldItems\n ) : (\n <div className='py-3 text-center text-xs text-[#c0c4cc]'>\n 无匹配字段\n </div>\n )}\n </div>\n ),\n });\n }\n\n return (\n <div className='flex h-full flex-col border-r border-[#f0f0f0] bg-[#f7f8fa]'>\n <div className='px-3 pb-2 pt-3'>\n <Input\n size='small'\n allowClear\n prefix={<span className='text-xs text-[#bbb]'>🔍</span>}\n placeholder='搜索组件…'\n value={keyword}\n onChange={(e) => setKeyword(e.target.value)}\n className='nexus-palette-search'\n />\n </div>\n <div className='flex-1 overflow-y-auto px-2 pb-3'>\n <Collapse\n className='nexus-palette-collapse'\n expandIconPlacement='end'\n defaultActiveKey={['widgets', 'layouts']}\n items={collapseItems}\n />\n </div>\n </div>\n );\n}\n"],"names":["PANE_PARENT_TYPE","isPaneItem","item","PaletteItem","onAdd","handleDragStart","e","payload","paneParent","title","jsxs","jsx","FieldDefItem","field","Palette","schema","selectedPath","addNode","fields","widgetCatalog","layoutCatalog","useDesigner","keyword","setKeyword","useState","handleAdd","useCallback","paneParentType","parent","getNodeAtProperties","parentProps","getPropertiesOf","key","generateKey","node","kw","widgetItems","useMemo","layoutItems","fieldItems","sectionGrid","items","hasMore","collapseItems","Input","Collapse"],"mappings":"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"}
|
package/dist/es/PropertyPanel.js
CHANGED
|
@@ -1,43 +1,41 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
function H({
|
|
13
|
-
schema: n,
|
|
1
|
+
import { jsxs as c, jsx as n } from "react/jsx-runtime";
|
|
2
|
+
import { useForm as W, NexusForm as E } from "@xbeeant/form-engine-react";
|
|
3
|
+
import { registerAntdUI as T } from "@xbeeant/form-engine-ui";
|
|
4
|
+
import { Input as A } from "antd";
|
|
5
|
+
import { useMemo as P, useCallback as b, useState as D, useRef as C, useEffect as K } from "react";
|
|
6
|
+
import { useDesigner as B } from "./DesignerContext.js";
|
|
7
|
+
import { dependencyPropertyFields as I, reactionPropertyFields as M, validationPropertyFields as $, commonPropertyFields as z } from "./property/basic-property.js";
|
|
8
|
+
import { getNodeAtProperties as U, extractFormLevelConfig as q, flattenNodeForPropertyEditor as j, diffPropertyPatch as G } from "./schemaUtils.js";
|
|
9
|
+
import { propertyWidgets as H } from "./widgets/index.js";
|
|
10
|
+
function J({
|
|
11
|
+
schema: o,
|
|
14
12
|
initialValues: e,
|
|
15
13
|
onValuesChange: r
|
|
16
14
|
}) {
|
|
17
|
-
const [
|
|
18
|
-
|
|
19
|
-
const
|
|
20
|
-
(t,
|
|
21
|
-
u &&
|
|
15
|
+
const [s] = W(), a = s._getEngine();
|
|
16
|
+
T(a);
|
|
17
|
+
const i = C(/* @__PURE__ */ new Set()), d = b(
|
|
18
|
+
(t, l, u) => {
|
|
19
|
+
u && i.current.add(u), r(
|
|
22
20
|
t,
|
|
23
|
-
|
|
21
|
+
i.current
|
|
24
22
|
);
|
|
25
23
|
},
|
|
26
24
|
[r]
|
|
27
25
|
);
|
|
28
|
-
return /* @__PURE__ */
|
|
29
|
-
|
|
26
|
+
return /* @__PURE__ */ n(
|
|
27
|
+
E,
|
|
30
28
|
{
|
|
31
29
|
footer: !1,
|
|
32
|
-
form:
|
|
33
|
-
schema:
|
|
30
|
+
form: s,
|
|
31
|
+
schema: o,
|
|
34
32
|
initialValues: e,
|
|
35
|
-
watch: { "#":
|
|
36
|
-
widgets:
|
|
33
|
+
watch: { "#": d },
|
|
34
|
+
widgets: H
|
|
37
35
|
}
|
|
38
36
|
);
|
|
39
37
|
}
|
|
40
|
-
const
|
|
38
|
+
const F = {
|
|
41
39
|
displayType: {
|
|
42
40
|
widget: "select",
|
|
43
41
|
type: "string",
|
|
@@ -80,7 +78,7 @@ const j = {
|
|
|
80
78
|
title: "每行显示列数(column)",
|
|
81
79
|
default: 1
|
|
82
80
|
}
|
|
83
|
-
},
|
|
81
|
+
}, Q = {
|
|
84
82
|
column: { widget: "number", type: "number", title: "列数(column)" },
|
|
85
83
|
gap: { widget: "number", type: "number", title: "间距(gap)" },
|
|
86
84
|
direction: {
|
|
@@ -95,63 +93,64 @@ const j = {
|
|
|
95
93
|
}
|
|
96
94
|
}
|
|
97
95
|
};
|
|
98
|
-
function m(
|
|
96
|
+
function m(o, e, r) {
|
|
99
97
|
return {
|
|
100
|
-
[
|
|
98
|
+
[o]: {
|
|
101
99
|
type: "collapsePanel",
|
|
102
100
|
title: e,
|
|
103
101
|
properties: r
|
|
104
102
|
}
|
|
105
103
|
};
|
|
106
104
|
}
|
|
107
|
-
function
|
|
108
|
-
const [
|
|
109
|
-
if (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
105
|
+
function X({ oldKey: o, locked: e, onRename: r }) {
|
|
106
|
+
const [s, a] = D(o), i = C(o);
|
|
107
|
+
if (K(() => {
|
|
108
|
+
o !== i.current && (i.current = o, a(o));
|
|
109
|
+
}, [o]), e)
|
|
110
|
+
return /* @__PURE__ */ c("div", { className: "mb-3 flex items-center justify-between gap-2 rounded-lg border border-[#f0f0f0] bg-[#fafafa] px-3 py-2", children: [
|
|
111
|
+
/* @__PURE__ */ c("div", { className: "min-w-0", children: [
|
|
112
|
+
/* @__PURE__ */ n("div", { className: "mb-0.5 text-[11px] text-[#999]", children: "字段标识(key)" }),
|
|
113
|
+
/* @__PURE__ */ n("code", { className: "break-all font-mono text-[13px] text-[#333]", children: o })
|
|
114
114
|
] }),
|
|
115
|
-
/* @__PURE__ */
|
|
115
|
+
/* @__PURE__ */ n("span", { className: "shrink-0 rounded bg-[#f0f0f0] px-1.5 py-0.5 text-[11px] text-[#999]", children: "🔒 锁定" })
|
|
116
116
|
] });
|
|
117
|
-
const
|
|
118
|
-
|
|
117
|
+
const d = (t) => {
|
|
118
|
+
i.current = t, a(t), r(t);
|
|
119
119
|
};
|
|
120
|
-
return /* @__PURE__ */
|
|
121
|
-
/* @__PURE__ */
|
|
122
|
-
/* @__PURE__ */
|
|
123
|
-
|
|
120
|
+
return /* @__PURE__ */ c("div", { className: "mb-3", children: [
|
|
121
|
+
/* @__PURE__ */ n("div", { className: "mb-1.5 text-[11px] text-[#999]", children: "字段标识(key)" }),
|
|
122
|
+
/* @__PURE__ */ n(
|
|
123
|
+
A,
|
|
124
124
|
{
|
|
125
125
|
size: "small",
|
|
126
|
-
value:
|
|
127
|
-
onChange: (
|
|
128
|
-
const
|
|
129
|
-
|
|
126
|
+
value: s,
|
|
127
|
+
onChange: (t) => {
|
|
128
|
+
const l = (t.target.value || "").trim();
|
|
129
|
+
d(l);
|
|
130
130
|
},
|
|
131
|
-
autoFocus: !0,
|
|
132
131
|
className: "nexus-key-input"
|
|
133
132
|
}
|
|
134
133
|
),
|
|
135
|
-
/* @__PURE__ */
|
|
134
|
+
/* @__PURE__ */ n("div", { className: "mt-1 text-[11px] text-[#c0c4cc]", children: "用于数据路径与联动引用,修改后自动迁移子节点" })
|
|
136
135
|
] });
|
|
137
136
|
}
|
|
138
|
-
function
|
|
137
|
+
function ce() {
|
|
139
138
|
const {
|
|
140
|
-
schema:
|
|
139
|
+
schema: o,
|
|
141
140
|
selectedPath: e,
|
|
142
141
|
updateNode: r,
|
|
143
|
-
renameNode:
|
|
144
|
-
selectNode:
|
|
145
|
-
setSchema:
|
|
146
|
-
propertySchemaMap:
|
|
147
|
-
} =
|
|
148
|
-
if (
|
|
142
|
+
renameNode: s,
|
|
143
|
+
selectNode: a,
|
|
144
|
+
setSchema: i,
|
|
145
|
+
propertySchemaMap: d
|
|
146
|
+
} = B(), t = e && e.length > 0 ? U(o.properties, e) : void 0, l = !e || e.length === 0, u = `node_${(e || []).join("_")}_${t?.type || "root"}`, g = e?.[e.length - 1] ?? "", L = t?._lockedKey === !0, x = t ? t.widget || t.type : null, R = P(() => {
|
|
147
|
+
if (l)
|
|
149
148
|
return {
|
|
150
149
|
type: "object",
|
|
151
|
-
properties:
|
|
150
|
+
properties: F,
|
|
152
151
|
displayType: "column"
|
|
153
152
|
};
|
|
154
|
-
const p =
|
|
153
|
+
const p = d[x] || Q;
|
|
155
154
|
return {
|
|
156
155
|
type: "object",
|
|
157
156
|
properties: {
|
|
@@ -171,7 +170,7 @@ function ae() {
|
|
|
171
170
|
...m(
|
|
172
171
|
"sectionCommon",
|
|
173
172
|
"通用属性",
|
|
174
|
-
|
|
173
|
+
z
|
|
175
174
|
),
|
|
176
175
|
...m(
|
|
177
176
|
"sectionFieldProps",
|
|
@@ -181,71 +180,71 @@ function ae() {
|
|
|
181
180
|
...m(
|
|
182
181
|
"sectionValidation",
|
|
183
182
|
"校验配置",
|
|
184
|
-
|
|
183
|
+
$
|
|
185
184
|
),
|
|
186
185
|
...m(
|
|
187
186
|
"sectionReaction",
|
|
188
187
|
"联动配置",
|
|
189
|
-
|
|
188
|
+
M
|
|
190
189
|
),
|
|
191
190
|
...m(
|
|
192
191
|
"sectionDependency",
|
|
193
192
|
"依赖配置",
|
|
194
|
-
|
|
193
|
+
I
|
|
195
194
|
)
|
|
196
195
|
}
|
|
197
196
|
}
|
|
198
197
|
},
|
|
199
198
|
displayType: "column"
|
|
200
199
|
};
|
|
201
|
-
}, [
|
|
202
|
-
() =>
|
|
203
|
-
|
|
204
|
-
Object.keys(
|
|
200
|
+
}, [l, x, d]), f = P(
|
|
201
|
+
() => q(
|
|
202
|
+
o,
|
|
203
|
+
Object.keys(F)
|
|
205
204
|
),
|
|
206
|
-
[
|
|
207
|
-
),
|
|
208
|
-
(p,
|
|
209
|
-
const
|
|
205
|
+
[o]
|
|
206
|
+
), _ = b(
|
|
207
|
+
(p, S) => {
|
|
208
|
+
const V = t ? j(
|
|
210
209
|
t
|
|
211
|
-
) : f, y =
|
|
210
|
+
) : f, y = G(V, p, S);
|
|
212
211
|
if (Object.keys(y).length === 0)
|
|
213
212
|
return;
|
|
214
213
|
if (!e || e.length === 0) {
|
|
215
|
-
const h = { ...
|
|
214
|
+
const h = { ...o };
|
|
216
215
|
for (const [k, N] of Object.entries(y))
|
|
217
216
|
N === void 0 ? delete h[k] : h[k] = N;
|
|
218
|
-
|
|
217
|
+
i(h);
|
|
219
218
|
return;
|
|
220
219
|
}
|
|
221
|
-
const { key:
|
|
220
|
+
const { key: Y, ...v } = y;
|
|
222
221
|
Object.keys(v).length > 0 && r(e, v);
|
|
223
222
|
},
|
|
224
223
|
[
|
|
225
224
|
e,
|
|
226
225
|
r,
|
|
227
|
-
|
|
228
|
-
|
|
226
|
+
i,
|
|
227
|
+
o,
|
|
229
228
|
t,
|
|
230
229
|
f
|
|
231
230
|
]
|
|
232
|
-
),
|
|
231
|
+
), O = b(
|
|
233
232
|
(p) => {
|
|
234
|
-
!e || e.length === 0 ||
|
|
233
|
+
!e || e.length === 0 || s(e, p);
|
|
235
234
|
},
|
|
236
|
-
[e,
|
|
235
|
+
[e, s]
|
|
237
236
|
), w = t ? (t.widget || t.type || "").toLowerCase() : "";
|
|
238
|
-
return /* @__PURE__ */
|
|
239
|
-
/* @__PURE__ */
|
|
240
|
-
/* @__PURE__ */
|
|
241
|
-
!
|
|
237
|
+
return /* @__PURE__ */ c("div", { className: "flex h-full flex-col border-l border-[#f0f0f0] bg-white", children: [
|
|
238
|
+
/* @__PURE__ */ c("div", { className: "flex items-center justify-between border-b border-[#f0f0f0] px-4 py-2.5", children: [
|
|
239
|
+
/* @__PURE__ */ c("div", { className: "pl-5 flex min-w-0 items-center gap-1 h-6", children: [
|
|
240
|
+
!l && /* @__PURE__ */ n(
|
|
242
241
|
"button",
|
|
243
242
|
{
|
|
244
243
|
type: "button",
|
|
245
|
-
onClick: () =>
|
|
244
|
+
onClick: () => a(null),
|
|
246
245
|
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]",
|
|
247
246
|
title: "返回表单属性",
|
|
248
|
-
children: /* @__PURE__ */
|
|
247
|
+
children: /* @__PURE__ */ n(
|
|
249
248
|
"svg",
|
|
250
249
|
{
|
|
251
250
|
width: "12",
|
|
@@ -257,32 +256,32 @@ function ae() {
|
|
|
257
256
|
strokeLinecap: "round",
|
|
258
257
|
strokeLinejoin: "round",
|
|
259
258
|
"aria-hidden": "true",
|
|
260
|
-
children: /* @__PURE__ */
|
|
259
|
+
children: /* @__PURE__ */ n("polyline", { points: "15 18 9 12 15 6" })
|
|
261
260
|
}
|
|
262
261
|
)
|
|
263
262
|
}
|
|
264
263
|
),
|
|
265
|
-
/* @__PURE__ */
|
|
264
|
+
/* @__PURE__ */ n("span", { className: "truncate text-[13px] font-semibold text-[#333]", children: l ? "表单属性" : "节点属性" })
|
|
266
265
|
] }),
|
|
267
|
-
!
|
|
266
|
+
!l && w && /* @__PURE__ */ n("span", { className: "ml-2 shrink-0 rounded-md bg-[#e8f1ff] px-1.5 py-0.5 text-[11px] text-[#1677ff]", children: w })
|
|
268
267
|
] }),
|
|
269
|
-
/* @__PURE__ */
|
|
270
|
-
!
|
|
271
|
-
|
|
268
|
+
/* @__PURE__ */ c("div", { className: "nexus-property-body flex-1 overflow-y-auto px-4 py-3", children: [
|
|
269
|
+
!l && g && /* @__PURE__ */ n(
|
|
270
|
+
X,
|
|
272
271
|
{
|
|
273
272
|
oldKey: g,
|
|
274
|
-
locked:
|
|
275
|
-
onRename:
|
|
273
|
+
locked: L,
|
|
274
|
+
onRename: O
|
|
276
275
|
}
|
|
277
276
|
),
|
|
278
|
-
/* @__PURE__ */
|
|
279
|
-
|
|
277
|
+
/* @__PURE__ */ n(
|
|
278
|
+
J,
|
|
280
279
|
{
|
|
281
|
-
schema:
|
|
282
|
-
initialValues: t ?
|
|
280
|
+
schema: R,
|
|
281
|
+
initialValues: t ? j(
|
|
283
282
|
t
|
|
284
283
|
) : f,
|
|
285
|
-
onValuesChange:
|
|
284
|
+
onValuesChange: _
|
|
286
285
|
},
|
|
287
286
|
u
|
|
288
287
|
)
|
|
@@ -290,6 +289,6 @@ function ae() {
|
|
|
290
289
|
] });
|
|
291
290
|
}
|
|
292
291
|
export {
|
|
293
|
-
|
|
292
|
+
ce as PropertyPanel
|
|
294
293
|
};
|
|
295
294
|
//# 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, useEffect, 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 // 记录已同步到本地 state 的外部 key:仅当外部 oldKey 发生「非本次编辑产生」的\n // 变化(如切换选中节点)时才重置输入框,避免用 key 重建组件导致失焦\n const syncedKeyRef = useRef(oldKey);\n\n useEffect(() => {\n if (oldKey !== syncedKeyRef.current) {\n syncedKeyRef.current = oldKey;\n setValue(oldKey);\n }\n }, [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 syncedKeyRef.current = v;\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 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","syncedKeyRef","useEffect","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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"}
|
package/dist/es/catalog.js
CHANGED
|
@@ -44,10 +44,10 @@ const e = [
|
|
|
44
44
|
label: "下拉选择(远程)",
|
|
45
45
|
icon: "📡",
|
|
46
46
|
category: "widget",
|
|
47
|
-
widget: "
|
|
47
|
+
widget: "remoteSelect",
|
|
48
48
|
createNode: () => ({
|
|
49
49
|
type: "string",
|
|
50
|
-
widget: "
|
|
50
|
+
widget: "remoteSelect",
|
|
51
51
|
title: "下拉选择(远程)",
|
|
52
52
|
remoteData: {
|
|
53
53
|
url: "/api/options",
|
|
@@ -111,10 +111,10 @@ const e = [
|
|
|
111
111
|
label: "多选下拉(远程)",
|
|
112
112
|
icon: "📡",
|
|
113
113
|
category: "widget",
|
|
114
|
-
widget: "
|
|
114
|
+
widget: "remoteMultiSelect",
|
|
115
115
|
createNode: () => ({
|
|
116
116
|
type: "array",
|
|
117
|
-
widget: "
|
|
117
|
+
widget: "remoteMultiSelect",
|
|
118
118
|
title: "多选下拉(远程)",
|
|
119
119
|
remoteData: {
|
|
120
120
|
url: "/api/multi-options",
|
|
@@ -246,10 +246,10 @@ const e = [
|
|
|
246
246
|
label: "自动完成(远程)",
|
|
247
247
|
icon: "📡",
|
|
248
248
|
category: "widget",
|
|
249
|
-
widget: "
|
|
249
|
+
widget: "remoteAutoComplete",
|
|
250
250
|
createNode: () => ({
|
|
251
251
|
type: "string",
|
|
252
|
-
widget: "
|
|
252
|
+
widget: "remoteAutoComplete",
|
|
253
253
|
title: "自动完成(远程)",
|
|
254
254
|
remoteData: {
|
|
255
255
|
url: "/api/suggestions",
|
|
@@ -276,10 +276,10 @@ const e = [
|
|
|
276
276
|
label: "级联选择(远程)",
|
|
277
277
|
icon: "📡",
|
|
278
278
|
category: "widget",
|
|
279
|
-
widget: "
|
|
279
|
+
widget: "remoteCascader",
|
|
280
280
|
createNode: () => ({
|
|
281
281
|
type: "array",
|
|
282
|
-
widget: "
|
|
282
|
+
widget: "remoteCascader",
|
|
283
283
|
title: "级联选择(远程)",
|
|
284
284
|
remoteData: {
|
|
285
285
|
url: "/api/cascader/nodes",
|
|
@@ -311,10 +311,10 @@ const e = [
|
|
|
311
311
|
label: "提及(远程)",
|
|
312
312
|
icon: "📡",
|
|
313
313
|
category: "widget",
|
|
314
|
-
widget: "
|
|
314
|
+
widget: "remoteMentions",
|
|
315
315
|
createNode: () => ({
|
|
316
316
|
type: "string",
|
|
317
|
-
widget: "
|
|
317
|
+
widget: "remoteMentions",
|
|
318
318
|
title: "提及(远程)",
|
|
319
319
|
remoteData: {
|
|
320
320
|
url: "/api/users/suggestions",
|
|
@@ -506,6 +506,13 @@ const e = [
|
|
|
506
506
|
category: "layout",
|
|
507
507
|
layoutType: "space",
|
|
508
508
|
createNode: () => ({ type: "space", properties: {} })
|
|
509
|
+
},
|
|
510
|
+
{
|
|
511
|
+
label: "透传容器",
|
|
512
|
+
icon: "📶",
|
|
513
|
+
category: "layout",
|
|
514
|
+
layoutType: "passThrough",
|
|
515
|
+
createNode: () => ({ type: "passThrough", properties: {} })
|
|
509
516
|
}
|
|
510
517
|
];
|
|
511
518
|
export {
|