From a292624c0872a29e907c68d5615884039eb70996 Mon Sep 17 00:00:00 2001 From: hypercross Date: Fri, 27 Feb 2026 13:00:24 +0800 Subject: [PATCH] feat: property editor --- .idea/indexLayout.xml | 8 + .idea/vcs.xml | 6 + src/components/FieldEditor.tsx | 156 ++++++++++++++++++++ src/components/editor-panel.tsx | 41 +++-- src/components/hooks/types.ts | 58 ++++++++ src/components/hooks/use-property-editor.ts | 91 ++++++++++++ src/components/md-table.tsx | 4 +- 7 files changed, 349 insertions(+), 15 deletions(-) create mode 100644 .idea/indexLayout.xml create mode 100644 .idea/vcs.xml create mode 100644 src/components/FieldEditor.tsx create mode 100644 src/components/hooks/types.ts create mode 100644 src/components/hooks/use-property-editor.ts diff --git a/.idea/indexLayout.xml b/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/components/FieldEditor.tsx b/src/components/FieldEditor.tsx new file mode 100644 index 0000000..ffba7b3 --- /dev/null +++ b/src/components/FieldEditor.tsx @@ -0,0 +1,156 @@ +import {Component, For, Show} from 'solid-js'; +import type { FieldSchema } from './hooks/types'; + +export interface FieldEditorProps { + /** 字段 Schema 定义 */ + field: FieldSchema; + /** 当前值 */ + value: string | number | boolean; + /** 值变化回调 */ + onChange: (value: string | number | boolean) => void; + /** 是否禁用 */ + disabled?: boolean; +} + +/** + * 通用字段编辑器组件 + * 根据字段类型自动渲染合适的表单控件 + */ +export const FieldEditor: Component = (props) => { + const handleChange = (e: Event) => { + const target = e.target as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement; + let value: string | number | boolean; + + if (props.field.type === 'boolean') { + value = (target as HTMLInputElement).checked; + } else if (props.field.type === 'number') { + value = Number(target.value); + } else { + value = target.value; + } + + props.onChange(value); + }; + + const label = props.field.label || props.field.key; + + return ( +
+ + + {/* 字符串输入 */} + + + + + {/* 多行文本输入 */} + +