From c3657150da82ecca99c32d0e74beb491d346eb30 Mon Sep 17 00:00:00 2001 From: sukuwc Date: Wed, 14 Oct 2026 14:35:46 +0200 Subject: [PATCH 1/2] Bump grid-uikit for stale delete-confirm popup fix The delete-confirmation popup kept showing a previously selected profile's name after cancel + reselect, because grid-uikit's tooltip action never updated the already-mounted popup on prop changes. Fixed upstream in @intechstudio/grid-uikit@1.20261014.1208. That version also pulls in svelte-splitpanes@^8.0.12, which broke the webcomponent build (it imports the SvelteKit-only $app/environment). Shimmed it the same way grid-uikit's own demo and grid-editor already do. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01619XN25FUTzqut4YbzZPQr --- package-lock.json | 104 ++++++++++++++++++++++-------------- package.json | 2 +- src/app-environment-shim.ts | 7 +++ vite.config.webcomponent.ts | 27 ++++++++++ 4 files changed, 99 insertions(+), 41 deletions(-) create mode 100644 src/app-environment-shim.ts diff --git a/package-lock.json b/package-lock.json index 2df5720..8dbeca5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.0.1", "dependencies": { "@intechstudio/grid-protocol": "1.20260828.1315", - "@intechstudio/grid-uikit": "1.20260922.1223", + "@intechstudio/grid-uikit": "1.20261014.1208", "@melt-ui/svelte": "^0.86.6", "firebase": "^12.2.1", "marked": "^12.0.2", @@ -1255,18 +1255,28 @@ } }, "node_modules/@intechstudio/grid-uikit": { - "version": "1.20260922.1223", - "resolved": "https://registry.npmjs.org/@intechstudio/grid-uikit/-/grid-uikit-1.20260922.1223.tgz", - "integrity": "sha512-GEJICGrecYwLgCBLA+6Luz03O1Jrej13OoHN7mEohpkgsQV2+FW8TTYuSL4Z1eDfbY8Bs1JCrX3IgzXFrg6fCA==", + "version": "1.20261014.1208", + "resolved": "https://registry.npmjs.org/@intechstudio/grid-uikit/-/grid-uikit-1.20261014.1208.tgz", + "integrity": "sha512-Lvqp2VujI/GCOh92rQfGXxoYcLa1bDqRxPsthlDj/GrjfZUDdosI4h5EIDGSVpvYmeLUiaxead6UL2n9GXt+Og==", "dependencies": { "@melt-ui/svelte": "^0.86.6", "color-convert": "^2.0.1", - "svelte-easy-popover": "^1.0.0" + "svelte-easy-popover": "^1.0.0", + "svelte-splitpanes": "^8.0.12" }, "peerDependencies": { "svelte": "^4.2.12 || ^5.1.0" } }, + "node_modules/@intechstudio/grid-uikit/node_modules/svelte-splitpanes": { + "version": "8.0.12", + "resolved": "https://registry.npmjs.org/svelte-splitpanes/-/svelte-splitpanes-8.0.12.tgz", + "integrity": "sha512-HJ07HgbtY0Q/35TEuJquGy47dtgCVavV7ay9r1FhWRx3boyUs3RpeiHlwMKliznCKy2ZotNeT+8GG+mIoNjgRA==", + "license": "MIT", + "peerDependencies": { + "svelte": "^5.43.0" + } + }, "node_modules/@internationalized/date": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/@internationalized/date/-/date-3.9.0.tgz", @@ -1306,9 +1316,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -1773,9 +1783,9 @@ "license": "MIT" }, "node_modules/@sveltejs/acorn-typescript": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.6.tgz", - "integrity": "sha512-4awhxtMh4cx9blePWl10HRHj8Iivtqj+2QdDCSMDzxG+XKa9+VCNupQuCuvzEhYPzZSrX+0gC+0lHA/0fFKKQQ==", + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/@sveltejs/acorn-typescript/-/acorn-typescript-1.0.13.tgz", + "integrity": "sha512-wgKggnhZVL9Bfx1OaKKTrYY9BFRk6C8UAkQNUcIv1+llzYrIqy+RZm5HPKzn0NpEBvTVhTqB4kQyllZywsRBRQ==", "license": "MIT", "peerDependencies": { "acorn": "^8.9.0" @@ -2147,9 +2157,9 @@ "license": "MIT" }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.19.0.tgz", + "integrity": "sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==", "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -2217,9 +2227,9 @@ "license": "Python-2.0" }, "node_modules/aria-query": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", - "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.1.tgz", + "integrity": "sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==", "license": "Apache-2.0", "engines": { "node": ">= 0.4" @@ -2434,10 +2444,9 @@ } }, "node_modules/devalue": { - "version": "5.6.2", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.2.tgz", - "integrity": "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==", - "dev": true, + "version": "5.9.4", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.4.tgz", + "integrity": "sha512-sPAT4pztbu6586/hrhOnMKS17IJrvg12mXiSPSS3W5qDeN2RGgvZ0diZCm31dBbnevfVmujNO3IM2wrS4Y2Rhg==", "license": "MIT" }, "node_modules/dir-glob": { @@ -2781,15 +2790,6 @@ "node": ">=4.0" } }, - "node_modules/esrap": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.1.0.tgz", - "integrity": "sha512-yzmPNpl7TBbMRC5Lj2JlJZNPml0tzqoqP5B1JXycNUwtqma9AKCO0M2wHrdgsHcy1WRW7S9rJknAMtByg3usgA==", - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - } - }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -4155,21 +4155,22 @@ } }, "node_modules/svelte": { - "version": "5.39.8", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.39.8.tgz", - "integrity": "sha512-KfZ3hCITdxIXTOvrea4nFZX2o+47HPTChKeocgj9BwJQYqWrviVCcPj4boXHF5yf8+eBKqhHY8xii//XaakKXA==", + "version": "5.57.2", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.57.2.tgz", + "integrity": "sha512-1YiPCAXT0Ct6g1vOMmSLa0Nsc3QRMvtDF32ihgglGVrugIuIK38RyDiFNXVDhtQ81TJjSO57NdMw6DyYLqSGDQ==", "license": "MIT", "dependencies": { - "@jridgewell/remapping": "^2.3.4", - "@jridgewell/sourcemap-codec": "^1.5.0", - "@sveltejs/acorn-typescript": "^1.0.5", - "@types/estree": "^1.0.5", - "acorn": "^8.12.1", - "aria-query": "^5.3.1", + "@jridgewell/remapping": "^2.3.5", + "@jridgewell/sourcemap-codec": "^1.6.0", + "@sveltejs/acorn-typescript": "^1.0.13", + "@types/estree": "^1.0.9", + "acorn": "^8.18.0", + "aria-query": "5.3.1", "axobject-query": "^4.1.0", "clsx": "^2.1.1", + "devalue": "^5.9.2", "esm-env": "^1.2.1", - "esrap": "^2.1.0", + "esrap": "^2.3.6", "is-reference": "^3.0.3", "locate-character": "^3.0.0", "magic-string": "^0.30.11", @@ -4382,6 +4383,29 @@ "svelte": "^4.2.19 || ^5.1.0" } }, + "node_modules/svelte/node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "license": "MIT" + }, + "node_modules/svelte/node_modules/esrap": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-2.4.0.tgz", + "integrity": "sha512-CQPcneEHw/czj32uwQC52nYnax8H4SXt25FCM+LIwGZ49cMIxpOj3bP8wmzcI+Z0HIy5KkClaPhRLfCySzwHPA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "peerDependencies": { + "@typescript-eslint/types": "^8.2.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/types": { + "optional": true + } + } + }, "node_modules/tabbable": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", diff --git a/package.json b/package.json index ae8a0dc..cb083f8 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "type": "module", "dependencies": { "@intechstudio/grid-protocol": "1.20260828.1315", - "@intechstudio/grid-uikit": "1.20260922.1223", + "@intechstudio/grid-uikit": "1.20261014.1208", "@melt-ui/svelte": "^0.86.6", "firebase": "^12.2.1", "marked": "^12.0.2", diff --git a/src/app-environment-shim.ts b/src/app-environment-shim.ts new file mode 100644 index 0000000..e8fac33 --- /dev/null +++ b/src/app-environment-shim.ts @@ -0,0 +1,7 @@ +// Shim for $app/environment (a SvelteKit-only module) so svelte-splitpanes +// resolves outside SvelteKit. The webcomponent build is plain Vite, not a +// SvelteKit app, so this module doesn't exist there otherwise. +export const browser = true; +export const building = false; +export const dev = import.meta.env.DEV; +export const version = ""; diff --git a/vite.config.webcomponent.ts b/vite.config.webcomponent.ts index 5f64a3a..363b1c7 100644 --- a/vite.config.webcomponent.ts +++ b/vite.config.webcomponent.ts @@ -2,8 +2,35 @@ import { defineConfig } from "vite"; import { svelte } from "@sveltejs/vite-plugin-svelte"; import { sveltePreprocess } from "svelte-preprocess"; import { notifyEditorAfterBuildPlugin } from "./vite.postbuild"; +import path from "path"; export default defineConfig({ + resolve: { + alias: { + // svelte-splitpanes (pulled in transitively via grid-uikit's + // GridSplitpanes) imports the SvelteKit-only $app/environment module; + // this build isn't a SvelteKit app, so shim it. Same pattern as + // grid-uikit's own demo and grid-editor's renderer config. + "$app/environment": path.resolve( + __dirname, + "src/app-environment-shim.ts", + ), + }, + }, + optimizeDeps: { + esbuildOptions: { + plugins: [ + { + name: "resolve-app-environment", + setup(build) { + build.onResolve({ filter: /^\$app\/environment$/ }, () => ({ + path: path.resolve(__dirname, "src/app-environment-shim.ts"), + })); + }, + }, + ], + }, + }, plugins: [ svelte({ preprocess: sveltePreprocess({ From f303d8433ef4c57c00ba80c04f2d2b4010664724 Mon Sep 17 00:00:00 2001 From: sukuwc Date: Wed, 14 Oct 2026 14:50:01 +0200 Subject: [PATCH 2/2] Migrate splitpanes to grid-uikit GridSplitpanes/GridPane Replaces the direct svelte-splitpanes usage in EditorLayout with the grid-uikit wrappers and drops the direct dependency. The wrappers' theme ships as a separate CSS file the editor never loads for the webcomponent, so inject extracted CSS into components.js in the webcomponent build. Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01619XN25FUTzqut4YbzZPQr --- package-lock.json | 22 ---------------------- package.json | 1 - src/routes/EditorLayout.svelte | 20 ++++++++++++-------- vite.config.webcomponent.ts | 26 +++++++++++++++++++++++++- 4 files changed, 37 insertions(+), 32 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8dbeca5..e731ba6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,6 @@ "firebase": "^12.2.1", "marked": "^12.0.2", "semver-parser": "^4.1.4", - "svelte-splitpanes": "^8.0.9", "uuid": "^9.0.0", "ws": "^8.18.3", "zod": "^3.21.4" @@ -2740,15 +2739,6 @@ "integrity": "sha512-Epxrv+Nr/CaL4ZcFGPJIYLWFom+YeV1DqMLHJoEd9SYRxNbaFruBwfEX/kkHUJf55j2+TUbmDcmuilbP1TmXHA==", "license": "MIT" }, - "node_modules/esm-env-robust": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/esm-env-robust/-/esm-env-robust-0.0.3.tgz", - "integrity": "sha512-90Gnuw2DALOqlL1581VxP3GHPUNHX9U+fQ+8FNcTTFClhY5gEggAAnJ3q1b2Oq23knRsjv8YpNeMRPaMLUymOA==", - "license": "MIT", - "dependencies": { - "esm-env": "^1.0.0" - } - }, "node_modules/espree": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", @@ -4371,18 +4361,6 @@ } } }, - "node_modules/svelte-splitpanes": { - "version": "8.0.9", - "resolved": "https://registry.npmjs.org/svelte-splitpanes/-/svelte-splitpanes-8.0.9.tgz", - "integrity": "sha512-L3oLXTC99M191FInTXJ/f/2i0welRql1QuVbPaU8iy6nvCR6X9VyjHCsCpLqKGWHwqkWo/AM9CQ1c0nzlb+MkA==", - "license": "MIT", - "dependencies": { - "esm-env-robust": "0.0.3" - }, - "peerDependencies": { - "svelte": "^4.2.19 || ^5.1.0" - } - }, "node_modules/svelte/node_modules/@types/estree": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", diff --git a/package.json b/package.json index cb083f8..d5f65d4 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,6 @@ "firebase": "^12.2.1", "marked": "^12.0.2", "semver-parser": "^4.1.4", - "svelte-splitpanes": "^8.0.9", "uuid": "^9.0.0", "ws": "^8.18.3", "zod": "^3.21.4" diff --git a/src/routes/EditorLayout.svelte b/src/routes/EditorLayout.svelte index b9f2293..005e503 100644 --- a/src/routes/EditorLayout.svelte +++ b/src/routes/EditorLayout.svelte @@ -39,9 +39,13 @@ import { loginToProfileCloud } from "./user_account"; import Filter from "./Filter.svelte"; import ConfigCardDisplay from "./ConfigCardDisplay.svelte"; - import { Pane, Splitpanes } from "svelte-splitpanes"; import configuration from "../../Configuration.json"; - import { MeltCheckbox, MoltenPushButton } from "@intechstudio/grid-uikit"; + import { + GridPane, + GridSplitpanes, + MeltCheckbox, + MoltenPushButton, + } from "@intechstudio/grid-uikit"; import { compatible_config_types } from "./EditorLayout"; import { dragTarget } from "../lib/actions/drag.action"; import { @@ -745,17 +749,17 @@ {/if}
- - + +
handleSyncConfig(e.detail, true)} /> -
- +
-
-
+ +
diff --git a/vite.config.webcomponent.ts b/vite.config.webcomponent.ts index 363b1c7..2e0bc5d 100644 --- a/vite.config.webcomponent.ts +++ b/vite.config.webcomponent.ts @@ -1,9 +1,32 @@ -import { defineConfig } from "vite"; +import { defineConfig, type Plugin } from "vite"; import { svelte } from "@sveltejs/vite-plugin-svelte"; import { sveltePreprocess } from "svelte-preprocess"; import { notifyEditorAfterBuildPlugin } from "./vite.postbuild"; import path from "path"; +// The host editor only loads components.js, so any CSS vite extracts into a +// separate file (e.g. grid-uikit's splitpanes theme) never reaches the page. +function injectCssIntoJsPlugin(): Plugin { + return { + name: "inject-css-into-js", + apply: "build", + enforce: "post", + generateBundle(_, bundle) { + const cssFiles = Object.keys(bundle).filter((k) => k.endsWith(".css")); + const css = cssFiles + .map((k) => (bundle[k] as { source: string }).source) + .join("\n"); + if (!css) return; + for (const chunk of Object.values(bundle)) { + if (chunk.type === "chunk" && chunk.isEntry) { + chunk.code += `\n;(function(){try{var s=document.createElement("style");s.textContent=${JSON.stringify(css)};document.head.appendChild(s);}catch(e){}})();`; + } + } + cssFiles.forEach((k) => delete bundle[k]); + }, + }; +} + export default defineConfig({ resolve: { alias: { @@ -46,6 +69,7 @@ export default defineConfig({ }, emitCss: false, }), + injectCssIntoJsPlugin(), notifyEditorAfterBuildPlugin(), ], build: {