
Security News
AI Has Taken Over Open Source
Vibe coding at scale is reshaping how packages are created, contributed, and selected across the software supply chain
craft-designer
Advanced tools
一个基于 Craft.js 的可视化、低代码页面设计器 React 组件库,支持拖拽编排、属性编辑、事件绑定、数据源管理、Schema 导入导出。
你可以用配置驱动的方式,从组件库拖拽到画布、编辑属性、绑定事件、接入数据源、导出 Schema,完成「设计 → 编辑 → 预览 → 保存」的完整闭环。
开箱即用:画布缩放、平移、吸附、撤销重做、组件树、属性面板、事件绑定、数据源、Schema 导入导出……这些都已经内置,你不用从零实现。
可配置:通过「组件配置」注册业务组件,就能自动出现在组件库和属性区。工具栏、面板宽度、根画布属性等都可以配置。
可替换:属性面板和顶栏支持完全自定义 UI,同时复用设计器的数据和工具栏等能力。
可集成:onSchemaChange 对接保存、designerRef 编程式读写、locale 与 词条表 对接宿主 i18n。
依赖清晰:peerDependencies 声明 React 与 AntD,产物不重复打包,宿主完全控制版本。
体验细节:缩放画布时控制框 1:1 视觉;拖拽超出画布自动拉回;大量节点下仍保持流畅。
在 React 项目中执行:
npm install craft-designer
需要已有 react、react-dom(^18 或 ^19)和 antd(>=5.0.0)。zustand、@craftjs/core 等内部依赖已打入产物,无需单独安装。
Craft.js API 透传:为避免 Context 双实例问题,
useNode、useEditor、Element等 Craft.js API 应从craft-designer导入,而非直接依赖@craftjs/core。
为每个可编排组件写一份配置,其中 preview 是纯展示用的 React 组件:
{
type: 'Button',
name: '按钮',
preview: () => <button>按钮</button>,
craftConfig: { props: {} },
propertyConfig: { layout: true, style: true },
}
容器类组件若需在画布内编辑,再提供 editorComponent。
在页面中渲染 <Designer />,传入 componentConfigs 即可:
import { Designer } from 'craft-designer';
import 'craft-designer/dist/craft-designer.css';
const configs = [{
type: 'Button',
name: '按钮',
preview: () => <button>按钮</button>,
craftConfig: { props: {} },
propertyConfig: { layout: true, style: true },
}];
export default function Page() {
return <Designer componentConfigs={configs} />;
}
onSchemaChange 回调里拿到最新 Schema,存到后端。designerRef.current?.serialize() 取 JSON。initialSchema 或 deserialize() 还原。renderPropertyPanel。renderHeader,可内嵌 DesignerTool。propertyConfig.business 或 createBusinessProperties。EventSystem 为组件配置交互行为。DataSource 模块注册和消费远程/静态数据。完整示例:playground/configs/DesignerPage/index.tsx,运行 npm run dev 打开 playground 体验。
npm install craft-designer antd
需要在 React 项目(^18 或 ^19)中使用。antd(>=5.0.0)为 peer 依赖,需要单独安装。
面向产品层面的能力说明,便于判断「能做什么、边界在哪」。技术实现见 接入与扩展。
onBeforeDelete 拦截确认。registerComponentIcon / registerComponentIcons)。propertyConfig 配置驱动;支持 dependsOn / dependsValue 条件显隐。renderPropertyPanel 完全替换。sections 按需显隐。initialSchema)、实时通知(onSchemaChange,防抖 300ms)、预览、复制、下载、designerRef 编程式 serialize / deserialize / getHistory。static)和远程请求(fetch)两种类型。requestMode: 'auto'(注册时自动拉取)和 'manual'。useDataSource、useDataSourceOptions、useInlineDataSource)直接在组件内消费。transformToOptions:将接口返回数据转换为下拉框选项。configureDataSourceApi 配置全局请求基址和拦截器。EventContextProvider + useEventContext 提供运行时事件分发。PreviewRenderer 支持预览模式下的事件执行。executeAction / createEventHandler 供自定义场景调用。createLogger(debug) 控制输出级别。locale 支持三种形态(快捷字符串 / 底稿+覆盖 / 宿主全权接管);完整词条见 docs/i18n-keys.md。每个组件可通过 craftConfig.controls 单独配置:可缩放、可旋转、可删除、保持比例。
componentConfigsinterface IComponentConfig {
type: string;
name: string;
group?: string;
icon?: React.ReactNode;
preview: React.ComponentType; // 纯展示组件
editorComponent?: React.ComponentType; // 容器类画布内编辑用
craftConfig?: {
props?: INodeProps;
rules?: { canDrag?, canMoveIn?, canMoveOut? };
controls?: IDesignerControls; // resizable, rotatable, deletable...
};
propertyConfig?: IComponentPropertyConfig;
wrapperOptions?: { wrapper?, wrapperProps? };
isRootConfig?: boolean;
}
propertyConfiginterface IComponentPropertyConfig {
layout?: boolean | string[] | IPropertyConfig[]; // true=全部, false=不展示
style?: boolean | string[] | IPropertyConfig[];
business?: IPropertyConfig[];
}
IPropertyConfig 常用字段:type(text/number/color/select/boolean/object)、category、options、default、dependsOn + dependsValue。
| Prop | 作用 |
|---|---|
componentConfigs | 注册业务组件(必填) |
rootCanvasProps | 根画布:layoutMode、sizePreset、width/height、background |
initialSchema / onSchemaChange | 初始 Schema、变更回调(防抖 300ms) |
designerRef | serialize() / deserialize() / getHistory() |
leftPanel / rightPanel | 左:layout、title、width;右:width |
keyboardShortcuts | false 全关,或 { undoRedo: false } 等 |
locale | 'zh-CN' | 'en-US' | Partial |
示例:rootCanvasProps
<Designer
componentConfigs={myConfigs}
rootCanvasProps={{
layoutMode: 'absolute',
sizePreset: 'custom',
width: 800,
height: 600,
background: '#f5f5f5',
}}
/>
示例:Schema 与 Ref
<Designer
componentConfigs={myConfigs}
initialSchema={savedJson}
onSchemaChange={(schema) => saveToServer(schema)}
designerRef={ref}
/>
// ref.current?.serialize() | deserialize(json) | getHistory()
renderPropertyPanel 完全接管右侧属性区;参数含 selectedNode、selectedNodes、setProp、setStyle 等。renderHeader 替换整个 Header;可内嵌 <DesignerTool sections={['zoom','undoRedo','zoomControl']} compact />。| 场景 | 参考 |
|---|---|
| 自由布局页面编排 | playground/configs/DesignerPage |
| 对接已有 Schema 的编辑页 | initialSchema + onSchemaChange + designerRef.serialize(),见 DesignerPage |
数据源模块提供注册、管理和消费远程/静态数据的能力,每个 Designer 实例拥有独立的数据源 store。
// 静态数据源
interface IStaticDataSource {
id: string;
type: 'static';
data: unknown;
}
// 远程数据源
interface IFetchDataSource {
id: string;
type: 'fetch';
fetchConfig: IFetchConfig;
requestMode?: 'auto' | 'manual';
}
import { useDataSource, useDataSourceOptions } from 'craft-designer';
// 获取原始数据
const { data, loading, error } = useDataSource('myDataSource');
// 直接转为 Select 选项
const options = useDataSourceOptions('myDataSource', {
labelField: 'name',
valueField: 'id',
});
import { configureDataSourceApi } from 'craft-designer';
configureDataSourceApi({
baseURL: '/api',
headers: { Authorization: `Bearer ${token}` },
});
事件系统为组件提供交互能力,支持在设计态绑定事件,在预览/运行态执行。
通过属性面板的「事件」区域为组件绑定事件和动作。每个事件可配置多个动作链。
import { EventContextProvider, PreviewRenderer } from 'craft-designer';
function PreviewPage({ schema }) {
return (
<EventContextProvider actions={actionMap}>
<PreviewRenderer schema={schema} />
</EventContextProvider>
);
}
import { executeAction, createEventHandler } from 'craft-designer';
// 直接执行单个动作
await executeAction(actionConfig, context);
// 创建事件处理函数(可绑定到 DOM 事件)
const handler = createEventHandler(eventDefinition, context);
element.addEventListener('click', handler);
locale prop 支持三种形态:
<Designer locale="en-US" />
<Designer locale="zh-CN" />
<Designer locale={{ preset: 'en-US', overrides: { 'Designer.leftPanel.title': 'My Library' } }} />
overrides 中存在的 key 覆盖 preset 对应的整包;未写的 key 用 preset 的文案补齐。
ILocale 对象const jaBundle: ILocale = { /* 日语完整 key-value */ };
<Designer locale={jaBundle} />
库不做任何合并,缺 key 时 t(key) 返回 key 字符串本身。
覆盖对象的 Key 须与 词条表 一致。部分文案含插值 {type}、{count}。高级用法可用导出的 resolveLocale(locale) 在非 React 处解析文案。
包内导出:zhCN、enUS、DesignerLocaleEnum、useLocale、LocaleProvider、resolveLocale;可用 t(DesignerLocaleEnum.xxx)。
| 符号 | 用途 |
|---|---|
Designer | 设计器主组件 |
DesignerTool | 可配置工具栏(供 renderHeader 内嵌) |
LayoutPanel / StylePanel | 布局/样式编辑面板块 |
MultiSelectLayoutSection | 多选时的对齐/层级操作区 |
PreviewRenderer | 预览渲染器 |
EventContextProvider | 事件运行时 Context Provider |
| 符号 | 用途 |
|---|---|
useDesignerConfig | 读取设计器配置上下文 |
useSelectedNode | 获取当前选中节点信息 |
useLayoutValues | 读取节点布局值与更新方法 |
useChildPositionInit | 自由布局下子节点位置初始化 |
useLocale | 获取多语言 t(key) 函数 |
useEventContext / useEventContextOptional | 事件运行时 Context |
useDataSource | 消费数据源原始数据 |
useDataSourceOptions | 数据源转下拉选项 |
useInlineDataSource | 行内数据源(组件内独立使用) |
useDataSourceStore / useDataSourceState / useDataSourceData / useDataSourceActions | 数据源 store 底层访问 |
| 符号 | 用途 |
|---|---|
createBusinessProperties | 业务属性配置工厂 |
getDefaultPropsFromConfig | 从配置提取默认 props |
extractPropertyKeys | 提取属性 key 列表 |
setLastDropPosition / subscribeDropPosition | 自由布局拖放位置管理 |
flatToTree / treeToFlat | 扁平 ↔ 嵌套树数据转换 |
registerComponentIcon / registerComponentIcons | 组件图标注册 |
getComponentIcon / hasComponentIcon / clearComponentIcons | 组件图标查询/清理 |
executeAction / createEventHandler | 事件执行 |
createLogger | 创建事件日志器 |
resolveLocale | 非 React 环境解析多语言 |
configureDataSourceApi / DataSourceApi / getApiConfig | 数据源 API 配置 |
fetchData / transformToOptions / executeDataSource / executeDataSourceAsOptions | 数据源执行器 |
DataSourceStoreProvider / createDataSourceStore | 数据源 store 创建 |
| 符号 | 用途 |
|---|---|
useNode | Craft 节点 Hook |
useEditor | Craft 编辑器 Hook |
Element | Craft 画布元素 |
Node / SerializedNodes | Craft 类型 |
IDesignerProps、IDesignerRef、DesignerComponentType、IComponentConfig、IComponentPropertyConfig、IPropertyConfig、ICustomPropertyPanelProps、ISelectedNodeInfo、INodeLayout、INodeStyle、StylePropertyKey、LayoutPropertyKey、IDesignerToolProps、DesignerToolSection、RenderPropertyPanel、LeftPanelLayout、TreeNode、ITreeNodeFilterInfo、ITreeNodeFilterResult、FilterTreeNode、IComponentIconConfig、ILocale、ILocaleKeys、DesignerLocale、BuiltinLocalePreset、ILocalePresetWithOverrides、IEventContext、IEventDefinition、IActionConfig、ActionType、ExecuteOptions、IEventSecurityOptions、PreviewRendererProps、NodeWrapper、IMultiSelectLayoutSectionProps、IDataSourceApiConfig。
完整列表见 src/index.ts。
npm run dev # playground 开发服务器
npm run build # 输出 dist/
npm run lint
npm run test # 单元测试
craft-designer/
├── src/
│ ├── components/Designer/
│ │ ├── index.tsx # 入口:Provider 嵌套 + Editor + 三栏布局
│ │ ├── DesignerConfig.tsx # 配置 Context
│ │ ├── DesignerEffects.tsx # 副作用聚合(schema 监听、快捷键、生命周期)
│ │ ├── DesignerRefBridge.tsx # designerRef → serialize/deserialize/history
│ │ ├── Canvas/ # 画布区(Frame + RootCanvas)
│ │ ├── common/
│ │ │ ├── RootCanvas/ # 根画布:尺寸/拖拽/缩放/自适应/居中
│ │ │ ├── RenderWrapper/ # 单节点 Moveable 控制框
│ │ │ └── GroupMoveable/ # 多选 Moveable
│ │ ├── Header/ # 顶栏 + 工具条
│ │ ├── LeftPanel/ # 组件库(分组 + 拖拽创建)
│ │ ├── RightPanel/ # 组件树 + 属性面板 + 事件面板
│ │ ├── DataSource/ # 数据源:store/executor/api/hooks
│ │ ├── EventSystem/ # 事件:Context/Executor/PreviewRenderer
│ │ ├── hooks/ # 画布交互、选中、schema、快捷键等
│ │ ├── store/ # UI 状态(zoom/offset/panels)
│ │ ├── locale/ # 多语言(zh-CN / en-US)
│ │ ├── types/ # 类型定义
│ │ ├── utils/ # 工具函数
│ │ └── icons/ # 内置图标
│ └── index.ts # 统一导出入口
├── docs/
├── playground/
└── package.json
组件样式通过 postcss-prefix-selector 自动添加 .craft-designer-scope 前缀,避免与宿主应用冲突。使用时需确保 Designer 组件被包裹在带有该 class 的容器中(已内置处理)。
开发调试日志通过 IEventLogger 抽象,createLogger(debug) 可控制是否输出 debug 级别日志。生产环境建议传入 debug: false。
MIT
FAQs
基于 Craft.js 的可视化页面设计器 React 组件库,拖拽编排、属性编辑、Schema 导入导出,开箱即用
The npm package craft-designer receives a total of 21 weekly downloads. As such, craft-designer popularity was classified as not popular.
We found that craft-designer demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Vibe coding at scale is reshaping how packages are created, contributed, and selected across the software supply chain

Security News
npm invalidated all granular access tokens that bypass 2FA after a fresh Mini Shai-Hulud wave compromised 323 npm packages. Staged publishing also entered public preview.

Research
/Security News
Compromised npm package art-template delivered a Coruna-like iOS Safari exploit framework through a watering-hole attack.