From dba8db7b76b03ba3fb9b529f839d1e94e06240bf Mon Sep 17 00:00:00 2001 From: Yordan Stoyanov Date: Mon, 6 Jul 2026 16:52:41 +0200 Subject: [PATCH 1/5] chore(chart-playground-web): add react-simple-code-editor and highlight.js --- .../chart-playground-web/package.json | 4 ++- pnpm-lock.yaml | 25 ++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/packages/pluggableWidgets/chart-playground-web/package.json b/packages/pluggableWidgets/chart-playground-web/package.json index 36978e4e95..9222d0095d 100644 --- a/packages/pluggableWidgets/chart-playground-web/package.json +++ b/packages/pluggableWidgets/chart-playground-web/package.json @@ -43,7 +43,9 @@ "@mendix/shared-charts": "workspace:*", "@mendix/widget-plugin-component-kit": "workspace:*", "@mendix/widget-plugin-hooks": "workspace:*", - "@mendix/widget-plugin-platform": "workspace:*" + "@mendix/widget-plugin-platform": "workspace:*", + "highlight.js": "^11.11.1", + "react-simple-code-editor": "^0.14.1" }, "devDependencies": { "@mendix/automation-utils": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 607db78a3f..eb0501d317 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -774,6 +774,12 @@ importers: '@mendix/widget-plugin-platform': specifier: workspace:* version: link:../../shared/widget-plugin-platform + highlight.js: + specifier: ^11.11.1 + version: 11.11.1 + react-simple-code-editor: + specifier: ^0.14.1 + version: 0.14.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) devDependencies: '@mendix/automation-utils': specifier: workspace:* @@ -783,7 +789,7 @@ importers: version: link:../../shared/eslint-config-web-widgets '@mendix/pluggable-widgets-tools': specifier: 11.11.0 - version: 11.11.0(patch_hash=036a1e3d1a57e7418725babb71e5eef5220ae90fc481ad7e04fa7e8901b25801)(@jest/transform@30.3.0)(@jest/types@30.4.1)(@swc/core@1.15.41)(@types/babel__core@7.20.5)(@types/node@24.12.4)(canvas@3.2.3)(eslint@9.39.4(jiti@2.6.1))(jest-util@30.4.1)(prettier@3.8.4)(react-dom@18.3.1(react@18.3.1))(react-native@0.86.0(@babel/core@7.29.7)(@types/react@19.2.17)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) + version: 11.11.0(patch_hash=036a1e3d1a57e7418725babb71e5eef5220ae90fc481ad7e04fa7e8901b25801)(@jest/transform@30.3.0)(@jest/types@30.4.1)(@swc/core@1.15.41)(@types/babel__core@7.20.5)(@types/node@24.12.4)(canvas@3.2.3)(eslint@9.39.4(jiti@2.6.1))(jest-util@30.4.1)(picomatch@4.0.4)(prettier@3.8.4)(react-dom@18.3.1(react@18.3.1))(react-native@0.86.0(@babel/core@7.29.7)(@types/react@19.2.17)(react@18.3.1))(react@18.3.1)(tslib@2.8.1) '@mendix/prettier-config-web-widgets': specifier: workspace:* version: link:../../shared/prettier-config-web-widgets @@ -7678,6 +7684,10 @@ packages: hermes-parser@0.36.0: resolution: {integrity: sha512-GdpwMmH5x6IpC1cijvcvYnlPB60Mh6kTSF/NFdYV/j56gYdi+0RIakYs+eqOV+bbO0SW7mgVVGSsTJxyPQfo3w==} + highlight.js@11.11.1: + resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} + engines: {node: '>=12.0.0'} + hoist-non-react-statics@2.5.5: resolution: {integrity: sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==} @@ -9988,6 +9998,12 @@ packages: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} + react-simple-code-editor@0.14.1: + resolution: {integrity: sha512-BR5DtNRy+AswWJECyA17qhUDvrrCZ6zXOCfkQY5zSmb96BVUbpVAv03WpcjcwtCwiLbIANx3gebHOcXYn1EHow==} + peerDependencies: + react: '>=18.0.0 <19.0.0' + react-dom: '>=18.0.0 <19.0.0' + react-test-renderer@19.2.7: resolution: {integrity: sha512-U4TyPDJ9MsC8rFimXuJum8w40aPc9kbOZYO8Pc2/4A884i8hwJsMNA/JNyuOc/f2/37wHvk7HjpVl1V4re7Dig==} peerDependencies: @@ -16994,6 +17010,8 @@ snapshots: dependencies: hermes-estree: 0.36.0 + highlight.js@11.11.1: {} + hoist-non-react-statics@2.5.5: {} hono@4.12.25: {} @@ -20052,6 +20070,11 @@ snapshots: react-refresh@0.14.2: {} + react-simple-code-editor@0.14.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-test-renderer@19.2.7(react@18.3.1): dependencies: react: 18.3.1 From 8eae73d43467284dbde1f31a3802c64e80154b01 Mon Sep 17 00:00:00 2001 From: Yordan Stoyanov Date: Mon, 6 Jul 2026 16:52:49 +0200 Subject: [PATCH 2/5] fix(chart-playground-web): restore highlighted JSON editor with invalid-JSON feedback --- .../src/components/CodeEditor.tsx | 54 ++++++++++++++++--- .../src/ui/Playground.scss | 17 ++++++ 2 files changed, 65 insertions(+), 6 deletions(-) diff --git a/packages/pluggableWidgets/chart-playground-web/src/components/CodeEditor.tsx b/packages/pluggableWidgets/chart-playground-web/src/components/CodeEditor.tsx index 7cda2cdcf0..2eb39f1280 100644 --- a/packages/pluggableWidgets/chart-playground-web/src/components/CodeEditor.tsx +++ b/packages/pluggableWidgets/chart-playground-web/src/components/CodeEditor.tsx @@ -1,4 +1,10 @@ +import hljs from "highlight.js/lib/core"; +import json from "highlight.js/lib/languages/json"; import { ReactElement } from "react"; +import Editor from "react-simple-code-editor"; +import "highlight.js/styles/atom-one-light.css"; + +hljs.registerLanguage("json", json); export interface CodeEditorProps { value: string; @@ -7,13 +13,49 @@ export interface CodeEditorProps { height?: string; } +function highlight(code: string): string { + try { + return hljs.highlight(code, { language: "json", ignoreIllegals: true }).value; + } catch (error) { + console.warn("Syntax highlighting error:", error); + return code; + } +} + +function jsonError(code: string): string | null { + if (code.trim() === "") { + return null; + } + try { + JSON.parse(code); + return null; + } catch (error) { + return error instanceof Error ? error.message : "Invalid JSON"; + } +} + export function CodeEditor(props: CodeEditorProps): ReactElement { + const error = jsonError(props.value); + return ( -