nbudin / react-blockly Goto Github PK
View Code? Open in Web Editor NEWA React component that embeds a Blockly visual programming editor.
License: MIT License
A React component that embeds a Blockly visual programming editor.
License: MIT License
To make the component load and work in my project I need to install the Webpack??
Hello,
I have a react app using typescript and vite where I want to use the react-blockly package in order to load blockly wrokspace. The blockly div exists if I open the dev tools, but in my page it wont show up at all.
My code :
import { BlocklyWorkspace } from 'react-blockly';
import { useState } from 'react';
import "./blockly.css";
const MY_TOOLBOX = {
"kind": "categoryToolbox",
"contents": [
{
"kind": "category",
"name": "Logic",
"contents": [
{
"kind": "block",
"type": "controls_if"
},
{
"kind": "block",
"type": "logic_compare"
}
]
}
]
}
const BlocklyEditorComponent = () => {
const [xml, setXml] = useState('<xml xmlns="http://www.w3.org/1999/xhtml"><block type="text" x="70" y="30"><field name="TEXT"></field></block></xml>');
return (
<BlocklyWorkspace
className="width-100 fill-height" // you can use whatever classes are appropriate for your app's CSS
toolboxConfiguration={MY_TOOLBOX} // this must be a JSON toolbox definition
initialXml={xml}
onXmlChange={setXml}
/>
)
}
export default BlocklyEditorComponent;
Any ideas what is wrong ?
Hi there,
Thanks for picking up on this project. I am trying to set it up on Google Chrome and I think I'm finding it hard due to the non-standard xml
, category
, etc tags that you are using. Did you consider changing everything for just div
, or creating the react classes yourself?
Best,
E
I will open a PR soon. My fork is at https://github.com/KodeForks/react-blockly/tree/react-18
As of the latest Blockly release (September 2020) you can define the toolbox in JSON instead of only XML (see https://developers.google.com/blockly/guides/configure/web/toolbox#json). This format is really similar to react-blockly
's format but has more configuration options, like separators. It would be great if react-blockly
could support this new format.
Hello, I have one question, because I'm very confused about how to use this component ReactBlockly.
I install in my react app but I would like to use the ReactBlockly component inside of a specific page of my site.
I create the page but when I call the component don't appear anything
Please help me because I'm a noob
I want to set Id of blocks with only numbers starting from 1 when I add them to workspace.
Suppose when I add 'block1' to workspace, then its id should be set to - '1'
And then next block added to workspace should have id as '2'
likewise, it should increment as I add blocks to workspace.
Please help how can I achieve this?
This is not the usual way:
Clone this repository, and then inside it, do:
npm install
npm run build
Everyone will use this instead:
npm i react-blockly
I really doubt that you even ever dog-food your own code successfully in your React projects.
During react renders the blocks' xml ends up injecting twice.
const { loaded, project, updateProject } = useProject(); //here is stored the workspace (into data.blocks property)
const blocklyRef = useRef(null);
const { xml, workspace } = useBlocklyWorkspace({
ref: blocklyRef,
toolboxConfiguration: toolbox,
initialXml: '',
workspaceConfiguration: { zoom: { controls: true, wheel: true, startScale: 1, maxScale: 3, minScale: 0.3, scaleSpeed: 1.2 }, theme },
onWorkspaceChange: (workspace) => {
if (loaded) {
console.log(xml);
}
}
});
useEffect(() => {
if (loaded) {
Blockly.serialization.workspaces.load(JSON.parse(project.data.blocks), Blockly.getMainWorkspace());
}
}, [loaded]);
return (
<div id="blockly" ref={blocklyRef}></div>
);
As you can see from the following image, the xml ends up doubling each block
Thanks in advance!
In the readme
file wrote that:
Once you've done either of these, you should be able to import ReactBlockly from 'react-blockly'; in your code and use ReactBlockly as a component.
But, basically, it's not correct, I just try to use that like that but then it's throwing an exception:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
The workaround for that is just to use the component as is: <ReactBlockly.BlocklyEditor .... />
The first interesting point is that in webpack.config
the entry point is './src/dev-index.jsx'
and not src/index.js
- is it mistake or something ?
The second point is that index.js
export object and not a component and that's why we can't use that as component
Maybe a clarify will be good here!
@nbudin I could change it myself but first I need to understand exactly what happening here!
Thanks.
How can i create a custom block?
Hey there! I am trying to use this package in a Next JS 13 app.
Currently getting the following error:
./node_modules/canvas/build/Release/canvas.node
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
I tried creating a webpack.config.js
file and including a loader - but no luck.
Not sure exactly how to move forward from here.
I need a package @types/react-blocky which does not exist :D
It will be cool if you add it!
Hey,
Thanks for the great job.
I was wondering if there is a way to enable JSON serialization system alongside the XML one?
As google advise, JSON is the future of serialization.
I use onWorkspaceChange to trigger conversion of blocks to python code. This fires consistently.
I used onJsonChange to trigger conversion of blocks to string (JSON.stringify) to update state. This doesn't fire consistently.
For example, edit an existing workspace with two random string blocks:
1 - edit first string and hit enter. Both onWorkspaceChange and onJsonChange fire as expected
2 - edit second string and hit enter. Only onWorkspaceChange fires.
3 - click elsewhere to deselect second string. Only onJsonChange fires (late).
To get around this inconsistency, I've switched to rely entirely on the onWorkspaceChange event.
According to this issue, and the documentation here we should be able to change colors of default blocks by doing
Blockly.Msg.LOGIC_HUE = "#C554AB";
but that doesn't seem to be working with React-Blockly. What is the correct way to achieve this?
Edit: I am using v6 and its README says a custom colour
property can be passed to the blocks
entry in toolboxCategories
but that doesn't seem to work either.
As of date there is a new version of Google's blockly lib. Any thoughts on upgrading?
Hello,I want to define custom category, just like Scratch,how should I do? Thanks.
Hi there,
As the title mentions, when I add readOnly: true, it give me below error
Uncaught Error: Existing toolbox is null. Can't create new toolbox. at WorkspaceSvg$$module$build$src$core$workspace_svg.updateToolbox (workspace_svg.ts:1869:13) at useBlocklyWorkspace.js:43:23
const {workspace} = useBlocklyWorkspace({ ref: blocklyRef, initialXml: programXml, toolboxConfiguration: { "kind": "flyoutToolbox", "contents": [ { "kind": "block", "type": "controls_if" }, { "kind": "block", "type": "controls_whileUntil" } ] }, workspaceConfiguration: { renderer: 'crc_renderer', readOnly: true, scrollbars: true, trashcan: false, grid: { spacing: 20, length: 3, colour: '#ccc', snap: true, }, media: '/blockly/media/', }, onDispose: (ws) => logger.info('on ws dispose', ws), // @ts-ignore onInject: (ws) => logger.info('injected ws', ws?.undoStack_), onWorkspaceChange: (ws) => logger.info('on ws change', ws), onImportXmlError: (error) => logger.warn('error importing XML', error) })
Hi!
The scroll bar is still showing even after closing the category that introduced it!
my Javascrpt code is
function App() {
const [xml, setXml] = useState('<xml xmlns="https://developers.google.com/blockly/xml"></xml>')
const [javascriptCode, setJavascriptCode] = useState(null)
return (
<BlocklyWorkspace
toolboxConfiguration={toolbox}
initialXml={xml}
onXmlChange={(xml) => {
setXml(xml)
console.log(xml)
}}
className="w-screen h-screen"
onImportXmlError={(e) => { console.log(e) }}
workspaceConfiguration={{
grid: {
spacing: 20,
length: 3,
colour: "#ccc",
snap: true
},
theme: DarkTheme,
renderer: 'zelos',
zoom: {
controls: true,
startScale: 0.9,
maxScale: 3,
minScale: 0.3,
scaleSpeed: 1.2
},
trashcan: true,
maxTrashcanContents: 0,
move: {
scrollbars: true,
drag: true,
wheel: true
},
readOnly: false
}}
onWorkspaceChange={(workspace) => {
setJavascriptCode(Blockly.JavaScript.workspaceToCode(workspace))
console.log(javascriptCode)
}}
/>
);
}
When trying to produce code in a language other than JS i get an undefined when calling workspaceToCode() function. Here goes an example using de demo and trying to produce python
workspaceDidChange = (workspace) => {
workspace.registerButtonCallback('myFirstButtonPressed', () => {
alert('button is pressed');
});
const newXml = Blockly.Xml.domToText(
Blockly.Xml.workspaceToDom(workspace),
);
document.getElementById('generated-xml').innerText = newXml;
console.log(Blockly);
const code = Blockly.Python.workspaceToCode(workspace);
document.getElementById('code').value = code;
};
produces error on browser:
Cannot read property 'workspaceToCode' of undefined
I just installed the react-blockly module via npm (npm install react-blockly
). By simply importing BlocklyWorkspace (import { BlocklyWorkspace } from 'react-blockly'
) I get over 15 warnings and the example code fails to display anything. Here is an example of the warnings:
WARNING in ./node_modules/blockly/blockly_compressed.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '/home/blah/react/live-robot-control/node_modules/blockly/src/com/google/javascript/jscomp/js/es6/array/flat.js' file:
Error: ENOENT: no such file or directory, open '/home/blah/react/live-robot-control/node_modules/blockly/src/com/google/javascript/jscomp/js/es6/array/flat.js'
WARNING in ./node_modules/blockly/blockly_compressed.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '/home/blah/react/live-robot-control/node_modules/blockly/src/com/google/javascript/jscomp/js/es6/array/values.js' file:
Error: ENOENT: no such file or directory, open '/home/blah/react/live-robot-control/node_modules/blockly/src/com/google/javascript/jscomp/js/es6/array/values.js'
WARNING in ./node_modules/blockly/blockly_compressed.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from '/home/blah/react/live-robot-control/node_modules/blockly/src/com/google/javascript/jscomp/js/es6/globalthis.js' file:
Error: ENOENT: no such file or directory, open '/home/blah/react/live-robot-control/node_modules/blockly/src/com/google/javascript/jscomp/js/es6/globalthis.js'
and here are the react and react-blockly entries in my package.json
"react": "^18.2.0",
"react-blockly": "^7.1.0",
I'd really like to use this module, any suggestions?
https://github.com/nbudin/react-blockly/blob/master/public/index.html this is NOT react.
In retrospect, these 2 callback can be replaced with useEffect
const { workspace ...
useEffect(() => {
// onInject
return () => // onDispose
}, [workspace])
react-blockly/src/useBlocklyWorkspace.js
Line 25 in bdf8bde
Hi. Do you know how to limit the number of blocks allowed for a particular type?
What I did is that I check the number of blocks on the workspace and if it exceeds the block limit I will set the shadow attribute of the block to true in the toolboxCategories array.
But somehow the Editor just didn't update according to the state change and the block is still visible..
Maybe there is a better way to implement this.
Whenever I import BlocklyWorkspace I get an error saying "SyntaxError: Cannot use import statement outside a module". I am using Next.js with create-next-app.
My code:
import styles from '../styles/Home.module.css'
import Head from 'next/head'
import Image from 'next/image'
import Script from 'next/script'
import React, { useState } from 'react';
import { BlocklyWorkspace } from 'react-blockly';
function BlocklyEditor() {
const [xml, setXml] = useState();
return (
<BlocklyWorkspace
className="width-100"
toolboxConfiguration={MY_TOOLBOX}
initialXml={xml}
onXmlChange={setXml}
/>
)
}
export default function Home() {
return (
<div className={styles.container}>
<Head>
<title>Studio</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<h1>Studio</h1>
<BlocklyEditor/>
</main>
</div>
)
}
wrapSafe
internal/modules/cjs/loader.js (988:16)
Module._compile
internal/modules/cjs/loader.js (1036:27)
Object.Module._extensions..js
internal/modules/cjs/loader.js (1101:10)
Module.load
internal/modules/cjs/loader.js (937:32)
Function.Module._load
internal/modules/cjs/loader.js (778:12)
Module.require
internal/modules/cjs/loader.js (961:19)
require
internal/modules/cjs/helpers.js (92:18)
Object.react-blockly
file:///Users/vadim/Documents/studio/.next/server/pages/index.js (174:18)
webpack_require
file:///Users/vadim/Documents/studio/.next/server/webpack-runtime.js (33:42)
eval
webpack-internal:///./pages/index.js (17:71)
The react-blockly is causing a "SyntaxError: Unexpected identifier" error when running test using the command "react-scripts test".
({"Object.":function(module,exports,require,__dirname,__filename,global,jest){import BlocklyEditor from './BlocklyEditor';
SyntaxError: Unexpected identifier
4 | import _ from 'lodash';
5 | import PropTypes from 'prop-types';
> 6 | import ReactBlockly from 'react-blockly';
| ^
7 | import Blockly from 'blockly';
8 | import Button from '@material-ui/core/Button';
9 | import Grid from '@material-ui/core/Grid';
at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
at Object.<anonymous> (src/components/blockly/Blockly.js:6:1)
Any ideas on how to fix this ?
Hi. Do you know how to render a toolbox with no categories - a toolbox that just has blocks on it.
I have been trying to do it but it doesn't work. Either by modifying the javascript array or modifying the xml string.
Any ideas ? Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.