d8d-blockly
项目简介
这是一个基于React的区块编辑器项目,使用了d8d-blockly库来实现可视化的代码块编辑功能。项目包含两个主要组件:单一编辑器(App.tsx)和多编辑器(AppMulti.tsx)。
功能特点
单一编辑器 (App.tsx)
- 使用BlockEditor组件实现代码块编辑
- 支持自定义区块类型和分类
- 实时更新代码块、JavaScript代码和导入代码
- 支持复制和粘贴代码块
多编辑器 (AppMulti.tsx)
- 支持多个BlockEditor实例
- 可以动态添加新的编辑器
- 支持在不同编辑器之间切换
- 共享复制的代码块across编辑器
技术栈
- React
- TypeScript
- d8d-blockly库
使用说明
- 克隆项目到本地
- 安装依赖:
npm install
- 运行项目:
npm start
代码示例
单一编辑器 (App.tsx)
import { useState } from "react";
import "./App.css";
import { BlockEditor, baseBlocks, baseCateItems } from "d8d-blockly";
import blockTypes from "@/app/blockTypes.json";
import { blocks, cates } from "@/app/test";
function App() {
const [blockCode, setBlockCode] = useState<TBlockCodeMap>(new Map());
const [copyBlocks, setCopyBlocks] = useState<TBlockNode[]>([]);
const cateItems = [...baseCateItems, ...cates];
const blocksCateConfig = {
...baseBlocks,
...blocks,
};
const onBlockChange = (
blockCode: TBlockCodeMap,
jsCode: string,
importCode: string
) => {
console.log(blockCode, [...blockCode.values()]);
console.log(jsCode);
console.log(importCode);
setBlockCode(blockCode);
};
const onCopyBlocksChange = (blocks: TBlockNode[]) => {
console.log("onCopyBlocksChange", blocks);
setCopyBlocks(blocks);
};
return (
<>
<div className="db-w-screen db-h-screen">
<BlockEditor
blockCode={blockCode}
onBlockChange={onBlockChange}
blocksCateConfig={blocksCateConfig}
cateItems={cateItems}
blockTypes={blockTypes}
copyBlocks={copyBlocks}
onCopyBlocksChange={onCopyBlocksChange}
/>
</div>
</>
);
}
export default App;
多编辑器 (AppMulti.tsx)
import { useCallback, useState } from "react";
import "./App.css";
import { BlockEditor, baseBlocks, baseCateItems } from "d8d-blockly";
import blockTypes from "@/app/blockTypes.json";
import { blocks, cates } from "@/app/test";
// 定义 BlockEditor 的状态类型
type TBlockEditorState = {
blockCode: Map<string, any>;
jsCode: string;
importCode: string;
};
function App() {
// 初始化 BlockEditor 状态数组
const [editors, setEditors] = useState<TBlockEditorState[]>([
{ blockCode: new Map(), jsCode: "", importCode: "" }, // 初始状态
]);
const [activeIndex, setActiveIndex] = useState(0); // 当前激活的 BlockEditor 索引
const [copyBlocks, setCopyBlocks] = useState<any[]>([]);
const cateItems = [...baseCateItems, ...cates];
const blocksCateConfig = {
...baseBlocks,
...blocks,
};
const onBlockChange =
(index: number) =>
(blockCode: Map<string, any>, jsCode: string, importCode: string) => {
const newEditors = [...editors];
newEditors[index] = { blockCode, jsCode, importCode };
setEditors(newEditors);
};
const onCopyBlocksChange = (blocks: any[]) => {
console.log("onCopyBlocksChange", blocks);
setCopyBlocks(blocks);
};
// 添加新的 BlockEditor
const addEditor = () => {
setEditors([
...editors,
{ blockCode: new Map(), jsCode: "", importCode: "" },
]);
};
// 切换激活的 BlockEditor
const switchEditor = (index: number) => {
setActiveIndex(index);
};
const EditorNode = useCallback(
(props: any) => {
const currentEditor = editors[activeIndex];
return (
currentEditor && (
<BlockEditor
blockCode={currentEditor.blockCode}
onBlockChange={onBlockChange(activeIndex)}
blocksCateConfig={blocksCateConfig}
cateItems={cateItems}
blockTypes={blockTypes}
{...props}
/>
)
);
},
[activeIndex]
);
return (
<>
<div className="db-w-screen db-h-screen">
<button
type="button"
className="db-bg-yellow-500 db-p-2 db-text-white db-rounded-md"
onClick={addEditor}
>
Add Editor
</button>
<div className="db-space-x-2">
{editors.map((_, index) => (
<button
key={index}
type="button"
className="db-bg-blue-500 db-p-2 db-text-white db-rounded-md"
onClick={() => switchEditor(index)}
>
Switch to Editor {index + 1}
</button>
))}
</div>
<div className="db-w-full db-h-[calc(100vh-100px)] db-bg-gray-100">
<EditorNode
copyBlocks={copyBlocks}
onCopyBlocksChange={onCopyBlocksChange}
/>
</div>
</div>
</>
);
}
export default App;
注意事项
- 确保已正确安装并配置d8d-blockly库
- 项目使用了自定义的CSS类名,可能需要相应的CSS框架支持
贡献
欢迎提交问题和合并请求,为项目做出贡献。
许可证
MIT