Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@ jobs:
name: eslint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Read .node-version
id: node-version
run: echo "node-version=$(cat .node-version)" >> $GITHUB_OUTPUT
- name: install node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
cache: yarn
node-version: ${{ steps.node-version.outputs.node-version }}
- name: Display Node.js version
run: node --version
- name: yarn install
run: yarn install
- name: yarn run lint
Expand All @@ -28,15 +30,17 @@ jobs:
name: typescript
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Read .node-version
id: node-version
run: echo "node-version=$(cat .node-version)" >> $GITHUB_OUTPUT
- name: install node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
cache: yarn
node-version: ${{ steps.node-version.outputs.node-version }}
- name: Display Node.js version
run: node --version
- name: yarn install
run: yarn install
- name: tsc on resulting generated files
Expand Down
37 changes: 37 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,22 +1,59 @@
# Build outputs
/dist
/dist-modules
*.tsbuildinfo

# Dependencies
/node_modules
/package-lock.json

# Logs
yarn-error.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Coverage directory used by tools like istanbul
coverage
*.lcov

# IDE files
.idea/*
.idea/codeStyles/
.idea/inspectionProfiles/
.idea/misc.xml
.idea/modules.xml
.idea/react-blockly-component.iml
.idea/vcs.xml
.vscode/
*.swp
*.swo

# OS files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

# Package managers
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases

# Temporary folders
tmp/
temp/
!.yarn/sdks
!.yarn/versions
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
16.15.0
20.19.0
8 changes: 8 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
dist/
node_modules/
*.log
.DS_Store
coverage/
.nyc_output/
.vscode/
.idea/
11 changes: 11 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": false,
"printWidth": 80,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"arrowParens": "avoid",
"endOfLine": "lf"
}
19 changes: 15 additions & 4 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
{
"search.exclude": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"eslint.enable": true,
"typescript.preferences.importModuleSpecifier": "relative",
"typescript.enablePromptUseWorkspaceTsdk": true,
"files.exclude": {
"**/node_modules": true,
"**/dist": true,
"**/*.tsbuildinfo": true,
"**/.yarn": true,
"**/.pnp.*": true
},
"eslint.nodePath": ".yarn/sdks",
"typescript.tsdk": ".yarn/sdks/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
"search.exclude": {
"**/node_modules": true,
"**/dist": true,
"**/.yarn": true,
"**/.pnp.*": true
}
}
2 changes: 2 additions & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
nodeLinker: node-modules

plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"
Expand Down
32 changes: 32 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,38 @@

We've switched to keeping our changelog in Github releases. [Please go here to view the latest release notes.](https://github.com/nbudin/react-blockly/releases)

# Version 10.0.0 - June 15, 2025

## Major React 19 Modernization & Tooling Update

### BREAKING CHANGES:
- React 19 Support: Updated peer dependencies to support React 19.x
- Node.js Requirements: Now requires Node.js >=18.0.0 and npm >=8.0.0
- Removed react-scripts dependency to eliminate peer dependency conflicts
- Package now uses ES modules (`"type": "module"`)

### New Features:
- Full React 19 compatibility while maintaining backward compatibility with React 16.8+
- Upgraded to TypeScript 5.8 with ES2020 target and stricter type checking
- Updated to ESLint 9 with flat config format and modern React rules
- Added Prettier integration for automatic code formatting
- Enhanced developer experience with VS Code settings and improved scripts

### Improvements:
- Updated all dependencies to latest versions (Blockly 12.1.0+, Webpack 5, etc.)
- Cleaner builds with incremental TypeScript compilation
- Improved type safety with better annotations and safer array/object access
- Added `clean`, `dev`, `format`, and `format:check` npm scripts
- Enhanced package.json with keywords and engine requirements

### Fixes:
- Eliminated need for `--legacy-peer-deps` flag during installation
- Updated from deprecated `ReactDOM.render()` to `createRoot()` API for React 19
- Fixed TypeScript compilation errors with stricter settings
- Zero ESLint errors with modern configuration

**Migration Guide**: This version maintains API compatibility while requiring React 19+. Update your React version and remove any `--legacy-peer-deps` flags from install commands.

# Version 6.0.1 - September 17, 2020

- Fix broken entrypoint in package.json; clean up build a bit.
Expand Down
65 changes: 65 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import js from '@eslint/js';
import typescript from '@typescript-eslint/eslint-plugin';
import typescriptParser from '@typescript-eslint/parser';
import react from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';

