refactor: introduce codemirror for CSS editor (#2039)

* refactor: introduce codemirror for CSS editor

* chore: fix formatting
This commit is contained in:
Carlos Valente
2026-03-26 15:25:32 +01:00
committed by GitHub
parent 2331205c93
commit 3a0df0b491
10 changed files with 247 additions and 105 deletions
+5 -4
View File
@@ -5,6 +5,10 @@
"type": "module",
"dependencies": {
"@base-ui/react": "1.0.0",
"@codemirror/commands": "^6.0.0",
"@codemirror/lang-css": "^6.0.0",
"@codemirror/state": "^6.0.0",
"@codemirror/view": "^6.0.0",
"@dnd-kit/core": "^6.3.1",
"@dnd-kit/sortable": "^10.0.0",
"@dnd-kit/utilities": "^3.2.2",
@@ -15,10 +19,10 @@
"@tanstack/react-query": "^5.85.9",
"@tanstack/react-query-devtools": "^5.85.9",
"@tanstack/react-table": "^8.21.3",
"@uiw/codemirror-theme-vscode": "^4.25.9",
"autosize": "^6.0.1",
"axios": "^1.12.2",
"csv-stringify": "^6.6.0",
"prismjs": "^1.30.0",
"qrcode": "^1.5.4",
"react": "^19.2.3",
"react-colorful": "^5.6.1",
@@ -27,7 +31,6 @@
"react-hook-form": "^7.62.0",
"react-icons": "5.5.0",
"react-router": "^7.11.0",
"react-simple-code-editor": "^0.14.1",
"react-virtuoso": "^4.17.0",
"web-vitals": "^5.1.0",
"zustand": "^5.0.9"
@@ -58,7 +61,6 @@
},
"devDependencies": {
"@sentry/vite-plugin": "5.1.1",
"@types/prismjs": "^1.26.6",
"@types/qrcode": "^1.5.6",
"@types/react": "^19.1.12",
"@types/react-dom": "^19.1.9",
@@ -70,7 +72,6 @@
"typescript": "catalog:",
"vite": "8.0.1",
"vite-plugin-compression2": "2.5.1",
"vite-plugin-prismjs-plus": "1.1.1",
"vite-plugin-svgr": "4.5.0",
"vite-tsconfig-paths": "6.1.1",
"vitest": "catalog:"
-4
View File
@@ -1,4 +0,0 @@
declare module 'virtual:prismjs' {
const prism: typeof import('prismjs');
export default prism;
}
@@ -1,5 +1,13 @@
.wrapper {
min-height: 500px;
max-height: 500px;
overflow-y: auto;
.editor {
width: 100%;
height: 100%;
:global(.cm-editor) {
height: 100%;
}
:global(.cm-scroller) {
height: 100%;
overflow: auto;
}
}
@@ -1,38 +1,86 @@
import { memo } from 'react';
import Editor from 'react-simple-code-editor';
import 'prismjs/themes/prism-tomorrow.min.css';
import Prism from 'virtual:prismjs';
import { defaultKeymap, indentWithTab } from '@codemirror/commands';
import { css } from '@codemirror/lang-css';
import { Annotation, EditorState } from '@codemirror/state';
import { EditorView, keymap } from '@codemirror/view';
import { vscodeDark } from '@uiw/codemirror-theme-vscode';
import { memo, useEffect, useRef } from 'react';
import style from './StyleEditor.module.scss';
interface CodeEditorProps {
language: string;
interface StyleEditorProps {
value: string;
onChange: (value: string) => void;
}
export default memo(CodeEditor);
function CodeEditor({ language, onChange, value }: CodeEditorProps) {
const highlight = (code: string) => {
const grammar = Prism.languages[language];
return grammar ? Prism.highlight(code, grammar, language) : code;
};
const editorExtensions = [keymap.of([indentWithTab, ...defaultKeymap]), css(), vscodeDark];
const externalValueSync = Annotation.define<boolean>();
return (
<div className={style.wrapper}>
<Editor
value={value}
padding={15}
onValueChange={onChange}
highlight={highlight}
style={{
fontFamily: 'monospace',
fontSize: 12,
minHeight: 500,
background: 'transparent',
}}
/>
</div>
);
export default memo(StyleEditor);
function StyleEditor({ onChange, value }: StyleEditorProps) {
const hostRef = useRef<HTMLDivElement | null>(null);
const viewRef = useRef<EditorView | null>(null);
const onChangeRef = useRef(onChange);
// Keep the latest callback available to the editor listener without recreating the editor instance.
useEffect(() => {
onChangeRef.current = onChange;
}, [onChange]);
// Create the CodeMirror editor once and wire document changes back to React state.
useEffect(() => {
if (viewRef.current) {
return;
}
const parent = hostRef.current;
if (!parent) {
return;
}
const updateListener = EditorView.updateListener.of((update) => {
if (!update.docChanged) {
return;
}
if (update.transactions.some((transaction) => transaction.annotation(externalValueSync))) {
return;
}
onChangeRef.current(update.state.doc.toString());
});
const state = EditorState.create({
doc: value,
extensions: [...editorExtensions, updateListener],
});
const view = new EditorView({ state, parent });
viewRef.current = view;
return () => {
view.destroy();
viewRef.current = null;
};
}, []);
// Apply external value updates to the editor when they differ from the current document.
useEffect(() => {
const view = viewRef.current;
if (!view) {
return;
}
const currentValue = view.state.doc.toString();
if (currentValue === value) {
return;
}
if (view.hasFocus) {
return;
}
view.dispatch({
changes: { from: 0, to: view.state.doc.length, insert: value },
annotations: externalValueSync.of(true),
});
}, [value]);
return <div className={style.editor} ref={hostRef} />;
}
@@ -16,7 +16,7 @@
.editorBody {
position: relative;
min-height: 500px;
height: 500px;
background-color: $gray-1350;
border: 1px solid $gray-1100;
border-radius: 3px;
@@ -51,11 +51,11 @@ export default function CodeEditorModal({ isOpen, onClose }: CodeEditorModalProp
const clear = () => setDraftCss('');
// Load the latest CSS from the server whenever the modal opens, and ignore stale responses on close.
useEffect(() => {
let isCancelled = false;
async function fetchServerCSS() {
// check for isOpen to fetch recent css
if (isOpen) {
try {
setError(null);
@@ -97,11 +97,9 @@ export default function CodeEditorModal({ isOpen, onClose }: CodeEditorModalProp
showBackdrop
bodyElements={
<div className={style.editorBody}>
{!isLoadingCss && (
<Suspense fallback={<Panel.Loader isLoading />}>
<CodeEditor value={draftCss} onChange={setDraftCss} language='css' />
</Suspense>
)}
<Suspense fallback={<Panel.Loader isLoading />}>
<CodeEditor value={draftCss} onChange={setDraftCss} />
</Suspense>
<Panel.Loader isLoading={isLoadingCss} />
</div>
}
-1
View File
@@ -10,7 +10,6 @@
"types": [
"vite/client",
"vite-plugin-svgr/client",
"vite-plugin-prismjs-plus/client",
],
"module": "esnext",
"moduleResolution": "bundler",
-11
View File
@@ -4,7 +4,6 @@ import { sentryVitePlugin } from '@sentry/vite-plugin';
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
import { compression } from 'vite-plugin-compression2';
import prismjsPlugin from 'vite-plugin-prismjs-plus';
import svgrPlugin from 'vite-plugin-svgr';
import { ONTIME_VERSION } from './src/ONTIME_VERSION';
@@ -17,11 +16,6 @@ const ReactCompilerConfig = {
export default defineConfig({
base: './', // Ontime cloud: we use relative paths to allow them to reference a dynamic base set at runtime
legacy: {
// Temporary compatibility for CJS packages affected by Vite 8 interop changes.
// ie: react-simple-code-editor
inconsistentCjsInterop: true,
},
define: {
// we pass along the NODE_ENV here in case it is a docker build
'import.meta.env.IS_DOCKER': process.env.NODE_ENV === 'docker',
@@ -54,11 +48,6 @@ export default defineConfig({
algorithm: 'brotliCompress',
exclude: /\.(html)$/, // Ontime cloud: Exclude HTML files from compression so we can change the base property at runtime
}),
prismjsPlugin({
manual: true,
languages: ['css'],
css: true,
}),
],
server: {
port: 3000,
+1
View File
@@ -1,4 +1,5 @@
import { DatabaseModel, OntimeView } from 'ontime-types';
import { backstageRundown, broadcastRundown, stageRundown } from './demoRundowns.js';
export const demoDb: DatabaseModel = {
+147 -45
View File
@@ -61,6 +61,18 @@ importers:
'@base-ui/react':
specifier: 1.0.0
version: 1.0.0(@types/react@19.1.12)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@codemirror/commands':
specifier: ^6.0.0
version: 6.10.3
'@codemirror/lang-css':
specifier: ^6.0.0
version: 6.3.1
'@codemirror/state':
specifier: ^6.0.0
version: 6.6.0
'@codemirror/view':
specifier: ^6.0.0
version: 6.40.0
'@dnd-kit/core':
specifier: ^6.3.1
version: 6.3.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -91,6 +103,9 @@ importers:
'@tanstack/react-table':
specifier: ^8.21.3
version: 8.21.3(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@uiw/codemirror-theme-vscode':
specifier: ^4.25.9
version: 4.25.9(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.40.0)
autosize:
specifier: ^6.0.1
version: 6.0.1
@@ -100,9 +115,6 @@ importers:
csv-stringify:
specifier: ^6.6.0
version: 6.6.0
prismjs:
specifier: ^1.30.0
version: 1.30.0
qrcode:
specifier: ^1.5.4
version: 1.5.4
@@ -127,9 +139,6 @@ importers:
react-router:
specifier: ^7.11.0
version: 7.11.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
react-simple-code-editor:
specifier: ^0.14.1
version: 0.14.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
react-virtuoso:
specifier: ^4.17.0
version: 4.17.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -143,9 +152,6 @@ importers:
'@sentry/vite-plugin':
specifier: 5.1.1
version: 5.1.1(encoding@0.1.13)(rollup@4.59.0)
'@types/prismjs':
specifier: ^1.26.6
version: 1.26.6
'@types/qrcode':
specifier: ^1.5.6
version: 1.5.6
@@ -179,9 +185,6 @@ importers:
vite-plugin-compression2:
specifier: 2.5.1
version: 2.5.1(rollup@4.59.0)
vite-plugin-prismjs-plus:
specifier: 1.1.1
version: 1.1.1(prismjs@1.30.0)(vite@8.0.1(@types/node@25.4.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.92.0)(tsx@4.20.5))
vite-plugin-svgr:
specifier: 4.5.0
version: 4.5.0(rollup@4.59.0)(typescript@6.0.0-beta)(vite@8.0.1(@types/node@25.4.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.92.0)(tsx@4.20.5))
@@ -522,6 +525,24 @@ packages:
'@types/react':
optional: true
'@codemirror/autocomplete@6.20.1':
resolution: {integrity: sha512-1cvg3Vz1dSSToCNlJfRA2WSI4ht3K+WplO0UMOgmUYPivCyy2oueZY6Lx7M9wThm7SDUBViRmuT+OG/i8+ON9A==}
'@codemirror/commands@6.10.3':
resolution: {integrity: sha512-JFRiqhKu+bvSkDLI+rUhJwSxQxYb759W5GBezE8Uc8mHLqC9aV/9aTC7yJSqCtB3F00pylrLCwnyS91Ap5ej4Q==}
'@codemirror/lang-css@6.3.1':
resolution: {integrity: sha512-kr5fwBGiGtmz6l0LSJIbno9QrifNMUusivHbnA1H6Dmqy4HZFte3UAICix1VuKo0lMPKQr2rqB+0BkKi/S3Ejg==}
'@codemirror/language@6.12.3':
resolution: {integrity: sha512-QwCZW6Tt1siP37Jet9Tb02Zs81TQt6qQrZR2H+eGMcFsL1zMrk2/b9CLC7/9ieP1fjIUMgviLWMmgiHoJrj+ZA==}
'@codemirror/state@6.6.0':
resolution: {integrity: sha512-4nbvra5R5EtiCzr9BTHiTLc+MLXK2QGiAVYMyi8PkQd3SR+6ixar/Q/01Fa21TBIDOZXgeWV4WppsQolSreAPQ==}
'@codemirror/view@6.40.0':
resolution: {integrity: sha512-WA0zdU7xfF10+5I3HhUUq3kqOx3KjqmtQ9lqZjfK7jtYk4G72YW9rezcSywpaUMCWOMlq+6E0pO1IWg1TNIhtg==}
'@develar/schema-utils@2.6.5':
resolution: {integrity: sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==}
engines: {node: '>= 8.9.0'}
@@ -1122,6 +1143,18 @@ packages:
'@jridgewell/trace-mapping@0.3.30':
resolution: {integrity: sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==}
'@lezer/common@1.5.1':
resolution: {integrity: sha512-6YRVG9vBkaY7p1IVxL4s44n5nUnaNnGM2/AckNgYOnxTG2kWh1vR8BMxPseWPjRNpb5VtXnMpeYAEAADoRV1Iw==}
'@lezer/css@1.3.3':
resolution: {integrity: sha512-RzBo8r+/6QJeow7aPHIpGVIH59xTcJXp399820gZoMo9noQDRVpJLheIBUicYwKcsbOYoBRoLZlf2720dG/4Tg==}
'@lezer/highlight@1.2.3':
resolution: {integrity: sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==}
'@lezer/lr@1.4.8':
resolution: {integrity: sha512-bPWa0Pgx69ylNlMlPvBPryqeLYQjyJjqPx+Aupm5zydLIF3NE+6MMLT8Yi23Bd9cif9VS00aUebn+6fDIGBcDA==}
'@malept/cross-spawn-promise@1.1.1':
resolution: {integrity: sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==}
engines: {node: '>= 10'}
@@ -1139,6 +1172,9 @@ packages:
peerDependencies:
react: ^18.x || ^19.x
'@marijn/find-cluster-break@1.0.2':
resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
'@napi-rs/wasm-runtime@1.1.1':
resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==}
@@ -2156,9 +2192,6 @@ packages:
'@types/plist@3.0.5':
resolution: {integrity: sha512-E6OCaRmAe4WDmWNsL/9RMqdkkzDCY1etutkflWk4c+AcjDU07Pcz1fQwTX0TQz+Pxqn9i4L1TU3UFpjnrcDgxA==}
'@types/prismjs@1.26.6':
resolution: {integrity: sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw==}
'@types/qrcode@1.5.6':
resolution: {integrity: sha512-te7NQcV2BOvdj2b1hCAHzAoMNuj65kNBMz0KBaxM6c3VGBOhU0dURQKOtH8CFNI/dsKkwlv32p26qYQTWoB5bw==}
@@ -2197,6 +2230,16 @@ packages:
'@types/yauzl@2.10.3':
resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==}
'@uiw/codemirror-theme-vscode@4.25.9':
resolution: {integrity: sha512-9KTnScHTSk97yGnyNYvDm6QZuBCdbO1OzMQ5bHtoBSPSVtH0LjY3bS6CXsBagb22v8OLPx/XwrBYOjKFp409CQ==}
'@uiw/codemirror-themes@4.25.9':
resolution: {integrity: sha512-DAHKb/L9ELwjY4nCf/MP/mIllHOn4GQe7RR4x8AMJuNeh9nGRRoo1uPxrxMmUL/bKqe6kDmDbIZ2AlhlqyIJuw==}
peerDependencies:
'@codemirror/language': '>=6.0.0'
'@codemirror/state': '>=6.0.0'
'@codemirror/view': '>=6.0.0'
'@vitejs/plugin-react@5.2.0':
resolution: {integrity: sha512-YmKkfhOAi3wsB1PhJq5Scj3GXMn3WvtQ/JC0xoopuHoXSdmtdStOpFrYaT1kie2YgFBcIe64ROzMYRjCrYOdYw==}
engines: {node: ^20.19.0 || >=22.12.0}
@@ -2689,6 +2732,9 @@ packages:
crc@3.8.0:
resolution: {integrity: sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==}
crelt@1.0.6:
resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==}
cross-env@7.0.3:
resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==}
engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'}
@@ -4073,10 +4119,6 @@ packages:
resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==}
engines: {node: ^10 || ^12 || >=14}
prismjs@1.30.0:
resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==}
engines: {node: '>=6'}
proc-log@2.0.1:
resolution: {integrity: sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==}
engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0}
@@ -4187,12 +4229,6 @@ packages:
react-dom:
optional: true
react-simple-code-editor@0.14.1:
resolution: {integrity: sha512-BR5DtNRy+AswWJECyA17qhUDvrrCZ6zXOCfkQY5zSmb96BVUbpVAv03WpcjcwtCwiLbIANx3gebHOcXYn1EHow==}
peerDependencies:
react: '>=16.8.0'
react-dom: '>=16.8.0'
react-virtuoso@4.17.0:
resolution: {integrity: sha512-od3pi2v13v31uzn5zPXC2u3ouISFCVhjFVFch2VvS2Cx7pWA2F1aJa3XhNTN2F07M3lhfnMnsmGeH+7wZICr7w==}
peerDependencies:
@@ -4523,6 +4559,9 @@ packages:
resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
engines: {node: '>=12'}
style-mod@4.1.3:
resolution: {integrity: sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==}
sucrase@3.35.0:
resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
engines: {node: '>=16 || 14 >=14.17'}
@@ -4821,12 +4860,6 @@ packages:
vite-plugin-compression2@2.5.1:
resolution: {integrity: sha512-2YpLZWs1ZRo9XwtSFA6/NVuBgOR+kvFk8M0HNDsP7Wu7OfJDOKT6fHB8kzuvw6jhgC9KYgDOttfaG2qC0wE9AQ==}
vite-plugin-prismjs-plus@1.1.1:
resolution: {integrity: sha512-RFmWuC3KiyXWe/Si3K2B2DOSITqUwVUtaSPoq+ss/7uo5tIdSi9lmrLjHlPe3G8AJCqhgTtKcPzM2HXUhwZ00A==}
peerDependencies:
prismjs: ^1.29.0
vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0
vite-plugin-svgr@4.5.0:
resolution: {integrity: sha512-W+uoSpmVkSmNOGPSsDCWVW/DDAyv+9fap9AZXBvWiQqrboJ08j2vh0tFxTD/LjwqwAd3yYSVJgm54S/1GhbdnA==}
peerDependencies:
@@ -4954,6 +4987,9 @@ packages:
jsdom:
optional: true
w3c-keyname@2.2.8:
resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==}
w3c-xmlserializer@4.0.0:
resolution: {integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==}
engines: {node: '>=14'}
@@ -5379,6 +5415,48 @@ snapshots:
optionalDependencies:
'@types/react': 19.1.12
'@codemirror/autocomplete@6.20.1':
dependencies:
'@codemirror/language': 6.12.3
'@codemirror/state': 6.6.0
'@codemirror/view': 6.40.0
'@lezer/common': 1.5.1
'@codemirror/commands@6.10.3':
dependencies:
'@codemirror/language': 6.12.3
'@codemirror/state': 6.6.0
'@codemirror/view': 6.40.0
'@lezer/common': 1.5.1
'@codemirror/lang-css@6.3.1':
dependencies:
'@codemirror/autocomplete': 6.20.1
'@codemirror/language': 6.12.3
'@codemirror/state': 6.6.0
'@lezer/common': 1.5.1
'@lezer/css': 1.3.3
'@codemirror/language@6.12.3':
dependencies:
'@codemirror/state': 6.6.0
'@codemirror/view': 6.40.0
'@lezer/common': 1.5.1
'@lezer/highlight': 1.2.3
'@lezer/lr': 1.4.8
style-mod: 4.1.3
'@codemirror/state@6.6.0':
dependencies:
'@marijn/find-cluster-break': 1.0.2
'@codemirror/view@6.40.0':
dependencies:
'@codemirror/state': 6.6.0
crelt: 1.0.6
style-mod: 4.1.3
w3c-keyname: 2.2.8
'@develar/schema-utils@2.6.5':
dependencies:
ajv: 6.14.0
@@ -5845,6 +5923,22 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
'@lezer/common@1.5.1': {}
'@lezer/css@1.3.3':
dependencies:
'@lezer/common': 1.5.1
'@lezer/highlight': 1.2.3
'@lezer/lr': 1.4.8
'@lezer/highlight@1.2.3':
dependencies:
'@lezer/common': 1.5.1
'@lezer/lr@1.4.8':
dependencies:
'@lezer/common': 1.5.1
'@malept/cross-spawn-promise@1.1.1':
dependencies:
cross-spawn: 7.0.6
@@ -5866,6 +5960,8 @@ snapshots:
dependencies:
react: 19.2.3
'@marijn/find-cluster-break@1.0.2': {}
'@napi-rs/wasm-runtime@1.1.1':
dependencies:
'@emnapi/core': 1.9.1
@@ -6629,8 +6725,6 @@ snapshots:
xmlbuilder: 15.1.1
optional: true
'@types/prismjs@1.26.6': {}
'@types/qrcode@1.5.6':
dependencies:
'@types/node': 25.4.0
@@ -6677,6 +6771,20 @@ snapshots:
'@types/node': 22.15.26
optional: true
'@uiw/codemirror-theme-vscode@4.25.9(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.40.0)':
dependencies:
'@uiw/codemirror-themes': 4.25.9(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.40.0)
transitivePeerDependencies:
- '@codemirror/language'
- '@codemirror/state'
- '@codemirror/view'
'@uiw/codemirror-themes@4.25.9(@codemirror/language@6.12.3)(@codemirror/state@6.6.0)(@codemirror/view@6.40.0)':
dependencies:
'@codemirror/language': 6.12.3
'@codemirror/state': 6.6.0
'@codemirror/view': 6.40.0
'@vitejs/plugin-react@5.2.0(vite@8.0.1(@types/node@25.4.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.92.0)(tsx@4.20.5))':
dependencies:
'@babel/core': 7.29.0
@@ -7314,6 +7422,8 @@ snapshots:
buffer: 5.7.1
optional: true
crelt@1.0.6: {}
cross-env@7.0.3:
dependencies:
cross-spawn: 7.0.3
@@ -8887,8 +8997,6 @@ snapshots:
picocolors: 1.1.1
source-map-js: 1.2.1
prismjs@1.30.0: {}
proc-log@2.0.1: {}
process-nextick-args@2.0.1: {}
@@ -8981,11 +9089,6 @@ snapshots:
optionalDependencies:
react-dom: 19.2.3(react@19.2.3)
react-simple-code-editor@0.14.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
dependencies:
react: 19.2.3
react-dom: 19.2.3(react@19.2.3)
react-virtuoso@4.17.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
dependencies:
react: 19.2.3
@@ -9409,6 +9512,8 @@ snapshots:
dependencies:
ansi-regex: 6.2.0
style-mod@4.1.3: {}
sucrase@3.35.0:
dependencies:
'@jridgewell/gen-mapping': 0.3.13
@@ -9695,11 +9800,6 @@ snapshots:
transitivePeerDependencies:
- rollup
vite-plugin-prismjs-plus@1.1.1(prismjs@1.30.0)(vite@8.0.1(@types/node@25.4.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.92.0)(tsx@4.20.5)):
dependencies:
prismjs: 1.30.0
vite: 8.0.1(@types/node@25.4.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.92.0)(tsx@4.20.5)
vite-plugin-svgr@4.5.0(rollup@4.59.0)(typescript@6.0.0-beta)(vite@8.0.1(@types/node@25.4.0)(esbuild@0.27.4)(jiti@2.6.1)(sass@1.92.0)(tsx@4.20.5)):
dependencies:
'@rollup/pluginutils': 5.3.0(rollup@4.59.0)
@@ -9846,6 +9946,8 @@ snapshots:
- tsx
- yaml
w3c-keyname@2.2.8: {}
w3c-xmlserializer@4.0.0:
dependencies:
xml-name-validator: 4.0.0