craft-designer
v0.2.7
Published
基于 Craft.js 的可视化页面设计器 React 组件库,拖拽编排、属性编辑、Schema 导入导出,开箱即用
Maintainers
Readme
craft-designer
一个基于 Craft.js 的可视化、低代码页面设计器 React 组件库,支持拖拽编排、属性编辑、Schema 导入导出。
你可以用配置驱动的方式,从组件库拖拽到画布、编辑属性、导出 Schema,完成「设计 → 编辑 → 保存」的完整闭环。
目录
为什么选择 craft-designer
开箱即用:画布缩放、平移、吸附、撤销重做、组件树、属性面板、Schema 导入导出……这些都已经内置,你不用从零实现。
可配置:通过「组件配置」注册业务组件,就能自动出现在组件库和属性区。工具栏、面板宽度、根画布属性等都可以配置。
可替换:属性面板和顶栏支持完全自定义 UI,同时复用设计器的数据和工具栏等能力。
可集成:onSchemaChange 对接保存、designerRef 编程式读写、locale 与 词条表 对接宿主 i18n。
依赖收敛:只装 craft-designer 和 React,其余已打包。
体验细节:缩放画布时控制框 1:1 视觉;拖拽超出画布自动拉回;大量节点下仍保持流畅。
快速上手
1. 安装
在 React 项目中执行:
npm install craft-designer需要已有 react、react-dom(^18 或 ^19)。antd、zustand、@craftjs/core 等已打入产物,无需单独安装。
2. 准备组件配置
为每个可编排组件写一份配置,其中 preview 是纯展示用的 React 组件:
{
type: 'Button',
name: '按钮',
preview: () => <button>按钮</button>,
craftConfig: { props: {} },
propertyConfig: { layout: true, style: true },
}容器类组件若需在画布内编辑,再提供 editorComponent。
3. 挂载设计器
在页面中渲染 <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} />;
}4. 持久化
- 设计变更时:在
onSchemaChange回调里拿到最新 Schema,存到后端。 - 保存/导出:通过
designerRef.current?.serialize()取 JSON。 - 打开编辑页:用
initialSchema或deserialize()还原。
5. 进阶
- 自定义属性面板:传
renderPropertyPanel。 - 自定义顶栏:传
renderHeader,可内嵌DesignerTool。 - 业务属性:用
propertyConfig.business或createBusinessProperties。
完整示例:playground/configs/DesignerPage/index.tsx,运行 npm run dev 打开 playground 体验。
安装
npm install craft-designer需要在 React 项目中使用,已安装 react、react-dom(^18 或 ^19)即可。
功能清单
面向产品层面的能力说明,便于判断「能做什么、边界在哪」。技术实现见 接入与扩展。
画布操作
- 尺寸预设:桌面端(1920×1080)、平板(768×1024)、手机(375×667)和自定义。
- 缩放:10%–500%,支持适应窗口、100% 重置。
- 平移:Alt + 左键或中键拖拽。
- 自适应:打开时自动适应窗口,面板展开/收起时重新计算。
- 溢出滚动:画布大于可视区时支持滚动。
- 背景色:可自定义。
组件库
- 按分组展示;支持图标+名称、预览卡片两种布局。
- 从左侧面板拖拽到画布即可创建实例。
- 面板可折叠。
组件交互
- 选中、拖拽、缩放、旋转:点击选中、八方向控制点缩放、顶部手柄旋转。
- 吸附:拖拽时吸附相邻组件和画布中心参考线。
- 跨容器拖拽:可在不同容器间移动,自动换算坐标。
- 删除:选中时显示删除按钮,支持
onBeforeDelete拦截确认。
多选操作
- Shift 多选;组拖拽;左/右/上/下/水平居中/垂直居中对齐;置顶、上移、下移、置底。
组件树
- 右侧树形展示层级;点击选中;树内拖拽排序;同类型自动编号;容器可折叠;悬停显示删除按钮;可拖拽分割线调整高度。
属性面板
- 布局:X、Y、宽、高、旋转。
- 样式:背景色、文字色、边框、圆角、透明度、字号、字重。
- 业务属性:由
propertyConfig配置驱动;支持dependsOn/dependsValue条件显隐。 - 多选:切换为对齐 + 层级操作。
- 画布:选中根画布可改尺寸预设、背景色、布局模式。
- 自定义:
renderPropertyPanel完全替换。
工具栏
- 缩放控制、撤销/重做(含快捷键)、层级排序、对齐、Schema 预览、导出、紧凑模式;
sections按需显隐。
数据管理
- 加载(
initialSchema)、实时通知(onSchemaChange,防抖 300ms)、预览、复制、下载、designerRef编程式serialize/deserialize/getHistory。
布局模式
- 自由布局(absolute):任意位置、拖拽/旋转/吸附/跨容器。
- 流式布局(flex):顺序排列,仅缩放,不支持拖拽和旋转。
多语言
- 内置中文、英文;
locale支持三种形态(快捷字符串 / 底稿+覆盖 / 宿主全权接管);完整词条见 docs/i18n-keys.md。
组件控制项
每个组件可通过 craftConfig.controls 单独配置:可缩放、可旋转、可删除、保持比例。
性能与体验
- 拖拽/缩放/旋转流畅;控制框 1:1 视觉;超出画布自动拉回;面板过渡平滑;大量组件下按需计算。
接入与扩展
组件注册:componentConfigs
interface 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;
}属性面板:propertyConfig
interface 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。
常用 Props 速查
| 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 |
Hooks、子组件与工具
| 名称 | 用途 |
|------|------|
| useDesignerConfig() | 配置上下文 |
| useSelectedNode() | 当前选中节点 |
| DesignerTool | 可配置工具栏 |
| LayoutPanel / StylePanel | 布局/样式编辑块 |
| createBusinessProperties | 业务属性配置工厂 |
| getDefaultPropsFromConfig | 从配置提取默认 props |
| setLastDropPosition / subscribeDropPosition | 自由布局拖放位置 |
多语言
locale prop 支持三种形态:
1. 快捷字符串 — 使用内置整包
<Designer locale="en-US" />
<Designer locale="zh-CN" />2. 底稿 + 覆盖 — 以内置包为底,覆盖部分 key
<Designer locale={{ preset: 'en-US', overrides: { 'Designer.leftPanel.title': 'My Library' } }} />overrides 中存在的 key 覆盖 preset 对应的整包;未写的 key 用 preset 的文案补齐。
3. 宿主全权接管 — 传完整 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)。
API 导出
| 类别 | 符号 | |------|------| | 组件 | Designer、DesignerTool、LayoutPanel、StylePanel、MultiSelectLayoutSection | | Hooks | useDesignerConfig、useSelectedNode、useLayoutValues、useChildPositionInit | | 工具 | createBusinessProperties、getDefaultPropsFromConfig、setLastDropPosition、subscribeDropPosition、extractPropertyKeys | | 多语言 | zhCN、enUS、DesignerLocaleEnum、useLocale、LocaleProvider、resolveLocale;类型 ILocale、ILocaleKeys、DesignerLocale、BuiltinLocalePreset、ILocalePresetWithOverrides | | Craft 透传 | useNode、useEditor、Element;类型 Node、SerializedNodes |
类型(节选):IDesignerProps、IDesignerRef、IComponentConfig、IComponentPropertyConfig、IPropertyConfig、ICustomPropertyPanelProps、ISelectedNodeInfo、INodeStyle、LeftPanelLayout、IDesignerToolProps、DesignerToolSection、RenderPropertyPanel 等。完整列表见 src/index.ts。
开发与目录
npm run dev # playground
npm run build # 输出 dist/
npm run lintcraft-designer/
├── src/
│ ├── components/Designer/ # 设计器(locale、Header、LeftPanel、RightPanel、Canvas…)
│ └── index.ts
├── docs/
├── playground/
└── package.jsonLicense
MIT