export default [
js.configs.recommended,
{
files: ['**/*.{ts,tsx}'],
languageOptions: {
parser: typescriptParser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
globals: {
// Browser globals
window: 'readonly',
document: 'readonly',
alert: 'readonly',
clearTimeout: 'readonly',
setTimeout: 'readonly',

// DOM types
HTMLElement: 'readonly',
HTMLDivElement: 'readonly',
Element: 'readonly',
},
},
plugins: {
'@typescript-eslint': typescript,
react,
'react-hooks': reactHooks,
},
rules: {
// TypeScript rules
'@typescript-eslint/no-unused-vars': ['warn', {argsIgnorePattern: '^_'}],
'@typescript-eslint/no-explicit-any': 'warn',
'no-unused-vars': 'off', // Use TypeScript version instead
'no-undef': 'off', // TypeScript handles this

// React rules
'react/react-in-jsx-scope': 'off', // Not needed in React 17+
'react/prop-types': 'off', // Using TypeScript for prop validation
'react/jsx-uses-react': 'off',
'react/jsx-uses-vars': 'error',

// React Hooks rules
'react-hooks/rules-of-hooks': 'error',
'react-hooks/exhaustive-deps': 'warn',
},
settings: {
react: {
version: 'detect',
},
},
},
{
ignores: ['dist/**', 'node_modules/**'],
},
];
90 changes: 53 additions & 37 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,59 +1,75 @@
{
"name": "react-blockly",
"version": "9.0.0",
"version": "10.0.0",
"type": "module",
"description": "A React wrapper for the Blockly visual programming editor",
"keywords": [
"react",
"blockly",
"visual-programming",
"editor",
"typescript",
"drag-and-drop",
"coding"
],
"main": "dist/index.js",
"types": "dist/index.d.ts",
"engines": {
"node": ">=18.0.0",
"npm": ">=8.0.0"
},
"scripts": {
"clean": "rm -rf dist",
"build": "npm run clean && tsc",
"watch": "tsc --watch",
"dev": "npm start",
"start": "webpack-dev-server --config webpack.config.test.cjs",
"lint": "eslint --ext .ts,.tsx src",
"lint:fix": "eslint --fix --ext .ts,.tsx src",
"start": "webpack-dev-server --config webpack.config.test.js",
"format": "prettier --write 'src/**/*.{ts,tsx}'",
"format:check": "prettier --check 'src/**/*.{ts,tsx}'",
"test": "echo \"Error: no test specified\" && exit 1",
"build": "tsc",
"watch": "tsc --watch",
"prepack": "yarn run build"
"prepare": "npm run build",
"prepublishOnly": "npm run build"
},
"files": [
"dist"
"dist",
"src",
"tsconfig.json"
],
"author": "Nat Budin <[email protected]>",
"license": "MIT",
"dependencies": {
"blockly": ">= 11.0.0",
"prop-types": "^15.8.1"
"blockly": ">=12.1.0",
"prop-types": "^15.8.1",
"typescript": "^5.8.3"
},
"peerDependencies": {
"react": "^16.8 || ^17.0 || ^18.0"
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0"
},
"devDependencies": {
"@types/node": "^12.0.0",
"@types/prop-types": "^15.7.5",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"@typescript-eslint/eslint-plugin": "^5.53.0",
"@typescript-eslint/parser": "^5.53.0",
"babel-eslint": "^10.1.0",
"css-loader": "^6.7.3",
"eslint": "^8.34.0",
"eslint-config-prettier": "^8.6.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"html-webpack-plugin": "^5.5.0",
"mini-css-extract-plugin": "^2.7.2",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"ts-loader": "^9.4.2",
"typescript": "^4.9.5",
"webpack": "^5.63.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.4.0"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
"@eslint/js": "^9.29.0",
"@types/node": "^24.0.1",
"@types/prop-types": "^15.7.15",
"@types/react": "^19.1.8",
"@types/react-dom": "^19.1.6",
"@typescript-eslint/eslint-plugin": "^8.34.0",
"@typescript-eslint/parser": "^8.34.0",
"css-loader": "^7.1.2",
"eslint": "^9.29.0",
"eslint-config-prettier": "^10.1.5",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^5.2.0",
"html-webpack-plugin": "^5.6.3",
"mini-css-extract-plugin": "^2.9.2",
"prettier": "^3.4.2",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"ts-loader": "^9.5.2",
"webpack": "^5.99.9",
"webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.2"
},
"repository": {
"type": "git",
Expand Down
6 changes: 3 additions & 3 deletions src/BlocklyWorkspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { BlocklyWorkspaceProps } from "./BlocklyWorkspaceProps";
const propTypes = {
initialXml: PropTypes.string,
initialJson: PropTypes.object,
toolboxConfiguration: PropTypes.object, // eslint-disable-line react/forbid-prop-types
workspaceConfiguration: PropTypes.object, // eslint-disable-line react/forbid-prop-types
toolboxConfiguration: PropTypes.object,
workspaceConfiguration: PropTypes.object,
className: PropTypes.string,
onWorkspaceChange: PropTypes.func,
onImportXmlError: PropTypes.func,
Expand All @@ -32,7 +32,7 @@ function BlocklyWorkspace({
onInject,
onDispose,
}: BlocklyWorkspaceProps) {
const editorDiv = React.useRef(null);
const editorDiv = React.useRef<HTMLDivElement>(null);
const { xml, json } = useBlocklyWorkspace({
ref: editorDiv,
initialXml,
Expand Down
Loading