From ffe40f228541e10e30a92fea9acf3f1e718b9beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Sun, 3 Mar 2024 09:48:31 +0100 Subject: [PATCH 01/56] Update to Svelte v5 preview --- package-lock.json | 188 +++++++++++++++++--------------------- package.json | 2 +- src/routes/+layout.svelte | 18 ++-- 3 files changed, 94 insertions(+), 114 deletions(-) diff --git a/package-lock.json b/package-lock.json index d4d909d..f8e4f8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.1.2", - "svelte": "^4.2.8", + "svelte": "5.0.0-next.70", "svelte-check": "^3.6.2", "svelte-highlight": "^7.3.0", "svelte-local-storage-store": "^0.6.4", @@ -1137,6 +1137,19 @@ "vite": "^5.0.0" } }, + "node_modules/@sveltejs/vite-plugin-svelte/node_modules/svelte-hmr": { + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz", + "integrity": "sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==", + "dev": true, + "peer": true, + "engines": { + "node": "^12.20 || ^14.13.1 || >= 16" + }, + "peerDependencies": { + "svelte": "^3.19.0 || ^4.0.0" + } + }, "node_modules/@tailwindcss/typography": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.10.tgz", @@ -1668,9 +1681,9 @@ "dev": true }, "node_modules/acorn": { - "version": "8.11.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", - "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", + "version": "8.11.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", + "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -1688,6 +1701,15 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/acorn-typescript": { + "version": "1.4.13", + "resolved": "https://registry.npmjs.org/acorn-typescript/-/acorn-typescript-1.4.13.tgz", + "integrity": "sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q==", + "dev": true, + "peerDependencies": { + "acorn": ">=8.9.0" + } + }, "node_modules/acorn-walk": { "version": "8.3.1", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", @@ -1919,9 +1941,9 @@ } }, "node_modules/axobject-query": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", - "integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz", + "integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==", "dev": true, "dependencies": { "dequal": "^2.0.3" @@ -2282,19 +2304,6 @@ "node": ">=0.8" } }, - "node_modules/code-red": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz", - "integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15", - "@types/estree": "^1.0.1", - "acorn": "^8.10.0", - "estree-walker": "^3.0.3", - "periscopic": "^3.1.0" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2399,19 +2408,6 @@ "fastparse": "^1.1.2" } }, - "node_modules/css-tree": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", - "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.30", - "source-map-js": "^1.0.1" - }, - "engines": { - "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" - } - }, "node_modules/cssesc": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", @@ -3025,6 +3021,33 @@ "node": ">=4" } }, + "node_modules/eslint-plugin-svelte/node_modules/svelte-eslint-parser": { + "version": "0.33.1", + "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.33.1.tgz", + "integrity": "sha512-vo7xPGTlKBGdLH8T5L64FipvTrqv3OQRx9d2z5X05KKZDlF4rQk8KViZO4flKERY+5BiVdOh7zZ7JGJWo5P0uA==", + "dev": true, + "dependencies": { + "eslint-scope": "^7.0.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "postcss": "^8.4.29", + "postcss-scss": "^4.0.8" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "svelte": "^3.37.0 || ^4.0.0" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + } + } + }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -3100,6 +3123,16 @@ "node": ">=0.10" } }, + "node_modules/esrap": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.2.1.tgz", + "integrity": "sha512-dhkcOLfN/aDdMFI1iwPEcy/XqAZzGNfgfEJjZozy2tia6u0dQoZyXzkRshHTckuNsM+c0CYQndY+uRFe3N+AIQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15", + "@types/estree": "^1.0.1" + } + }, "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", @@ -5039,12 +5072,6 @@ "node": ">=0.10.0" } }, - "node_modules/mdn-data": { - "version": "2.0.30", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true - }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -5962,17 +5989,6 @@ "node": "*" } }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dev": true, - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" - } - }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -7059,27 +7075,27 @@ } }, "node_modules/svelte": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.8.tgz", - "integrity": "sha512-hU6dh1MPl8gh6klQZwK/n73GiAHiR95IkFsesLPbMeEZi36ydaXL/ZAb4g9sayT0MXzpxyZjR28yderJHxcmYA==", + "version": "5.0.0-next.70", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.70.tgz", + "integrity": "sha512-o24bDlhjz4MLdc9Lq1SVdLarv9MDgYFTOmzFcAqytRcG0AMOw+LGMoTb8gkFTACOu4exbvL18RS8Z8xgzIrDoA==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", "@jridgewell/sourcemap-codec": "^1.4.15", - "@jridgewell/trace-mapping": "^0.3.18", - "acorn": "^8.9.0", + "@types/estree": "^1.0.5", + "acorn": "^8.11.3", + "acorn-typescript": "^1.4.13", "aria-query": "^5.3.0", - "axobject-query": "^3.2.1", - "code-red": "^1.0.3", - "css-tree": "^2.3.1", - "estree-walker": "^3.0.3", - "is-reference": "^3.0.1", + "axobject-query": "^4.0.0", + "esm-env": "^1.0.0", + "esrap": "^1.2.1", + "is-reference": "^3.0.2", "locate-character": "^3.0.0", - "magic-string": "^0.30.4", - "periscopic": "^3.1.0" + "magic-string": "^0.30.5", + "zimmerframe": "^1.1.2" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/svelte-check": { @@ -7104,33 +7120,6 @@ "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" } }, - "node_modules/svelte-eslint-parser": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.33.1.tgz", - "integrity": "sha512-vo7xPGTlKBGdLH8T5L64FipvTrqv3OQRx9d2z5X05KKZDlF4rQk8KViZO4flKERY+5BiVdOh7zZ7JGJWo5P0uA==", - "dev": true, - "dependencies": { - "eslint-scope": "^7.0.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "postcss": "^8.4.29", - "postcss-scss": "^4.0.8" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "svelte": "^3.37.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "svelte": { - "optional": true - } - } - }, "node_modules/svelte-highlight": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/svelte-highlight/-/svelte-highlight-7.4.6.tgz", @@ -7140,19 +7129,6 @@ "highlight.js": "11.9.0" } }, - "node_modules/svelte-hmr": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/svelte-hmr/-/svelte-hmr-0.15.3.tgz", - "integrity": "sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==", - "dev": true, - "peer": true, - "engines": { - "node": "^12.20 || ^14.13.1 || >= 16" - }, - "peerDependencies": { - "svelte": "^3.19.0 || ^4.0.0" - } - }, "node_modules/svelte-local-storage-store": { "version": "0.6.4", "resolved": "https://registry.npmjs.org/svelte-local-storage-store/-/svelte-local-storage-store-0.6.4.tgz", @@ -8096,6 +8072,12 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zimmerframe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz", + "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==", + "dev": true } } } diff --git a/package.json b/package.json index 7dd4397..56b376d 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.1.2", - "svelte": "^4.2.8", + "svelte": "5.0.0-next.70", "svelte-check": "^3.6.2", "svelte-highlight": "^7.3.0", "svelte-local-storage-store": "^0.6.4", diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index 7cccac3..4872820 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -54,16 +54,14 @@

svelte-konva examples

diff --git a/src/routes/examples/connectFour/Game.svelte b/src/routes/examples/connectFour/Game.svelte index b50af40..7baade1 100644 --- a/src/routes/examples/connectFour/Game.svelte +++ b/src/routes/examples/connectFour/Game.svelte @@ -245,7 +245,7 @@
- +
diff --git a/src/routes/examples/connectFour/GameGrid.svelte b/src/routes/examples/connectFour/GameGrid.svelte index d0f665e..3cf018f 100644 --- a/src/routes/examples/connectFour/GameGrid.svelte +++ b/src/routes/examples/connectFour/GameGrid.svelte @@ -3,13 +3,19 @@ import Layer from 'svelte-konva/Layer.svelte'; import Stage from 'svelte-konva/Stage.svelte'; import type Konva from 'konva'; - import { onMount } from 'svelte'; + import { onMount, type Snippet } from 'svelte'; import { gameScale } from './store'; // Assets import grid from './assets/grid.svg'; import { GAME_BASE_SIZE } from './constants'; + type Props = { + children: Snippet; + }; + + let { children }: Props = $props(); + let container: HTMLDivElement; let stageConfig: Konva.ContainerConfig = { @@ -61,7 +67,7 @@ - + {@render children()} diff --git a/src/routes/examples/drawing/Drawing.svelte b/src/routes/examples/drawing/Drawing.svelte index 0fa2452..ac03e1d 100644 --- a/src/routes/examples/drawing/Drawing.svelte +++ b/src/routes/examples/drawing/Drawing.svelte @@ -99,11 +99,11 @@
(selectedTool = Tools.Pen)}>Pen (selectedTool = Tools.Eraser)}>Eraser
diff --git a/src/templates/svelteKonvaComponent.hbs b/src/templates/svelteKonvaComponent.hbs index d4798a8..e929b76 100644 --- a/src/templates/svelteKonvaComponent.hbs +++ b/src/templates/svelteKonvaComponent.hbs @@ -29,7 +29,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.{{ component interface $$Events extends KonvaEvents {} - let { config, staticConfig = false }: Props = $props(); + let { config = $bindable(), staticConfig = false }: Props = $props(); export const handle = new Konva.{{ componentName }}(config); From 2a18b6322f0a828c164a9994c96ae3cbc4f8e985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Wed, 24 Apr 2024 20:25:44 +0200 Subject: [PATCH 09/56] removed deprecated svelte event dispatcher, moved to Svelte 5 event hook functions instead. --- src/lib/Arc.svelte | 17 +-- src/lib/Arrow.svelte | 17 +-- src/lib/Circle.svelte | 17 +-- src/lib/Ellipse.svelte | 17 +-- src/lib/Group.svelte | 13 +-- src/lib/Image.svelte | 17 +-- src/lib/Label.svelte | 13 +-- src/lib/Layer.svelte | 13 +-- src/lib/Line.svelte | 17 +-- src/lib/Path.svelte | 17 +-- src/lib/Rect.svelte | 17 +-- src/lib/RegularPolygon.svelte | 17 +-- src/lib/Ring.svelte | 17 +-- src/lib/Shape.svelte | 17 +-- src/lib/Sprite.svelte | 17 +-- src/lib/Stage.svelte | 10 +- src/lib/Star.svelte | 17 +-- src/lib/Tag.svelte | 17 +-- src/lib/Text.svelte | 17 +-- src/lib/TextPath.svelte | 17 +-- src/lib/Transformer.svelte | 16 +-- src/lib/Wedge.svelte | 17 +-- src/lib/util/events.ts | 110 +++++++++--------- src/lib/util/props.ts | 3 +- src/routes/ResponsiveStage.svelte | 16 +-- src/routes/examples/connectFour/Token.svelte | 4 +- src/routes/examples/drawing/Drawing.svelte | 12 +- src/routes/examples/label/Label.svelte | 13 +-- .../examples/transform/Transform.svelte | 20 ++-- src/templates/svelteKonvaComponent.hbs | 17 +-- 30 files changed, 270 insertions(+), 279 deletions(-) diff --git a/src/lib/Arc.svelte b/src/lib/Arc.svelte index f83bc5f..653b18d 100644 --- a/src/lib/Arc.svelte +++ b/src/lib/Arc.svelte @@ -20,21 +20,22 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Arc.html), [ */ import Konva from 'konva'; - import { onMount, onDestroy, createEventDispatcher } from 'svelte'; - import type { Writable } from 'svelte/store'; - import { registerEvents, type KonvaEvents } from '$lib/util/events'; + import { onMount, onDestroy } from 'svelte'; + import { type Writable } from 'svelte/store'; + import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; - interface $$Events extends KonvaEvents {} - - let { config = $bindable(), staticConfig = false }: Props = $props(); + let { + config = $bindable(), + staticConfig = false, + ...eventHooks + }: Props = $props(); export const handle = new Konva.Arc(config); const parent: Writable = getParentContainer(); - const dispatcher = createEventDispatcher(); $effect(() => { handle.setAttrs(config); @@ -53,7 +54,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Arc.html), [ }); } - registerEvents(dispatcher, handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { diff --git a/src/lib/Arrow.svelte b/src/lib/Arrow.svelte index ebbd7b9..c698d49 100644 --- a/src/lib/Arrow.svelte +++ b/src/lib/Arrow.svelte @@ -20,21 +20,22 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Arrow.html), */ import Konva from 'konva'; - import { onMount, onDestroy, createEventDispatcher } from 'svelte'; - import type { Writable } from 'svelte/store'; - import { registerEvents, type KonvaEvents } from '$lib/util/events'; + import { onMount, onDestroy } from 'svelte'; + import { type Writable } from 'svelte/store'; + import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; - interface $$Events extends KonvaEvents {} - - let { config = $bindable(), staticConfig = false }: Props = $props(); + let { + config = $bindable(), + staticConfig = false, + ...eventHooks + }: Props = $props(); export const handle = new Konva.Arrow(config); const parent: Writable = getParentContainer(); - const dispatcher = createEventDispatcher(); $effect(() => { handle.setAttrs(config); @@ -53,7 +54,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Arrow.html), }); } - registerEvents(dispatcher, handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { diff --git a/src/lib/Circle.svelte b/src/lib/Circle.svelte index 5c42b5d..8bc8907 100644 --- a/src/lib/Circle.svelte +++ b/src/lib/Circle.svelte @@ -20,21 +20,22 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Circle.html) */ import Konva from 'konva'; - import { onMount, onDestroy, createEventDispatcher } from 'svelte'; - import type { Writable } from 'svelte/store'; - import { registerEvents, type KonvaEvents } from '$lib/util/events'; + import { onMount, onDestroy } from 'svelte'; + import { type Writable } from 'svelte/store'; + import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; - interface $$Events extends KonvaEvents {} - - let { config = $bindable(), staticConfig = false }: Props = $props(); + let { + config = $bindable(), + staticConfig = false, + ...eventHooks + }: Props = $props(); export const handle = new Konva.Circle(config); const parent: Writable = getParentContainer(); - const dispatcher = createEventDispatcher(); $effect(() => { handle.setAttrs(config); @@ -53,7 +54,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Circle.html) }); } - registerEvents(dispatcher, handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { diff --git a/src/lib/Ellipse.svelte b/src/lib/Ellipse.svelte index 3bb0710..4436ca7 100644 --- a/src/lib/Ellipse.svelte +++ b/src/lib/Ellipse.svelte @@ -20,21 +20,22 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Ellipse.html */ import Konva from 'konva'; - import { onMount, onDestroy, createEventDispatcher } from 'svelte'; - import type { Writable } from 'svelte/store'; - import { registerEvents, type KonvaEvents } from '$lib/util/events'; + import { onMount, onDestroy } from 'svelte'; + import { type Writable } from 'svelte/store'; + import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; - interface $$Events extends KonvaEvents {} - - let { config = $bindable(), staticConfig = false }: Props = $props(); + let { + config = $bindable(), + staticConfig = false, + ...eventHooks + }: Props = $props(); export const handle = new Konva.Ellipse(config); const parent: Writable = getParentContainer(); - const dispatcher = createEventDispatcher(); $effect(() => { handle.setAttrs(config); @@ -53,7 +54,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Ellipse.html }); } - registerEvents(dispatcher, handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { diff --git a/src/lib/Group.svelte b/src/lib/Group.svelte index 51c1a2a..ebe623e 100644 --- a/src/lib/Group.svelte +++ b/src/lib/Group.svelte @@ -20,7 +20,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Group.html), -->
- + {@render children()}
diff --git a/src/routes/examples/connectFour/Token.svelte b/src/routes/examples/connectFour/Token.svelte index bf4cfde..a957a8a 100644 --- a/src/routes/examples/connectFour/Token.svelte +++ b/src/routes/examples/connectFour/Token.svelte @@ -93,7 +93,7 @@ // On dragend we need to check if the token/stone has been moved into a position where it can be dropped into the game grid function handleDragEnd(e: KonvaDragTransformEvent) { // stop propagation as the event handling is done in this component - e.stopPropagation(); + e.cancelBubble = true; // as the circle config is bound we already know the current position of the circle and do not need to extract it from the event manually if (config.y! < TOKEN_DROP_THRESHOLD_Y) { @@ -159,4 +159,4 @@ } - + diff --git a/src/routes/examples/drawing/Drawing.svelte b/src/routes/examples/drawing/Drawing.svelte index ac03e1d..d4698ef 100644 --- a/src/routes/examples/drawing/Drawing.svelte +++ b/src/routes/examples/drawing/Drawing.svelte @@ -84,10 +84,8 @@ } function drawMouseOut(e: KonvaMouseEvent) { - const konvaEvent = e.detail; - // Check if event target is stage (eg. user clicked on empty part of the stage and not any shape) - if (konvaEvent.target.getType() !== 'Stage') { + if (e.target.getType() !== 'Stage') { return; } @@ -113,10 +111,10 @@
diff --git a/src/routes/examples/label/Label.svelte b/src/routes/examples/label/Label.svelte index e753d3b..a508359 100644 --- a/src/routes/examples/label/Label.svelte +++ b/src/routes/examples/label/Label.svelte @@ -8,6 +8,7 @@ import Label from 'svelte-konva/Label.svelte'; import Tag from 'svelte-konva/Tag.svelte'; import Text from 'svelte-konva/Text.svelte'; + import type { KonvaMouseEvent } from 'svelte-konva'; let circles: Array = []; @@ -52,12 +53,10 @@ fill: 'white' }; - function handleMouseEnter(e: CustomEvent>) { - const konvaEvent = e.detail; - - let hoveredElementPos = konvaEvent.target.getPosition(); - let hoveredElementRadius = konvaEvent.target.attrs.radius; - let hoveredElementName = konvaEvent.target.attrs.name; + function handleMouseEnter(e: KonvaMouseEvent) { + let hoveredElementPos = e.target.getPosition(); + let hoveredElementRadius = e.target.attrs.radius; + let hoveredElementName = e.target.attrs.name; labelConfig.x = hoveredElementPos.x; labelConfig.y = hoveredElementPos.y - hoveredElementRadius; @@ -75,7 +74,7 @@ {#each circles as config} - + {/each}
{#if isReady && children} {@render children()} diff --git a/src/routes/ResponsiveStage.svelte b/src/routes/ResponsiveStage.svelte index 1445bac..912f8a0 100644 --- a/src/routes/ResponsiveStage.svelte +++ b/src/routes/ResponsiveStage.svelte @@ -9,7 +9,15 @@ handle?: null | Konva.Stage; } & KonvaEventHooks; - let { children, handle = $bindable(), ...restProps }: Props = $props(); + let { + children, + handle = $bindable(), + onpointerdblclick, + onpointerdown, + onpointerup, + onpointermove, + onmouseout + }: Props = $props(); let container: HTMLDivElement; @@ -43,7 +51,16 @@
- + {@render children()}
From 21bef3737043d0d14e6fe52a32f1971eb66276ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Thu, 25 Apr 2024 19:12:58 +0200 Subject: [PATCH 11/56] Expose handle via props using a shadow variable to prevent overwriting, update svelte package (fixes dist output types) --- package-lock.json | 35 ++++++++++++-------------- package.json | 2 +- src/lib/Arc.svelte | 23 +++++++++-------- src/lib/Arrow.svelte | 23 +++++++++-------- src/lib/Circle.svelte | 23 +++++++++-------- src/lib/Ellipse.svelte | 23 +++++++++-------- src/lib/Group.svelte | 25 ++++++++++-------- src/lib/Image.svelte | 23 +++++++++-------- src/lib/Label.svelte | 25 ++++++++++-------- src/lib/Layer.svelte | 27 ++++++++++---------- src/lib/Line.svelte | 23 +++++++++-------- src/lib/Path.svelte | 23 +++++++++-------- src/lib/Rect.svelte | 23 +++++++++-------- src/lib/RegularPolygon.svelte | 23 +++++++++-------- src/lib/Ring.svelte | 23 +++++++++-------- src/lib/Shape.svelte | 23 +++++++++-------- src/lib/Sprite.svelte | 23 +++++++++-------- src/lib/Stage.svelte | 2 +- src/lib/Star.svelte | 23 +++++++++-------- src/lib/Tag.svelte | 23 +++++++++-------- src/lib/Text.svelte | 23 +++++++++-------- src/lib/TextPath.svelte | 23 +++++++++-------- src/lib/Transformer.svelte | 23 +++++++++-------- src/lib/Wedge.svelte | 23 +++++++++-------- src/lib/util/props.ts | 10 ++++---- src/templates/svelteKonvaComponent.hbs | 23 +++++++++-------- 26 files changed, 312 insertions(+), 251 deletions(-) diff --git a/package-lock.json b/package-lock.json index 59b0429..5680143 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,7 @@ "devDependencies": { "@sveltejs/adapter-static": "^3.0.1", "@sveltejs/kit": "^2.5.7", - "@sveltejs/package": "^2.1.0", + "@sveltejs/package": "^2.3.1", "@tailwindcss/typography": "^0.5.7", "@testing-library/svelte": "^5.1.0", "@types/lodash.clonedeep": "^4.5.7", @@ -1075,16 +1075,16 @@ } }, "node_modules/@sveltejs/package": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@sveltejs/package/-/package-2.2.5.tgz", - "integrity": "sha512-H0dFDrp7b/tr4zrUzOfqPKHG8y6ceNlGKPfSpp4ym1kTPWP79Mea5rvDlcmsbOS26FmHN/vttubalBdOCGA6qA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@sveltejs/package/-/package-2.3.1.tgz", + "integrity": "sha512-JvR2J4ost1oCn1CSdqenYRwGX/1RX+7LN+VZ71aPnz3JAlIFaEKQd1pBxlb+OSQTfeugJO0W39gB9voAbBO5ow==", "dev": true, "dependencies": { - "chokidar": "^3.5.3", + "chokidar": "^3.6.0", "kleur": "^4.1.5", "sade": "^1.8.1", "semver": "^7.5.4", - "svelte2tsx": "~0.6.27" + "svelte2tsx": "~0.7.0" }, "bin": { "svelte-package": "svelte-package.js" @@ -1093,7 +1093,7 @@ "node": "^16.14 || >=18" }, "peerDependencies": { - "svelte": "^3.44.0 || ^4.0.0" + "svelte": "^3.44.0 || ^4.0.0 || ^5.0.0-next.1" } }, "node_modules/@sveltejs/vite-plugin-svelte": { @@ -2210,16 +2210,10 @@ } }, "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", @@ -2232,6 +2226,9 @@ "engines": { "node": ">= 8.10.0" }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, "optionalDependencies": { "fsevents": "~2.3.2" } @@ -7224,9 +7221,9 @@ } }, "node_modules/svelte2tsx": { - "version": "0.6.27", - "resolved": "https://registry.npmjs.org/svelte2tsx/-/svelte2tsx-0.6.27.tgz", - "integrity": "sha512-E1uPW1o6VsbRz+nUk3fznZ2lSmCITAJoNu8AYefWSvIwE2pSB01i5sId4RMbWNzfcwCQl1DcgGShCPcldl4rvg==", + "version": "0.7.7", + "resolved": "https://registry.npmjs.org/svelte2tsx/-/svelte2tsx-0.7.7.tgz", + "integrity": "sha512-HAIxtk5TUHXvCRKApKfxoh1BGT85S/17lS3DvbfxRKFd+Ghr5YScqBvd+sU+p7vJFw48LNkzdFk+ooNVk3e4kA==", "dev": true, "dependencies": { "dedent-js": "^1.0.1", diff --git a/package.json b/package.json index fb27d91..bc941c9 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "devDependencies": { "@sveltejs/adapter-static": "^3.0.1", "@sveltejs/kit": "^2.5.7", - "@sveltejs/package": "^2.1.0", + "@sveltejs/package": "^2.3.1", "@tailwindcss/typography": "^0.5.7", "@testing-library/svelte": "^5.1.0", "@types/lodash.clonedeep": "^4.5.7", diff --git a/src/lib/Arc.svelte b/src/lib/Arc.svelte index 653b18d..b8b1aac 100644 --- a/src/lib/Arc.svelte +++ b/src/lib/Arc.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Arc.html), [ let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Arc(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Arc(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Arrow.svelte b/src/lib/Arrow.svelte index c698d49..f881a56 100644 --- a/src/lib/Arrow.svelte +++ b/src/lib/Arrow.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Arrow.html), let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Arrow(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Arrow(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Circle.svelte b/src/lib/Circle.svelte index 8bc8907..6627aba 100644 --- a/src/lib/Circle.svelte +++ b/src/lib/Circle.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Circle.html) let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Circle(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Circle(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Ellipse.svelte b/src/lib/Ellipse.svelte index 4436ca7..af2328c 100644 --- a/src/lib/Ellipse.svelte +++ b/src/lib/Ellipse.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Ellipse.html let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Ellipse(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Ellipse(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Group.svelte b/src/lib/Group.svelte index ebe623e..37c2048 100644 --- a/src/lib/Group.svelte +++ b/src/lib/Group.svelte @@ -36,42 +36,45 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Group.html), children, config = $bindable({}), staticConfig = false, + handle = $bindable(), ...eventHooks - }: PropsContainer = $props(); + }: PropsContainer = $props(); - export const handle = new Konva.Group(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Group(config); + handle = _handle; const inner = writable(null); let isReady = $state(false); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); const parent: Writable = getParentContainer(); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); - inner.set(handle); + inner.set(_handle); isReady = true; }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); setContainerContext(Container.Group, inner); diff --git a/src/lib/Image.svelte b/src/lib/Image.svelte index 91518f1..c6a1a22 100644 --- a/src/lib/Image.svelte +++ b/src/lib/Image.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Image.html), let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Image(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Image(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Label.svelte b/src/lib/Label.svelte index b422e7d..8c3e32d 100644 --- a/src/lib/Label.svelte +++ b/src/lib/Label.svelte @@ -37,42 +37,45 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Label.html), children, config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: PropsContainer = $props(); + }: PropsContainer = $props(); - export const handle = new Konva.Label(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Label(config); + handle = _handle; const inner = writable(null); let isReady = $state(false); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); const parent: Writable = getParentContainer(); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); - inner.set(handle); + inner.set(_handle); isReady = true; }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); setContainerContext(Container.Label, inner); diff --git a/src/lib/Layer.svelte b/src/lib/Layer.svelte index a12f30c..a7f11b1 100644 --- a/src/lib/Layer.svelte +++ b/src/lib/Layer.svelte @@ -33,44 +33,45 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Layer.html), children, config = $bindable({}), staticConfig = false, + handle = $bindable(), ...eventHooks - }: PropsContainer = $props(); + }: PropsContainer = $props(); - export const handle = new Konva.Layer(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Layer(config); + handle = _handle; const inner = writable(null); let isReady = $state(false); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); let parent: Writable = getParentStage(); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); - inner.set(handle); + inner.set(_handle); isReady = true; }); onDestroy(() => { - if (handle) { - handle.destroy(); - } + _handle.destroy(); }); setContainerContext(Container.Layer, inner); diff --git a/src/lib/Line.svelte b/src/lib/Line.svelte index c0ea819..79d5d8b 100644 --- a/src/lib/Line.svelte +++ b/src/lib/Line.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Line.html), let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Line(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Line(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Path.svelte b/src/lib/Path.svelte index 12c8794..019d141 100644 --- a/src/lib/Path.svelte +++ b/src/lib/Path.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Path.html), let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Path(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Path(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Rect.svelte b/src/lib/Rect.svelte index bb9721a..2bc3c21 100644 --- a/src/lib/Rect.svelte +++ b/src/lib/Rect.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Rect.html), let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Rect(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Rect(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/RegularPolygon.svelte b/src/lib/RegularPolygon.svelte index 9f670b0..3f1cf8d 100644 --- a/src/lib/RegularPolygon.svelte +++ b/src/lib/RegularPolygon.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.RegularPolyg let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.RegularPolygon(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.RegularPolygon(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Ring.svelte b/src/lib/Ring.svelte index 0ccb6b5..c3a7194 100644 --- a/src/lib/Ring.svelte +++ b/src/lib/Ring.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Ring.html), let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Ring(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Ring(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Shape.svelte b/src/lib/Shape.svelte index 2a7c46b..658cdbd 100644 --- a/src/lib/Shape.svelte +++ b/src/lib/Shape.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Shape.html), let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Shape(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Shape(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Sprite.svelte b/src/lib/Sprite.svelte index 096b714..36154e8 100644 --- a/src/lib/Sprite.svelte +++ b/src/lib/Sprite.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Sprite.html) let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Sprite(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Sprite(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Stage.svelte b/src/lib/Stage.svelte index 7bcc194..339ac26 100644 --- a/src/lib/Stage.svelte +++ b/src/lib/Stage.svelte @@ -29,8 +29,8 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), let { children, config = $bindable(), - handle = $bindable(), staticConfig = false, + handle = $bindable(), ...restProps }: StageProps = $props(); handle = null; // A bit of a workaround as bindings on fallback values are disallowed in runes mode (https://github.com/sveltejs/svelte/issues/9764) diff --git a/src/lib/Star.svelte b/src/lib/Star.svelte index b642df6..c412646 100644 --- a/src/lib/Star.svelte +++ b/src/lib/Star.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Star.html), let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Star(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Star(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Tag.svelte b/src/lib/Tag.svelte index 550ec9a..1bb8f65 100644 --- a/src/lib/Tag.svelte +++ b/src/lib/Tag.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Tag.html), [ let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Tag(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Tag(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Text.svelte b/src/lib/Text.svelte index 74ad1bf..986d418 100644 --- a/src/lib/Text.svelte +++ b/src/lib/Text.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Text.html), let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Text(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Text(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/TextPath.svelte b/src/lib/TextPath.svelte index 44c45fe..8c5c050 100644 --- a/src/lib/TextPath.svelte +++ b/src/lib/TextPath.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.TextPath.htm let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.TextPath(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.TextPath(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Transformer.svelte b/src/lib/Transformer.svelte index 191c2e0..22d45dd 100644 --- a/src/lib/Transformer.svelte +++ b/src/lib/Transformer.svelte @@ -35,34 +35,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Transformer. let { config = $bindable({}), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Transformer(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Transformer(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/Wedge.svelte b/src/lib/Wedge.svelte index 93e48be..1e7fdc4 100644 --- a/src/lib/Wedge.svelte +++ b/src/lib/Wedge.svelte @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Wedge.html), let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.Wedge(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.Wedge(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); diff --git a/src/lib/util/props.ts b/src/lib/util/props.ts index b6a65ea..4fac746 100644 --- a/src/lib/util/props.ts +++ b/src/lib/util/props.ts @@ -1,26 +1,26 @@ import type Konva from 'konva'; -import type { Bindable, Snippet } from 'svelte'; +import type { Bindable, Binding, Snippet } from 'svelte'; import { type KonvaEventHooks } from '$lib/util/events'; /** * Shared props type used on all svelte-konva components */ -export type Props = { +export type Props = { config: Config; staticConfig?: boolean; + handle?: Node; } & KonvaEventHooks; /** * Props extension for konva container types which can hold more konva nodes */ -export interface PropsContainer extends Props { +export interface PropsContainer extends Props { children?: Snippet; } /** * Special props extension for svelte-konva Stage (Forwards rest props to canvas div container) */ -export interface StageProps extends PropsContainer { - readonly handle?: null | Konva.Stage; +export interface StageProps extends PropsContainer { [key: string]: any; } diff --git a/src/templates/svelteKonvaComponent.hbs b/src/templates/svelteKonvaComponent.hbs index d0db478..a98db8d 100644 --- a/src/templates/svelteKonvaComponent.hbs +++ b/src/templates/svelteKonvaComponent.hbs @@ -30,34 +30,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.{{ component let { config = $bindable(), staticConfig = false, + handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - export const handle = new Konva.{{ componentName }}(config); + // Hide inner handle behind a shadow variable to prevent users from overwriting it + const _handle = new Konva.{{ componentName }}(config); + handle = _handle; const parent: Writable = getParentContainer(); $effect(() => { - handle.setAttrs(config); + _handle.setAttrs(config); }); onMount(() => { - $parent!.add(handle); + $parent!.add(_handle); if (!staticConfig) { - handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('transformend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); - handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + _handle.on('dragend', () => { + copyExistingKeys(config, _handle.getAttrs()); }); } - registerEvents(eventHooks, handle); + registerEvents(eventHooks, _handle); }); onDestroy(() => { - handle.destroy(); + _handle.destroy(); }); From a55b88f6af631da3df48b0be692da04bdfae143b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 26 Apr 2024 08:06:36 +0200 Subject: [PATCH 12/56] Update eslint and svelte check --- package-lock.json | 283 +++++++++++++++++++++++----------------------- package.json | 12 +- 2 files changed, 149 insertions(+), 146 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5680143..1039c01 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,13 +15,13 @@ "@tailwindcss/typography": "^0.5.7", "@testing-library/svelte": "^5.1.0", "@types/lodash.clonedeep": "^4.5.7", - "@typescript-eslint/eslint-plugin": "^7.1.0", - "@typescript-eslint/parser": "^7.1.0", + "@typescript-eslint/eslint-plugin": "^7.7.1", + "@typescript-eslint/parser": "^7.7.1", "canvas": "^2.11.2", "daisyui": "^4.4.2", - "eslint": "^8.28.0", + "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-svelte": "^2.31.0", + "eslint-plugin-svelte": "^2.38.0", "jsdom": "^24.0.0", "konva": "^9.2.0", "lodash.clonedeep": "^4.5.0", @@ -29,7 +29,7 @@ "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", "svelte": "5.0.0-next.114", - "svelte-check": "^3.6.9", + "svelte-check": "^3.7.0", "svelte-highlight": "^7.3.0", "svelte-local-storage-store": "^0.6.4", "svelte-preprocess": "^5.0.4", @@ -1305,25 +1305,25 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.0.tgz", - "integrity": "sha512-j6vT/kCulhG5wBmGtstKeiVr1rdXE4nk+DT1k6trYkwlrvW9eOF5ZbgKnd/YR6PcM4uTEXa0h6Fcvf6X7Dxl0w==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.7.1.tgz", + "integrity": "sha512-KwfdWXJBOviaBVhxO3p5TJiLpNuh2iyXyjmWN0f1nU87pwyvfS0EmjC6ukQVYVFJd/K1+0NWGPDXiyEyQorn0Q==", "dev": true, "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.1.0", - "@typescript-eslint/type-utils": "7.1.0", - "@typescript-eslint/utils": "7.1.0", - "@typescript-eslint/visitor-keys": "7.1.0", + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/type-utils": "7.7.1", + "@typescript-eslint/utils": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", "debug": "^4.3.4", "graphemer": "^1.4.0", - "ignore": "^5.2.4", + "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1340,19 +1340,19 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.1.0.tgz", - "integrity": "sha512-V1EknKUubZ1gWFjiOZhDSNToOjs63/9O0puCgGS8aDOgpZY326fzFu15QAUjwaXzRZjf/qdsdBrckYdv9YxB8w==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.7.1.tgz", + "integrity": "sha512-vmPzBOOtz48F6JAGVS/kZYk4EkXao6iGrD838sp1w3NQQC0W8ry/q641KU4PrG7AKNAf56NOcR8GOpH8l9FPCw==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.1.0", - "@typescript-eslint/types": "7.1.0", - "@typescript-eslint/typescript-estree": "7.1.0", - "@typescript-eslint/visitor-keys": "7.1.0", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", "debug": "^4.3.4" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1368,16 +1368,16 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.0.tgz", - "integrity": "sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.7.1.tgz", + "integrity": "sha512-PytBif2SF+9SpEUKynYn5g1RHFddJUcyynGpztX3l/ik7KmZEv19WCMhUBkHXPU9es/VWGD3/zg3wg90+Dh2rA==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.1.0", - "@typescript-eslint/visitor-keys": "7.1.0" + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1385,18 +1385,18 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.1.0.tgz", - "integrity": "sha512-UZIhv8G+5b5skkcuhgvxYWHjk7FW7/JP5lPASMEUoliAPwIH/rxoUSQPia2cuOj9AmDZmwUl1usKm85t5VUMew==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.7.1.tgz", + "integrity": "sha512-ZksJLW3WF7o75zaBPScdW1Gbkwhd/lyeXGf1kQCxJaOeITscoSl0MjynVvCzuV5boUz/3fOI06Lz8La55mu29Q==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.1.0", - "@typescript-eslint/utils": "7.1.0", + "@typescript-eslint/typescript-estree": "7.7.1", + "@typescript-eslint/utils": "7.7.1", "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1412,12 +1412,12 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.0.tgz", - "integrity": "sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.7.1.tgz", + "integrity": "sha512-AmPmnGW1ZLTpWa+/2omPrPfR7BcbUU4oha5VIbSbS1a1Tv966bklvLNXxp3mrbc+P2j4MNOTfDffNsk4o0c6/w==", "dev": true, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1425,22 +1425,22 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.0.tgz", - "integrity": "sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.7.1.tgz", + "integrity": "sha512-CXe0JHCXru8Fa36dteXqmH2YxngKJjkQLjxzoj6LYwzZ7qZvgsLSc+eqItCrqIop8Vl2UKoAi0StVWu97FQZIQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.1.0", - "@typescript-eslint/visitor-keys": "7.1.0", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/visitor-keys": "7.7.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^1.3.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1462,9 +1462,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", + "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" @@ -1477,21 +1477,21 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.1.0.tgz", - "integrity": "sha512-WUFba6PZC5OCGEmbweGpnNJytJiLG7ZvDBJJoUcX4qZYf1mGZ97mO2Mps6O2efxJcJdRNpqweCistDbZMwIVHw==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.7.1.tgz", + "integrity": "sha512-QUvBxPEaBXf41ZBbaidKICgVL8Hin0p6prQDu6bbetWo39BKbWJxRsErOzMNT1rXvTll+J7ChrbmMCXM9rsvOQ==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.1.0", - "@typescript-eslint/types": "7.1.0", - "@typescript-eslint/typescript-estree": "7.1.0", - "semver": "^7.5.4" + "@types/json-schema": "^7.0.15", + "@types/semver": "^7.5.8", + "@typescript-eslint/scope-manager": "7.7.1", + "@typescript-eslint/types": "7.7.1", + "@typescript-eslint/typescript-estree": "7.7.1", + "semver": "^7.6.0" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -1502,16 +1502,16 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.0.tgz", - "integrity": "sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.7.1.tgz", + "integrity": "sha512-gBL3Eq25uADw1LQ9kVpf3hRM+DWzs0uZknHYK3hq4jcTPqVCClHGDnB6UUUV2SFeBeA4KWHWbbLqmbGcZ4FYbw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.1.0", - "eslint-visitor-keys": "^3.4.1" + "@typescript-eslint/types": "7.7.1", + "eslint-visitor-keys": "^3.4.3" }, "engines": { - "node": "^16.0.0 || >=18.0.0" + "node": "^18.18.0 || >=20.0.0" }, "funding": { "type": "opencollective", @@ -2957,10 +2957,13 @@ } }, "node_modules/eslint-compat-utils": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.1.2.tgz", - "integrity": "sha512-Jia4JDldWnFNIru1Ehx1H5s9/yxiRHY/TimCuUc0jNexew3cF1gI6CYZil1ociakfWO3rRqFjl1mskBblB3RYg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.0.tgz", + "integrity": "sha512-dc6Y8tzEcSYZMHa+CMPLi/hyo1FzNeonbhJL7Ol0ccuKQkwopJcJBA9YL/xmMTLU1eKigXo9vj9nALElWYSowg==", "dev": true, + "dependencies": { + "semver": "^7.5.4" + }, "engines": { "node": ">=12" }, @@ -2981,23 +2984,23 @@ } }, "node_modules/eslint-plugin-svelte": { - "version": "2.35.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.35.1.tgz", - "integrity": "sha512-IF8TpLnROSGy98Z3NrsKXWDSCbNY2ReHDcrYTuXZMbfX7VmESISR78TWgO9zdg4Dht1X8coub5jKwHzP0ExRug==", + "version": "2.38.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-svelte/-/eslint-plugin-svelte-2.38.0.tgz", + "integrity": "sha512-IwwxhHzitx3dr0/xo0z4jjDlb2AAHBPKt+juMyKKGTLlKi1rZfA4qixMwnveU20/JTHyipM6keX4Vr7LZFYc9g==", "dev": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@jridgewell/sourcemap-codec": "^1.4.14", - "debug": "^4.3.1", - "eslint-compat-utils": "^0.1.2", + "@eslint-community/eslint-utils": "^4.4.0", + "@jridgewell/sourcemap-codec": "^1.4.15", + "debug": "^4.3.4", + "eslint-compat-utils": "^0.5.0", "esutils": "^2.0.3", - "known-css-properties": "^0.29.0", - "postcss": "^8.4.5", + "known-css-properties": "^0.30.0", + "postcss": "^8.4.38", "postcss-load-config": "^3.1.4", "postcss-safe-parser": "^6.0.0", - "postcss-selector-parser": "^6.0.11", - "semver": "^7.5.3", - "svelte-eslint-parser": ">=0.33.0 <1.0.0" + "postcss-selector-parser": "^6.0.16", + "semver": "^7.6.0", + "svelte-eslint-parser": ">=0.35.0 <1.0.0" }, "engines": { "node": "^14.17.0 || >=16.0.0" @@ -3006,8 +3009,8 @@ "url": "https://github.com/sponsors/ota-meshi" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0-0", - "svelte": "^3.37.0 || ^4.0.0" + "eslint": "^7.0.0 || ^8.0.0-0 || ^9.0.0-0", + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.112" }, "peerDependenciesMeta": { "svelte": { @@ -3016,9 +3019,9 @@ } }, "node_modules/eslint-plugin-svelte/node_modules/postcss-selector-parser": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz", - "integrity": "sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==", + "version": "6.0.16", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.16.tgz", + "integrity": "sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -3028,33 +3031,6 @@ "node": ">=4" } }, - "node_modules/eslint-plugin-svelte/node_modules/svelte-eslint-parser": { - "version": "0.33.1", - "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.33.1.tgz", - "integrity": "sha512-vo7xPGTlKBGdLH8T5L64FipvTrqv3OQRx9d2z5X05KKZDlF4rQk8KViZO4flKERY+5BiVdOh7zZ7JGJWo5P0uA==", - "dev": true, - "dependencies": { - "eslint-scope": "^7.0.0", - "eslint-visitor-keys": "^3.0.0", - "espree": "^9.0.0", - "postcss": "^8.4.29", - "postcss-scss": "^4.0.8" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "svelte": "^3.37.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "svelte": { - "optional": true - } - } - }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -4000,9 +3976,9 @@ ] }, "node_modules/ignore": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", - "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", "dev": true, "engines": { "node": ">= 4" @@ -4810,9 +4786,9 @@ } }, "node_modules/known-css-properties": { - "version": "0.29.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.29.0.tgz", - "integrity": "sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==", + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.30.0.tgz", + "integrity": "sha512-VSWXYUnsPu9+WYKkfmJyLKtIvaRJi1kXUqVmBACORXZQxT5oZDsoZ2vQP+bQFDnWtpI/4eq3MLoRMjI2fnLzTQ==", "dev": true }, "node_modules/konva": { @@ -6078,9 +6054,9 @@ } }, "node_modules/postcss": { - "version": "8.4.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", - "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", "dev": true, "funding": [ { @@ -6099,7 +6075,7 @@ "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "source-map-js": "^1.2.0" }, "engines": { "node": "^10 || ^12 || >=14" @@ -6686,9 +6662,9 @@ } }, "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", + "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -6888,9 +6864,9 @@ } }, "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, "engines": { "node": ">=0.10.0" @@ -7106,9 +7082,9 @@ } }, "node_modules/svelte-check": { - "version": "3.6.9", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.6.9.tgz", - "integrity": "sha512-hDQrk3L0osX07djQyMiXocKysTLfusqi8AriNcCiQxhQR49/LonYolcUGMtZ0fbUR8HTR198Prrgf52WWU9wEg==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.7.0.tgz", + "integrity": "sha512-Va6sGL4Vy4znn0K+vaatk98zoBvG2aDee4y3r5X4S80z8DXfbACHvdLlyXa4C4c5tQzK9H0Uq2pbd20wH3ucjQ==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", @@ -7127,6 +7103,33 @@ "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" } }, + "node_modules/svelte-eslint-parser": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.35.0.tgz", + "integrity": "sha512-CtbPseajW0gjwEvHiuzYJkPDjAcHz2FaHt540j6RVYrZgnE6xWkzUBodQ4I3nV+G5AS0Svt8K6aIA/CIU9xT2Q==", + "dev": true, + "dependencies": { + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "postcss": "^8.4.38", + "postcss-scss": "^4.0.9" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.112" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + } + } + }, "node_modules/svelte-highlight": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/svelte-highlight/-/svelte-highlight-7.4.6.tgz", @@ -7503,12 +7506,12 @@ } }, "node_modules/ts-api-utils": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.3.tgz", - "integrity": "sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, "engines": { - "node": ">=16.13.0" + "node": ">=16" }, "peerDependencies": { "typescript": ">=4.2.0" diff --git a/package.json b/package.json index bc941c9..8d69c42 100644 --- a/package.json +++ b/package.json @@ -49,13 +49,13 @@ "@tailwindcss/typography": "^0.5.7", "@testing-library/svelte": "^5.1.0", "@types/lodash.clonedeep": "^4.5.7", - "@typescript-eslint/eslint-plugin": "^7.1.0", - "@typescript-eslint/parser": "^7.1.0", + "@typescript-eslint/eslint-plugin": "^7.7.1", + "@typescript-eslint/parser": "^7.7.1", "canvas": "^2.11.2", "daisyui": "^4.4.2", - "eslint": "^8.28.0", + "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-svelte": "^2.31.0", + "eslint-plugin-svelte": "^2.38.0", "jsdom": "^24.0.0", "konva": "^9.2.0", "lodash.clonedeep": "^4.5.0", @@ -63,7 +63,7 @@ "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", "svelte": "5.0.0-next.114", - "svelte-check": "^3.6.9", + "svelte-check": "^3.7.0", "svelte-highlight": "^7.3.0", "svelte-local-storage-store": "^0.6.4", "svelte-preprocess": "^5.0.4", @@ -269,4 +269,4 @@ ] } } -} +} \ No newline at end of file From 7ebe1ea00acbdf965ccd735b29072c2dc3625e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 26 Apr 2024 08:08:23 +0200 Subject: [PATCH 13/56] Update svelte-persistent-store for svelte 5 compatibility --- package-lock.json | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1039c01..8dbed99 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,7 @@ "svelte": "5.0.0-next.114", "svelte-check": "^3.7.0", "svelte-highlight": "^7.3.0", - "svelte-local-storage-store": "^0.6.4", + "svelte-persisted-store": "^0.9.2", "svelte-preprocess": "^5.0.4", "tailwindcss": "^3.1.8", "tslib": "^2.5.3", @@ -7139,16 +7139,16 @@ "highlight.js": "11.9.0" } }, - "node_modules/svelte-local-storage-store": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/svelte-local-storage-store/-/svelte-local-storage-store-0.6.4.tgz", - "integrity": "sha512-45WoY2vSGPQM1sIQJ9jTkPPj20hYeqm+af6mUGRFSPP5WglZf36YYoZqwmZZ8Dt/2SU8lem+BTA8/Z/8TkqNLg==", + "node_modules/svelte-persisted-store": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/svelte-persisted-store/-/svelte-persisted-store-0.9.2.tgz", + "integrity": "sha512-jp7W98yMgBhgz5fWnjZBCmCX89Rse13iqVpjK+1ByS6iYkvW9WT+F2vwsep3f0Zy/tnGYbb8MI+9Vx7W0NQsPg==", "dev": true, "engines": { "node": ">=0.14" }, "peerDependencies": { - "svelte": "^3.48.0 || >4.0.0" + "svelte": "^3.48.0 || ^4.0.0 || ^5.0.0-next.0" } }, "node_modules/svelte-preprocess": { diff --git a/package.json b/package.json index 8d69c42..56bed2a 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,7 @@ "svelte": "5.0.0-next.114", "svelte-check": "^3.7.0", "svelte-highlight": "^7.3.0", - "svelte-local-storage-store": "^0.6.4", + "svelte-persisted-store": "^0.9.2", "svelte-preprocess": "^5.0.4", "tailwindcss": "^3.1.8", "tslib": "^2.5.3", From 9c314f194bbb4139665a8576f30506f873df494d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 26 Apr 2024 08:15:08 +0200 Subject: [PATCH 14/56] Fix wrong import --- src/routes/stores.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/stores.ts b/src/routes/stores.ts index 1011d98..02f2c5e 100644 --- a/src/routes/stores.ts +++ b/src/routes/stores.ts @@ -1,3 +1,3 @@ -import { persisted } from 'svelte-local-storage-store'; +import { persisted } from 'svelte-persisted-store'; export const darkMode = persisted('darkMode', false); From 632d661d1e3a7a318d8c4fd9a6bd38a8da9a56e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 26 Apr 2024 12:10:24 +0200 Subject: [PATCH 15/56] Fix optional config prop and clean up props --- src/lib/Group.svelte | 4 ++-- src/lib/Label.svelte | 4 ++-- src/lib/Layer.svelte | 4 ++-- src/lib/Stage.svelte | 4 ++-- src/lib/util/props.ts | 17 +++++++++++++---- src/templates/svelteKonvaComponent.hbs | 2 +- 6 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/lib/Group.svelte b/src/lib/Group.svelte index 37c2048..b6c61ac 100644 --- a/src/lib/Group.svelte +++ b/src/lib/Group.svelte @@ -30,7 +30,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Group.html), } from '$lib/util/manageContext'; import { registerEvents } from '$lib/util/events'; import { copyExistingKeys } from '$lib/util/object'; - import { type PropsContainer } from '$lib/util/props'; + import { type PropsContainer, type PropsOptionalConfig } from '$lib/util/props'; let { children, @@ -38,7 +38,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Group.html), staticConfig = false, handle = $bindable(), ...eventHooks - }: PropsContainer = $props(); + }: PropsOptionalConfig & PropsContainer = $props(); // Hide inner handle behind a shadow variable to prevent users from overwriting it const _handle = new Konva.Group(config); diff --git a/src/lib/Label.svelte b/src/lib/Label.svelte index 8c3e32d..a3231f2 100644 --- a/src/lib/Label.svelte +++ b/src/lib/Label.svelte @@ -31,7 +31,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Label.html), type KonvaParent } from '$lib/util/manageContext'; import { registerEvents } from '$lib/util/events'; - import { type PropsContainer } from '$lib/util/props'; + import { type Props, type PropsContainer } from '$lib/util/props'; let { children, @@ -39,7 +39,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Label.html), staticConfig = false, handle = $bindable(), ...eventHooks - }: PropsContainer = $props(); + }: Props & PropsContainer = $props(); // Hide inner handle behind a shadow variable to prevent users from overwriting it const _handle = new Konva.Label(config); diff --git a/src/lib/Layer.svelte b/src/lib/Layer.svelte index a7f11b1..e5457d2 100644 --- a/src/lib/Layer.svelte +++ b/src/lib/Layer.svelte @@ -27,7 +27,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Layer.html), import { Container, getParentStage, setContainerContext } from '$lib/util/manageContext'; import { registerEvents } from '$lib/util/events'; import { copyExistingKeys } from '$lib/util/object'; - import { type PropsContainer } from '$lib/util/props'; + import { type PropsContainer, type PropsOptionalConfig } from '$lib/util/props'; let { children, @@ -35,7 +35,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Layer.html), staticConfig = false, handle = $bindable(), ...eventHooks - }: PropsContainer = $props(); + }: PropsOptionalConfig & PropsContainer = $props(); // Hide inner handle behind a shadow variable to prevent users from overwriting it const _handle = new Konva.Layer(config); diff --git a/src/lib/Stage.svelte b/src/lib/Stage.svelte index 339ac26..d19d498 100644 --- a/src/lib/Stage.svelte +++ b/src/lib/Stage.svelte @@ -24,7 +24,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), import { registerEvents } from '$lib/util/events'; import { Container, setContainerContext } from '$lib/util/manageContext'; import { copyExistingKeys } from '$lib/util/object'; - import { type StageProps } from '$lib/util/props'; + import { type Props, type PropsContainer, type PropsStage } from '$lib/util/props'; let { children, @@ -32,7 +32,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), staticConfig = false, handle = $bindable(), ...restProps - }: StageProps = $props(); + }: Props & PropsContainer & PropsStage = $props(); handle = null; // A bit of a workaround as bindings on fallback values are disallowed in runes mode (https://github.com/sveltejs/svelte/issues/9764) let _handle: Konva.Stage | null = null; // Hide inner handle behind a shadow variable to prevent users from overwriting it diff --git a/src/lib/util/props.ts b/src/lib/util/props.ts index 4fac746..a1ad4ef 100644 --- a/src/lib/util/props.ts +++ b/src/lib/util/props.ts @@ -1,5 +1,4 @@ -import type Konva from 'konva'; -import type { Bindable, Binding, Snippet } from 'svelte'; +import type { Snippet } from 'svelte'; import { type KonvaEventHooks } from '$lib/util/events'; /** @@ -11,16 +10,26 @@ export type Props = { handle?: Node; } & KonvaEventHooks; +/** + * Same as Props but with optional Config + */ +export type PropsOptionalConfig = { + config?: Config; + staticConfig?: boolean; + handle?: Node; +} & KonvaEventHooks; + + /** * Props extension for konva container types which can hold more konva nodes */ -export interface PropsContainer extends Props { +export type PropsContainer = { children?: Snippet; } /** * Special props extension for svelte-konva Stage (Forwards rest props to canvas div container) */ -export interface StageProps extends PropsContainer { +export type PropsStage = { [key: string]: any; } diff --git a/src/templates/svelteKonvaComponent.hbs b/src/templates/svelteKonvaComponent.hbs index a98db8d..aeb92f3 100644 --- a/src/templates/svelteKonvaComponent.hbs +++ b/src/templates/svelteKonvaComponent.hbs @@ -27,7 +27,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.{{ component import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; - let { + let { config = $bindable(), staticConfig = false, handle = $bindable(), From 1b04a0179573e399939782d986efdc3f031a0dcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 26 Apr 2024 12:21:10 +0200 Subject: [PATCH 16/56] Fix rest props in combination with konva event hooks --- src/lib/Stage.svelte | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/lib/Stage.svelte b/src/lib/Stage.svelte index d19d498..bea81bd 100644 --- a/src/lib/Stage.svelte +++ b/src/lib/Stage.svelte @@ -31,6 +31,37 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), config = $bindable(), staticConfig = false, handle = $bindable(), + onclick, + ondblclick, + ondbltap, + ondragend, + ondragmove, + ondragstart, + onmousedown, + onmouseenter, + onmouseleave, + onmousemove, + onmouseout, + onmouseover, + onmouseup, + onpointercancel, + onpointerclick, + onpointerdblclick, + onpointerdown, + onpointerenter, + onpointerleave, + onpointermove, + onpointerout, + onpointerover, + onpointerup, + ontap, + ontouchend, + ontouchmove, + ontouchstart, + ontransform, + ontransformend, + ontransformstart, + onwheel, ...restProps }: Props & PropsContainer & PropsStage = $props(); handle = null; // A bit of a workaround as bindings on fallback values are disallowed in runes mode (https://github.com/sveltejs/svelte/issues/9764) From ed79335741a708b65c89a7c8c5d77fed373039ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 26 Apr 2024 12:34:03 +0200 Subject: [PATCH 17/56] Fix event hook registering in stage component --- src/lib/Stage.svelte | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/lib/Stage.svelte b/src/lib/Stage.svelte index bea81bd..2297ac8 100644 --- a/src/lib/Stage.svelte +++ b/src/lib/Stage.svelte @@ -91,7 +91,42 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), }); } - registerEvents(restProps, _handle); + registerEvents( + { + onclick, + ondblclick, + ondbltap, + ondragend, + ondragmove, + ondragstart, + onmousedown, + onmouseenter, + onmouseleave, + onmousemove, + onmouseout, + onmouseover, + onmouseup, + onpointercancel, + onpointerclick, + onpointerdblclick, + onpointerdown, + onpointerenter, + onpointerleave, + onpointermove, + onpointerout, + onpointerover, + onpointerup, + ontap, + ontouchend, + ontouchmove, + ontouchstart, + ontransform, + ontransformend, + ontransformstart, + onwheel + }, + _handle + ); inner.set(_handle); isReady = true; From 5ec3240b113177abd9e9f4125a96f06e253f9eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 26 Apr 2024 12:34:39 +0200 Subject: [PATCH 18/56] Do not use state as static value for other states --- src/routes/examples/connectFour/Game.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/routes/examples/connectFour/Game.svelte b/src/routes/examples/connectFour/Game.svelte index 7baade1..2846074 100644 --- a/src/routes/examples/connectFour/Game.svelte +++ b/src/routes/examples/connectFour/Game.svelte @@ -9,7 +9,7 @@ import { onDestroy } from 'svelte'; let activePlayer = $state(Player.Red); - let tokens: Array = $state([activePlayer]); + let tokens: Array = $state([Player.Red]); /** * Handle the end of a single player move From 3384c8289ab06a64f319acba5ea2b87537bddb9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 3 May 2024 10:32:53 +0200 Subject: [PATCH 19/56] Fix test config --- vite.config.ts | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/vite.config.ts b/vite.config.ts index 20c852f..d54f4da 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,7 +1,6 @@ import { sveltekit } from '@sveltejs/kit/vite'; import { svelteTesting } from '@testing-library/svelte/vite'; import type { UserConfig } from 'vite'; -import path from 'path'; const config: UserConfig = { plugins: [sveltekit(), svelteTesting()], @@ -21,19 +20,7 @@ const config: UserConfig = { alias: { '@testing-library/svelte': '@testing-library/svelte/svelte5' } - }, - // Workaround as in svelte tests onMount is not called due to being in nodejs environment (SSR) see: https://github.com/testing-library/svelte-testing-library/issues/222#issuecomment-1588987135 - // By directly importing the runtime we force Svelte to call it without onMount being replaced by noop - resolve: process.env.TEST - ? { - alias: [ - { - find: /^svelte$/, - replacement: path.join(__dirname, 'node_modules/svelte/src/runtime/index.js') - } - ] - } - : {} + } }; export default config; From e9897566569a1486622305abcaa75ffc945a6a3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 3 May 2024 10:33:01 +0200 Subject: [PATCH 20/56] format --- package.json | 2 +- src/lib/util/props.ts | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 56bed2a..89f7fdb 100644 --- a/package.json +++ b/package.json @@ -269,4 +269,4 @@ ] } } -} \ No newline at end of file +} diff --git a/src/lib/util/props.ts b/src/lib/util/props.ts index a1ad4ef..4b41c1e 100644 --- a/src/lib/util/props.ts +++ b/src/lib/util/props.ts @@ -19,17 +19,16 @@ export type PropsOptionalConfig = { handle?: Node; } & KonvaEventHooks; - /** * Props extension for konva container types which can hold more konva nodes */ export type PropsContainer = { children?: Snippet; -} +}; /** * Special props extension for svelte-konva Stage (Forwards rest props to canvas div container) */ export type PropsStage = { [key: string]: any; -} +}; From 47aabcbc5bbd228e5e55021c72e797dbfdcf52d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 3 May 2024 10:40:31 +0200 Subject: [PATCH 21/56] Update to svelte next 121 --- package-lock.json | 16 ++++++++-------- package.json | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8dbed99..ea25262 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", - "svelte": "5.0.0-next.114", + "svelte": "5.0.0-next.121", "svelte-check": "^3.7.0", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", @@ -3107,9 +3107,9 @@ } }, "node_modules/esrap": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.2.1.tgz", - "integrity": "sha512-dhkcOLfN/aDdMFI1iwPEcy/XqAZzGNfgfEJjZozy2tia6u0dQoZyXzkRshHTckuNsM+c0CYQndY+uRFe3N+AIQ==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/esrap/-/esrap-1.2.2.tgz", + "integrity": "sha512-F2pSJklxx1BlQIQgooczXCPHmcWpn6EsP5oo73LQfonG9fIlIENQ8vMmfGXeojP9MrkzUNAfyU5vdFlR9shHAw==", "dev": true, "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15", @@ -7058,9 +7058,9 @@ } }, "node_modules/svelte": { - "version": "5.0.0-next.114", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.114.tgz", - "integrity": "sha512-eMctRQVb7OSS+hiksy3+2iKw0wmg8B7VUP7tITmR4ZNYKe5C61OJaJQMo1IUBylLGMCjSOdGnHfC4Jb/xivM3Q==", + "version": "5.0.0-next.121", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.121.tgz", + "integrity": "sha512-dWxr42t8wv6iUmgKrYDG9RwQd2lf3vF2+ACYT7ziDnLeYItPM4sABmM8ptMaYL8czwtqpNzfCsxQR7ShN5PS9A==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", @@ -7071,7 +7071,7 @@ "aria-query": "^5.3.0", "axobject-query": "^4.0.0", "esm-env": "^1.0.0", - "esrap": "^1.2.1", + "esrap": "^1.2.2", "is-reference": "^3.0.2", "locate-character": "^3.0.0", "magic-string": "^0.30.5", diff --git a/package.json b/package.json index 89f7fdb..caf8576 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", - "svelte": "5.0.0-next.114", + "svelte": "5.0.0-next.121", "svelte-check": "^3.7.0", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", From 2f16d139ab6ff8ec683ea48019be806edf55c618 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 3 May 2024 14:56:34 +0200 Subject: [PATCH 22/56] Export handle as const prop to better match Svelte 5 paradigms and ease component testing --- src/lib/Arc.svelte | 23 ++++++++++------------- src/lib/Arrow.svelte | 23 ++++++++++------------- src/lib/Circle.svelte | 23 ++++++++++------------- src/lib/Ellipse.svelte | 23 ++++++++++------------- src/lib/Group.svelte | 25 +++++++++++-------------- src/lib/Image.svelte | 23 ++++++++++------------- src/lib/Label.svelte | 25 +++++++++++-------------- src/lib/Layer.svelte | 25 +++++++++++-------------- src/lib/Line.svelte | 23 ++++++++++------------- src/lib/Path.svelte | 23 ++++++++++------------- src/lib/Rect.svelte | 23 ++++++++++------------- src/lib/RegularPolygon.svelte | 23 ++++++++++------------- src/lib/Ring.svelte | 23 ++++++++++------------- src/lib/Shape.svelte | 23 ++++++++++------------- src/lib/Sprite.svelte | 23 ++++++++++------------- src/lib/Stage.svelte | 12 ++++++------ src/lib/Star.svelte | 23 ++++++++++------------- src/lib/Tag.svelte | 23 ++++++++++------------- src/lib/Text.svelte | 23 ++++++++++------------- src/lib/TextPath.svelte | 23 ++++++++++------------- src/lib/Transformer.svelte | 23 ++++++++++------------- src/lib/Wedge.svelte | 23 ++++++++++------------- src/lib/util/props.ts | 6 ++---- src/templates/svelteKonvaComponent.hbs | 23 ++++++++++------------- 24 files changed, 231 insertions(+), 299 deletions(-) diff --git a/src/lib/Arc.svelte b/src/lib/Arc.svelte index b8b1aac..653b18d 100644 --- a/src/lib/Arc.svelte +++ b/src/lib/Arc.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Arc.html), [ let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Arc(config); - handle = _handle; + export const handle = new Konva.Arc(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Arrow.svelte b/src/lib/Arrow.svelte index f881a56..c698d49 100644 --- a/src/lib/Arrow.svelte +++ b/src/lib/Arrow.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Arrow.html), let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Arrow(config); - handle = _handle; + export const handle = new Konva.Arrow(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Circle.svelte b/src/lib/Circle.svelte index 6627aba..8bc8907 100644 --- a/src/lib/Circle.svelte +++ b/src/lib/Circle.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Circle.html) let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Circle(config); - handle = _handle; + export const handle = new Konva.Circle(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Ellipse.svelte b/src/lib/Ellipse.svelte index af2328c..4436ca7 100644 --- a/src/lib/Ellipse.svelte +++ b/src/lib/Ellipse.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Ellipse.html let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Ellipse(config); - handle = _handle; + export const handle = new Konva.Ellipse(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Group.svelte b/src/lib/Group.svelte index b6c61ac..f04919d 100644 --- a/src/lib/Group.svelte +++ b/src/lib/Group.svelte @@ -36,45 +36,42 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Group.html), children, config = $bindable({}), staticConfig = false, - handle = $bindable(), ...eventHooks - }: PropsOptionalConfig & PropsContainer = $props(); + }: PropsOptionalConfig & PropsContainer = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Group(config); - handle = _handle; + export const handle = new Konva.Group(config); const inner = writable(null); let isReady = $state(false); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); const parent: Writable = getParentContainer(); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); - inner.set(_handle); + inner.set(handle); isReady = true; }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); setContainerContext(Container.Group, inner); diff --git a/src/lib/Image.svelte b/src/lib/Image.svelte index c6a1a22..91518f1 100644 --- a/src/lib/Image.svelte +++ b/src/lib/Image.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Image.html), let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Image(config); - handle = _handle; + export const handle = new Konva.Image(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Label.svelte b/src/lib/Label.svelte index a3231f2..9fb64c7 100644 --- a/src/lib/Label.svelte +++ b/src/lib/Label.svelte @@ -37,45 +37,42 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Label.html), children, config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props & PropsContainer = $props(); + }: Props & PropsContainer = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Label(config); - handle = _handle; + export const handle = new Konva.Label(config); const inner = writable(null); let isReady = $state(false); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); const parent: Writable = getParentContainer(); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); - inner.set(_handle); + inner.set(handle); isReady = true; }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); setContainerContext(Container.Label, inner); diff --git a/src/lib/Layer.svelte b/src/lib/Layer.svelte index e5457d2..f26aef1 100644 --- a/src/lib/Layer.svelte +++ b/src/lib/Layer.svelte @@ -33,45 +33,42 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Layer.html), children, config = $bindable({}), staticConfig = false, - handle = $bindable(), ...eventHooks - }: PropsOptionalConfig & PropsContainer = $props(); + }: PropsOptionalConfig & PropsContainer = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Layer(config); - handle = _handle; + export const handle = new Konva.Layer(config); const inner = writable(null); let isReady = $state(false); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); let parent: Writable = getParentStage(); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); - inner.set(_handle); + inner.set(handle); isReady = true; }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); setContainerContext(Container.Layer, inner); diff --git a/src/lib/Line.svelte b/src/lib/Line.svelte index 79d5d8b..c0ea819 100644 --- a/src/lib/Line.svelte +++ b/src/lib/Line.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Line.html), let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Line(config); - handle = _handle; + export const handle = new Konva.Line(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Path.svelte b/src/lib/Path.svelte index 019d141..12c8794 100644 --- a/src/lib/Path.svelte +++ b/src/lib/Path.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Path.html), let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Path(config); - handle = _handle; + export const handle = new Konva.Path(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Rect.svelte b/src/lib/Rect.svelte index 2bc3c21..bb9721a 100644 --- a/src/lib/Rect.svelte +++ b/src/lib/Rect.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Rect.html), let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Rect(config); - handle = _handle; + export const handle = new Konva.Rect(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/RegularPolygon.svelte b/src/lib/RegularPolygon.svelte index 3f1cf8d..9f670b0 100644 --- a/src/lib/RegularPolygon.svelte +++ b/src/lib/RegularPolygon.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.RegularPolyg let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.RegularPolygon(config); - handle = _handle; + export const handle = new Konva.RegularPolygon(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Ring.svelte b/src/lib/Ring.svelte index c3a7194..0ccb6b5 100644 --- a/src/lib/Ring.svelte +++ b/src/lib/Ring.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Ring.html), let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Ring(config); - handle = _handle; + export const handle = new Konva.Ring(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Shape.svelte b/src/lib/Shape.svelte index 658cdbd..2a7c46b 100644 --- a/src/lib/Shape.svelte +++ b/src/lib/Shape.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Shape.html), let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Shape(config); - handle = _handle; + export const handle = new Konva.Shape(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Sprite.svelte b/src/lib/Sprite.svelte index 36154e8..096b714 100644 --- a/src/lib/Sprite.svelte +++ b/src/lib/Sprite.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Sprite.html) let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Sprite(config); - handle = _handle; + export const handle = new Konva.Sprite(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Stage.svelte b/src/lib/Stage.svelte index 2297ac8..194530b 100644 --- a/src/lib/Stage.svelte +++ b/src/lib/Stage.svelte @@ -30,7 +30,6 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), children, config = $bindable(), staticConfig = false, - handle = $bindable(), onclick, ondblclick, ondbltap, @@ -63,9 +62,12 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), ontransformstart, onwheel, ...restProps - }: Props & PropsContainer & PropsStage = $props(); - handle = null; // A bit of a workaround as bindings on fallback values are disallowed in runes mode (https://github.com/sveltejs/svelte/issues/9764) - let _handle: Konva.Stage | null = null; // Hide inner handle behind a shadow variable to prevent users from overwriting it + }: Props & PropsContainer & PropsStage = $props(); + + let _handle: Konva.Stage | null = null; + export function handle() { + return _handle; + } const inner = writable(null); @@ -83,8 +85,6 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), ...config }); - handle = _handle; - if (!staticConfig) { _handle.on('dragend', () => { copyExistingKeys(config, _handle!.getAttrs()); diff --git a/src/lib/Star.svelte b/src/lib/Star.svelte index c412646..b642df6 100644 --- a/src/lib/Star.svelte +++ b/src/lib/Star.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Star.html), let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Star(config); - handle = _handle; + export const handle = new Konva.Star(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Tag.svelte b/src/lib/Tag.svelte index 1bb8f65..550ec9a 100644 --- a/src/lib/Tag.svelte +++ b/src/lib/Tag.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Tag.html), [ let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Tag(config); - handle = _handle; + export const handle = new Konva.Tag(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Text.svelte b/src/lib/Text.svelte index 986d418..74ad1bf 100644 --- a/src/lib/Text.svelte +++ b/src/lib/Text.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Text.html), let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Text(config); - handle = _handle; + export const handle = new Konva.Text(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/TextPath.svelte b/src/lib/TextPath.svelte index 8c5c050..44c45fe 100644 --- a/src/lib/TextPath.svelte +++ b/src/lib/TextPath.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.TextPath.htm let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.TextPath(config); - handle = _handle; + export const handle = new Konva.TextPath(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Transformer.svelte b/src/lib/Transformer.svelte index 22d45dd..191c2e0 100644 --- a/src/lib/Transformer.svelte +++ b/src/lib/Transformer.svelte @@ -35,37 +35,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Transformer. let { config = $bindable({}), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Transformer(config); - handle = _handle; + export const handle = new Konva.Transformer(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/Wedge.svelte b/src/lib/Wedge.svelte index 1e7fdc4..93e48be 100644 --- a/src/lib/Wedge.svelte +++ b/src/lib/Wedge.svelte @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Wedge.html), let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.Wedge(config); - handle = _handle; + export const handle = new Konva.Wedge(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); diff --git a/src/lib/util/props.ts b/src/lib/util/props.ts index 4b41c1e..c87ef46 100644 --- a/src/lib/util/props.ts +++ b/src/lib/util/props.ts @@ -4,19 +4,17 @@ import { type KonvaEventHooks } from '$lib/util/events'; /** * Shared props type used on all svelte-konva components */ -export type Props = { +export type Props = { config: Config; staticConfig?: boolean; - handle?: Node; } & KonvaEventHooks; /** * Same as Props but with optional Config */ -export type PropsOptionalConfig = { +export type PropsOptionalConfig = { config?: Config; staticConfig?: boolean; - handle?: Node; } & KonvaEventHooks; /** diff --git a/src/templates/svelteKonvaComponent.hbs b/src/templates/svelteKonvaComponent.hbs index aeb92f3..3f25bd0 100644 --- a/src/templates/svelteKonvaComponent.hbs +++ b/src/templates/svelteKonvaComponent.hbs @@ -30,37 +30,34 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.{{ component let { config = $bindable(), staticConfig = false, - handle = $bindable(), ...eventHooks - }: Props = $props(); + }: Props = $props(); - // Hide inner handle behind a shadow variable to prevent users from overwriting it - const _handle = new Konva.{{ componentName }}(config); - handle = _handle; + export const handle = new Konva.{{ componentName }}(config); const parent: Writable = getParentContainer(); $effect(() => { - _handle.setAttrs(config); + handle.setAttrs(config); }); onMount(() => { - $parent!.add(_handle); + $parent!.add(handle); if (!staticConfig) { - _handle.on('transformend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('transformend', () => { + copyExistingKeys(config, handle.getAttrs()); }); - _handle.on('dragend', () => { - copyExistingKeys(config, _handle.getAttrs()); + handle.on('dragend', () => { + copyExistingKeys(config, handle.getAttrs()); }); } - registerEvents(eventHooks, _handle); + registerEvents(eventHooks, handle); }); onDestroy(() => { - _handle.destroy(); + handle.destroy(); }); From 5f9cb2152276558c2d15a3921e1ca9d64e31c634 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 3 May 2024 17:51:46 +0200 Subject: [PATCH 23/56] Update vitest, update test cases to Svelte 5 --- package-lock.json | 171 ++++++++++---------- package.json | 2 +- src/templates/svelteKonvaComponentTests.hbs | 41 ++--- src/tests/arc.test.ts | 41 ++--- src/tests/arrow.test.ts | 41 ++--- src/tests/circle.test.ts | 41 ++--- src/tests/ellipse.test.ts | 41 ++--- src/tests/group.test.ts | 45 ++---- src/tests/image.test.ts | 45 ++---- src/tests/label.test.ts | 41 ++--- src/tests/layer.test.ts | 42 ++--- src/tests/line.test.ts | 41 ++--- src/tests/path.test.ts | 41 ++--- src/tests/rect.test.ts | 41 ++--- src/tests/regularpolygon.test.ts | 41 ++--- src/tests/ring.test.ts | 41 ++--- src/tests/shape.test.ts | 48 ++---- src/tests/sprite.test.ts | 7 +- src/tests/stage.test.ts | 38 ++--- src/tests/star.test.ts | 41 ++--- src/tests/tag.test.ts | 41 ++--- src/tests/text.test.ts | 41 ++--- src/tests/textpath.test.ts | 41 ++--- src/tests/wedge.test.ts | 41 ++--- 24 files changed, 306 insertions(+), 748 deletions(-) diff --git a/package-lock.json b/package-lock.json index ea25262..503582e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -37,7 +37,7 @@ "tslib": "^2.5.3", "typescript": "^5.4.2", "vite": "^5.0.0", - "vitest": "^1.1.0" + "vitest": "^1.5.3" }, "peerDependencies": { "konva": "8 - 9", @@ -1525,13 +1525,13 @@ "dev": true }, "node_modules/@vitest/expect": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.2.0.tgz", - "integrity": "sha512-H+2bHzhyvgp32o7Pgj2h9RTHN0pgYaoi26Oo3mE+dCi1PAqV31kIIVfTbqMO3Bvshd5mIrJLc73EwSRrbol9Lw==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.5.3.tgz", + "integrity": "sha512-y+waPz31pOFr3rD7vWTbwiLe5+MgsMm40jTZbQE8p8/qXyBX3CQsIXRx9XK12IbY7q/t5a5aM/ckt33b4PxK2g==", "dev": true, "dependencies": { - "@vitest/spy": "1.2.0", - "@vitest/utils": "1.2.0", + "@vitest/spy": "1.5.3", + "@vitest/utils": "1.5.3", "chai": "^4.3.10" }, "funding": { @@ -1539,12 +1539,12 @@ } }, "node_modules/@vitest/runner": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.2.0.tgz", - "integrity": "sha512-vaJkDoQaNUTroT70OhM0NPznP7H3WyRwt4LvGwCVYs/llLaqhoSLnlIhUClZpbF5RgAee29KRcNz0FEhYcgxqA==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.5.3.tgz", + "integrity": "sha512-7PlfuReN8692IKQIdCxwir1AOaP5THfNkp0Uc4BKr2na+9lALNit7ub9l3/R7MP8aV61+mHKRGiqEKRIwu6iiQ==", "dev": true, "dependencies": { - "@vitest/utils": "1.2.0", + "@vitest/utils": "1.5.3", "p-limit": "^5.0.0", "pathe": "^1.1.1" }, @@ -1580,9 +1580,9 @@ } }, "node_modules/@vitest/snapshot": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.2.0.tgz", - "integrity": "sha512-P33EE7TrVgB3HDLllrjK/GG6WSnmUtWohbwcQqmm7TAk9AVHpdgf7M3F3qRHKm6vhr7x3eGIln7VH052Smo6Kw==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.5.3.tgz", + "integrity": "sha512-K3mvIsjyKYBhNIDujMD2gfQEzddLe51nNOAf45yKRt/QFJcUIeTQd2trRvv6M6oCBHNVnZwFWbQ4yj96ibiDsA==", "dev": true, "dependencies": { "magic-string": "^0.30.5", @@ -1620,15 +1620,15 @@ } }, "node_modules/@vitest/snapshot/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true }, "node_modules/@vitest/spy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.2.0.tgz", - "integrity": "sha512-MNxSAfxUaCeowqyyGwC293yZgk7cECZU9wGb8N1pYQ0yOn/SIr8t0l9XnGRdQZvNV/ZHBYu6GO/W3tj5K3VN1Q==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.5.3.tgz", + "integrity": "sha512-Llj7Jgs6lbnL55WoshJUUacdJfjU2honvGcAJBxhra5TPEzTJH8ZuhI3p/JwqqfnTr4PmP7nDmOXP53MS7GJlg==", "dev": true, "dependencies": { "tinyspy": "^2.2.0" @@ -1638,9 +1638,9 @@ } }, "node_modules/@vitest/utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.2.0.tgz", - "integrity": "sha512-FyD5bpugsXlwVpTcGLDf3wSPYy8g541fQt14qtzo8mJ4LdEpDKZ9mQy2+qdJm2TZRpjY5JLXihXCgIxiRJgi5g==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.5.3.tgz", + "integrity": "sha512-rE9DTN1BRhzkzqNQO+kw8ZgfeEBCLXiHJwetk668shmNBpSagQxneT5eSqEBLP+cqSiAeecvQmbpFfdMyLcIQA==", "dev": true, "dependencies": { "diff-sequences": "^29.6.3", @@ -1679,9 +1679,9 @@ } }, "node_modules/@vitest/utils/node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true }, "node_modules/abbrev": { @@ -1721,9 +1721,9 @@ } }, "node_modules/acorn-walk": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.1.tgz", - "integrity": "sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", + "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", "dev": true, "engines": { "node": ">=0.4.0" @@ -3031,6 +3031,33 @@ "node": ">=4" } }, + "node_modules/eslint-plugin-svelte/node_modules/svelte-eslint-parser": { + "version": "0.35.0", + "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.35.0.tgz", + "integrity": "sha512-CtbPseajW0gjwEvHiuzYJkPDjAcHz2FaHt540j6RVYrZgnE6xWkzUBodQ4I3nV+G5AS0Svt8K6aIA/CIU9xT2Q==", + "dev": true, + "dependencies": { + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "postcss": "^8.4.38", + "postcss-scss": "^4.0.9" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.112" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + } + } + }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -6980,17 +7007,23 @@ } }, "node_modules/strip-literal": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", - "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz", + "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==", "dev": true, "dependencies": { - "acorn": "^8.10.0" + "js-tokens": "^9.0.0" }, "funding": { "url": "https://github.com/sponsors/antfu" } }, + "node_modules/strip-literal/node_modules/js-tokens": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz", + "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==", + "dev": true + }, "node_modules/sucrase": { "version": "3.34.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz", @@ -7103,33 +7136,6 @@ "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" } }, - "node_modules/svelte-eslint-parser": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.35.0.tgz", - "integrity": "sha512-CtbPseajW0gjwEvHiuzYJkPDjAcHz2FaHt540j6RVYrZgnE6xWkzUBodQ4I3nV+G5AS0Svt8K6aIA/CIU9xT2Q==", - "dev": true, - "dependencies": { - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "postcss": "^8.4.38", - "postcss-scss": "^4.0.9" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.112" - }, - "peerDependenciesMeta": { - "svelte": { - "optional": true - } - } - }, "node_modules/svelte-highlight": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/svelte-highlight/-/svelte-highlight-7.4.6.tgz", @@ -7419,18 +7425,18 @@ "dev": true }, "node_modules/tinypool": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.1.tgz", - "integrity": "sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==", + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz", + "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==", "dev": true, "engines": { "node": ">=14.0.0" } }, "node_modules/tinyspy": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.0.tgz", - "integrity": "sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", + "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", "dev": true, "engines": { "node": ">=14.0.0" @@ -7726,9 +7732,9 @@ } }, "node_modules/vite-node": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.2.0.tgz", - "integrity": "sha512-ETnQTHeAbbOxl7/pyBck9oAPZZZo+kYnFt1uQDD+hPReOc+wCjXw4r4jHriBRuVDB5isHmPXxrfc1yJnfBERqg==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.5.3.tgz", + "integrity": "sha512-axFo00qiCpU/JLd8N1gu9iEYL3xTbMbMrbe5nDp9GL0nb6gurIdZLkkFogZXWnE8Oyy5kfSLwNVIcVsnhE7lgQ==", "dev": true, "dependencies": { "cac": "^6.7.14", @@ -7763,18 +7769,17 @@ } }, "node_modules/vitest": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.2.0.tgz", - "integrity": "sha512-Ixs5m7BjqvLHXcibkzKRQUvD/XLw0E3rvqaCMlrm/0LMsA0309ZqYvTlPzkhh81VlEyVZXFlwWnkhb6/UMtcaQ==", + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.5.3.tgz", + "integrity": "sha512-2oM7nLXylw3mQlW6GXnRriw+7YvZFk/YNV8AxIC3Z3MfFbuziLGWP9GPxxu/7nRlXhqyxBikpamr+lEEj1sUEw==", "dev": true, "dependencies": { - "@vitest/expect": "1.2.0", - "@vitest/runner": "1.2.0", - "@vitest/snapshot": "1.2.0", - "@vitest/spy": "1.2.0", - "@vitest/utils": "1.2.0", - "acorn-walk": "^8.3.1", - "cac": "^6.7.14", + "@vitest/expect": "1.5.3", + "@vitest/runner": "1.5.3", + "@vitest/snapshot": "1.5.3", + "@vitest/spy": "1.5.3", + "@vitest/utils": "1.5.3", + "acorn-walk": "^8.3.2", "chai": "^4.3.10", "debug": "^4.3.4", "execa": "^8.0.1", @@ -7783,11 +7788,11 @@ "pathe": "^1.1.1", "picocolors": "^1.0.0", "std-env": "^3.5.0", - "strip-literal": "^1.3.0", + "strip-literal": "^2.0.0", "tinybench": "^2.5.1", - "tinypool": "^0.8.1", + "tinypool": "^0.8.3", "vite": "^5.0.0", - "vite-node": "1.2.0", + "vite-node": "1.5.3", "why-is-node-running": "^2.2.2" }, "bin": { @@ -7802,8 +7807,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "^1.0.0", - "@vitest/ui": "^1.0.0", + "@vitest/browser": "1.5.3", + "@vitest/ui": "1.5.3", "happy-dom": "*", "jsdom": "*" }, diff --git a/package.json b/package.json index caf8576..8db5217 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "tslib": "^2.5.3", "typescript": "^5.4.2", "vite": "^5.0.0", - "vitest": "^1.1.0" + "vitest": "^1.5.3" }, "type": "module", "exports": { diff --git a/src/templates/svelteKonvaComponentTests.hbs b/src/templates/svelteKonvaComponentTests.hbs index a4366c9..9295ec4 100644 --- a/src/templates/svelteKonvaComponentTests.hbs +++ b/src/templates/svelteKonvaComponentTests.hbs @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render({{ componentName }}, { context: createMockParentContext(Container.Layer), props: { - config: {{{ testConfig }}} + config: {{{ testConfig }}}, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.{{ componentName }} = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.{{ componentName }} = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.{{ componentName }} = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render({{ componentName }}, { - context: createMockParentContext(Container.Layer), - props: { - config: {{{ testConfig }}} - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/arc.test.ts b/src/tests/arc.test.ts index 70d1639..079f7e9 100644 --- a/src/tests/arc.test.ts +++ b/src/tests/arc.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Arc, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 } + config: { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Arc = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Arc = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Arc = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Arc, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/arrow.test.ts b/src/tests/arrow.test.ts index 4c78fa5..2e547b6 100644 --- a/src/tests/arrow.test.ts +++ b/src/tests/arrow.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Arrow, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } + config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Arrow = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Arrow = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Arrow = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Arrow, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/circle.test.ts b/src/tests/circle.test.ts index b9fc3b5..e849432 100644 --- a/src/tests/circle.test.ts +++ b/src/tests/circle.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Circle, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, radius: 100 } + config: { x: 0, radius: 100 }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Circle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Circle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Circle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Circle, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, radius: 100 } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/ellipse.test.ts b/src/tests/ellipse.test.ts index 211e5c9..617e224 100644 --- a/src/tests/ellipse.test.ts +++ b/src/tests/ellipse.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Ellipse, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, radiusX: 120, radiusY: 70 } + config: { x: 0, radiusX: 120, radiusY: 70 }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Ellipse = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Ellipse = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Ellipse = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Ellipse, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, radiusX: 120, radiusY: 70 } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/group.test.ts b/src/tests/group.test.ts index 2f598c3..603d7fd 100644 --- a/src/tests/group.test.ts +++ b/src/tests/group.test.ts @@ -33,8 +33,7 @@ test('passes the config prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Group = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(handle.getAttrs()).toStrictEqual(CONFIG); }); @@ -45,9 +44,8 @@ test('is correctly added to the parent Layer', () => { context: mockContext }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -63,9 +61,8 @@ test('is correctly added to the parent Group', () => { context: mockContext }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -81,9 +78,8 @@ test('is correctly added to the parent Label', () => { context: mockContext }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -95,12 +91,15 @@ test('is correctly added to the parent Label', () => { test('Can listen to Konva events', () => { const mockContext = createMockParentContext(Container.Layer); + const mockFn = vi.fn(); const rendered = render(Group, { - context: mockContext + context: mockContext, + props: { + onmousedown: mockFn + } }); - const component = rendered.component.$$; - const handle: Konva.Group = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -109,9 +108,6 @@ test('Can listen to Konva events', () => { handle.add(rectangle); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -126,8 +122,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Group = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -156,8 +151,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Group = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -182,7 +176,7 @@ test('sets the correct context', () => { const component = rendered.component.$$; const context = component.context; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(get(context.get(CONTAINER_COMPONENT_KEYS[Container.Group]))).toStrictEqual(handle); }); @@ -219,22 +213,9 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; - expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Group, { - context: createMockParentContext(Container.Layer) - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/image.test.ts b/src/tests/image.test.ts index 3cf2a34..5bc07c8 100644 --- a/src/tests/image.test.ts +++ b/src/tests/image.test.ts @@ -56,9 +56,8 @@ test('is correctly added to the parent Layer', async () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -81,9 +80,8 @@ test('is correctly added to the parent Group', async () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -106,9 +104,8 @@ test('is correctly added to the parent Label', async () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -121,26 +118,24 @@ test('is correctly added to the parent Label', async () => { test('Can listen to Konva events', async () => { const testImage = await loadImage(image); + const mockFn = vi.fn(); const rendered = render(KonvaImage, { context: createMockParentContext(Container.Layer), props: { config: { image: testImage - } + }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Image = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -161,8 +156,7 @@ test('Correctly updates bound config on dragend', async () => { } }); - const component = rendered.component.$$; - const handle: Konva.Image = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -195,8 +189,7 @@ test('Does not update config if instantiated with staticConfig prop', async () = } }); - const component = rendered.component.$$; - const handle: Konva.Image = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -254,29 +247,9 @@ test('Konva instance is correctly destroyed on component unmount', async () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; - expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', async () => { - const testImage = await loadImage(image); - - const rendered = render(KonvaImage, { - context: createMockParentContext(Container.Layer), - props: { - config: { - image: testImage - } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/label.test.ts b/src/tests/label.test.ts index 8810c1a..67a9530 100644 --- a/src/tests/label.test.ts +++ b/src/tests/label.test.ts @@ -41,9 +41,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -62,9 +61,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -83,9 +81,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -96,15 +93,16 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Label, { context: createMockParentContext(Container.Layer), props: { - config: {} + config: {}, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Label = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -113,9 +111,6 @@ test('Can listen to Konva events', () => { handle.add(rectangle); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -130,8 +125,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Label = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -160,8 +154,7 @@ test('Does not update config if instantiated with staticConfig prop', async () = } }); - const component = rendered.component.$$; - const handle: Konva.Label = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -189,7 +182,7 @@ test('sets the correct context', () => { const component = rendered.component.$$; const context = component.context; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(get(context.get(CONTAINER_COMPONENT_KEYS[Container.Label]))).toStrictEqual(handle); }); @@ -232,8 +225,7 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -243,14 +235,3 @@ test('Konva instance is correctly destroyed on component unmount', () => { expect(handle).toBeUndefined(); }); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Label, { - context: createMockParentContext(Container.Layer), - props: { - config: {} - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact -}); diff --git a/src/tests/layer.test.ts b/src/tests/layer.test.ts index 5edb560..fdb0a98 100644 --- a/src/tests/layer.test.ts +++ b/src/tests/layer.test.ts @@ -41,8 +41,7 @@ test('passes the config prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Layer = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(handle.getAttrs()).toStrictEqual(CONFIG); }); @@ -54,9 +53,8 @@ test('is correctly added to the parent stage', () => { context: mockContext }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Stage])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -68,12 +66,15 @@ test('is correctly added to the parent stage', () => { test('Can listen to Konva events', () => { const div = document.createElement('div'); + const mockFn = vi.fn(); const rendered = render(Layer, { - context: createMockParentContext(Container.Stage, div) + context: createMockParentContext(Container.Stage, div), + props: { + onmousedown: mockFn + } }); - const component = rendered.component.$$; - const handle: Konva.Layer = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; // As the layer only receives events if any of its children detects an event // we need to create a shape as child of the layer and start the event on that shape @@ -82,9 +83,6 @@ test('Can listen to Konva events', () => { const rectangle = new Konva.Rect({ x: 0, y: 0, width: 100, height: 100 }); handle.add(rectangle); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - const stage = handle.getStage(); stage.draw(); @@ -104,8 +102,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Layer = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const stage = handle.getStage()!; const rectangle = new Konva.Rect({ x: 0, y: 0, width: 100, height: 100, fill: 'red' }); @@ -135,8 +132,7 @@ test('Does not update config if instantiated with staticConfig prop', async () = } }); - const component = rendered.component.$$; - const handle: Konva.Layer = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const stage = handle.getStage()!; const rectangle = new Konva.Rect({ x: 0, y: 0, width: 100, height: 100, fill: 'red' }); @@ -162,7 +158,7 @@ test('sets the correct context', () => { const component = rendered.component.$$; const context = component.context; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(get(context.get(CONTAINER_COMPONENT_KEYS[Container.Layer]))).toStrictEqual(handle); }); @@ -201,25 +197,9 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; - expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const div = document.createElement('div'); - const mockContext = createMockParentContext(Container.Stage, div); - - const rendered = render(Layer, { - context: mockContext - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/line.test.ts b/src/tests/line.test.ts index 6bcbdae..b6aa4f3 100644 --- a/src/tests/line.test.ts +++ b/src/tests/line.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Line, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } + config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Line = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Line = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Line = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Line, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/path.test.ts b/src/tests/path.test.ts index 67b929d..5f0094e 100644 --- a/src/tests/path.test.ts +++ b/src/tests/path.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Path, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } + config: { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Path = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Path = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Path = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Path, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/rect.test.ts b/src/tests/rect.test.ts index 62cb18b..f0c0aa9 100644 --- a/src/tests/rect.test.ts +++ b/src/tests/rect.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Rect, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, width: 100, height: 100 } + config: { x: 0, width: 100, height: 100 }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Rect = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Rect = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Rect = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Rect, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, width: 100, height: 100 } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/regularpolygon.test.ts b/src/tests/regularpolygon.test.ts index f65a1d2..cdce604 100644 --- a/src/tests/regularpolygon.test.ts +++ b/src/tests/regularpolygon.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(RegularPolygon, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, sides: 7, radius: 80 } + config: { x: 0, sides: 7, radius: 80 }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.RegularPolygon = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.RegularPolygon = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.RegularPolygon = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(RegularPolygon, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, sides: 7, radius: 80 } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/ring.test.ts b/src/tests/ring.test.ts index fd608f1..04541ab 100644 --- a/src/tests/ring.test.ts +++ b/src/tests/ring.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Ring, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, innerRadius: 20, outerRadius: 100 } + config: { x: 0, innerRadius: 20, outerRadius: 100 }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Ring = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Ring = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Ring = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Ring, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100 } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/shape.test.ts b/src/tests/shape.test.ts index b87d804..e962081 100644 --- a/src/tests/shape.test.ts +++ b/src/tests/shape.test.ts @@ -65,9 +65,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -94,9 +93,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -123,9 +121,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -136,6 +133,7 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Shape, { context: createMockParentContext(Container.Layer), props: { @@ -147,21 +145,18 @@ test('Can listen to Konva events', () => { context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); context.fillStrokeShape(shape); } - } + }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Line = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -186,8 +181,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Line = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -225,7 +219,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { }); const component = rendered.component.$$; - const handle: Konva.Line = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -291,33 +285,9 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; - expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Shape, { - context: createMockParentContext(Container.Layer), - props: { - config: { - width: 100, - height: 100, - sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { - context.beginPath(); - context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); - context.fillStrokeShape(shape); - } - } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/sprite.test.ts b/src/tests/sprite.test.ts index 6cc8b39..82450a2 100644 --- a/src/tests/sprite.test.ts +++ b/src/tests/sprite.test.ts @@ -141,6 +141,7 @@ test('is correctly added to the parent Label', async () => { test('Can listen to Konva events', async () => { const spriteImage = await loadImage(sprite); + const mockFn = vi.fn(); const rendered = render(Sprite, { context: createMockParentContext(Container.Layer), props: { @@ -150,7 +151,8 @@ test('Can listen to Konva events', async () => { animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, frameRate: 7, frameIndex: 0 - } + }, + onmousedown: mockFn } }); @@ -162,9 +164,6 @@ test('Can listen to Konva events', async () => { stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 20, y: 20 }); expect(mockFn).toHaveBeenCalledTimes(1); diff --git a/src/tests/stage.test.ts b/src/tests/stage.test.ts index e9487ea..a87eb8f 100644 --- a/src/tests/stage.test.ts +++ b/src/tests/stage.test.ts @@ -53,8 +53,7 @@ test('creates a konva stage instance and passes config prop', () => { id: 'container' }); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle(); expect(handle).toBeTruthy(); @@ -64,17 +63,16 @@ test('creates a konva stage instance and passes config prop', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); + const rendered = render(Stage, { - config: { width: 1000, height: 1000 } + config: { width: 1000, height: 1000 }, + onmousedown: mockFn }); - const component = rendered.component.$$; - const handle: MockStage = component.ctx[component.props['handle'] as number]; - - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); + const handle = rendered.component.handle(); - handle.simulateMouseDown({ x: 50, y: 50 }); + (handle as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); }); @@ -123,20 +121,18 @@ test('sets the correct context', () => { }); const component = rendered.component.$$; + const context = component.context; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle(); expect(get(context.get(CONTAINER_COMPONENT_KEYS[Container.Stage]))).toStrictEqual(handle); }); test('nulls unused context', () => { - const rendered = render(Stage, { - config: { width: 1000, height: 1000 } + render(Stage, { + props: { config: { width: 1000, height: 1000 } } }); - const component = rendered.component.$$; - const context = component.context; - const otherKeys = CONTAINER_COMPONENT_KEYS.slice(); otherKeys.splice(Container.Stage, 1); @@ -157,17 +153,5 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; - expect(Konva.stages.length).toBe(previousStageCount); - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', async () => { - const rendered = render(Stage, { - config: { width: 1000, height: 1000 } - }); - - rendered.component.$set({ _handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/star.test.ts b/src/tests/star.test.ts index d4cafbe..0f6f5fb 100644 --- a/src/tests/star.test.ts +++ b/src/tests/star.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Star, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } + config: { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Star = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Star = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Star = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Star, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/tag.test.ts b/src/tests/tag.test.ts index d935799..045002b 100644 --- a/src/tests/tag.test.ts +++ b/src/tests/tag.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Tag, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } + config: { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Tag = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Tag = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Tag = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Tag, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/text.test.ts b/src/tests/text.test.ts index 4ea8f73..d7cec3c 100644 --- a/src/tests/text.test.ts +++ b/src/tests/text.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Text, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, fontSize: 100, text: 'some text', fill: 'black' } + config: { x: 0, fontSize: 100, text: 'some text', fill: 'black' }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Text = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Text = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Text = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Text, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, fontSize: 100, text: 'some text', fill: 'black' } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/textpath.test.ts b/src/tests/textpath.test.ts index 545479c..98ee92d 100644 --- a/src/tests/textpath.test.ts +++ b/src/tests/textpath.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(TextPath, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } + config: { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.TextPath = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.TextPath = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.TextPath = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(TextPath, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); diff --git a/src/tests/wedge.test.ts b/src/tests/wedge.test.ts index 2c82339..d145e95 100644 --- a/src/tests/wedge.test.ts +++ b/src/tests/wedge.test.ts @@ -44,9 +44,8 @@ test('is correctly added to the parent Layer', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -65,9 +64,8 @@ test('is correctly added to the parent Group', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -86,9 +84,8 @@ test('is correctly added to the parent Label', () => { } }); - const component = rendered.component.$$; const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); @@ -99,24 +96,22 @@ test('is correctly added to the parent Label', () => { }); test('Can listen to Konva events', () => { + const mockFn = vi.fn(); const rendered = render(Wedge, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, radius: 100, angle: 300 } + config: { x: 0, radius: 100, angle: 300 }, + onmousedown: mockFn } }); - const component = rendered.component.$$; - const handle: Konva.Wedge = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); stage.add(handle.getLayer()!); - const mockFn = vi.fn(); - rendered.component.$on('mousedown', mockFn); - (stage as MockStage).simulateMouseDown({ x: 50, y: 50 }); expect(mockFn).toHaveBeenCalledTimes(1); @@ -132,8 +127,7 @@ test('Correctly updates bound config on dragend', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Wedge = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -161,8 +155,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { } }); - const component = rendered.component.$$; - const handle: Konva.Wedge = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; const div = document.createElement('div'); const stage = new Konva.Stage({ container: div, width: 1000, height: 1000 }); @@ -212,25 +205,11 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const component = rendered.component.$$; - const handle = component.ctx[component.props['handle'] as number]; + const handle = rendered.component.handle; expect(parent.children).toBeTruthy(); if (parent.children) { expect(parent.children.length).toBe(0); } - - expect(handle).toBeUndefined(); -}); - -test('Overwriting the handle of the component from outside should have no effect', () => { - const rendered = render(Wedge, { - context: createMockParentContext(Container.Layer), - props: { - config: { x: 0, radius: 100, angle: 300 } - } - }); - - rendered.component.$set({ handle: undefined }); // Overwrite handle from outside, should not throw as internal handle is still intact }); From d05fee0568c44556909a74a020f4d65c1dfef4cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 3 May 2024 19:13:09 +0200 Subject: [PATCH 24/56] Corrections on examples for new handle location and runes --- src/routes/ResponsiveStage.svelte | 6 +-- src/routes/examples/connectFour/Game.svelte | 6 +-- src/routes/examples/connectFour/Token.svelte | 15 ++++---- src/routes/examples/drawing/Drawing.svelte | 2 +- .../examples/transform/Transform.svelte | 38 ++++++++++--------- 5 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/routes/ResponsiveStage.svelte b/src/routes/ResponsiveStage.svelte index 912f8a0..99d9557 100644 --- a/src/routes/ResponsiveStage.svelte +++ b/src/routes/ResponsiveStage.svelte @@ -6,12 +6,12 @@ type Props = { children: Snippet; - handle?: null | Konva.Stage; + stage?: Stage | undefined; } & KonvaEventHooks; let { children, - handle = $bindable(), + stage = $bindable(), onpointerdblclick, onpointerdown, onpointerup, @@ -54,7 +54,7 @@ ) { + function handleMoveEnd(e: TokenPos) { // Check winning condition - const won = hasWon(e.detail); + const won = hasWon(e); if (won) { handleWin(won); return; @@ -262,7 +262,7 @@ {#key reset} {#each tokens as token} - + {/each} {/key} diff --git a/src/routes/examples/connectFour/Token.svelte b/src/routes/examples/connectFour/Token.svelte index a957a8a..3c3fe10 100644 --- a/src/routes/examples/connectFour/Token.svelte +++ b/src/routes/examples/connectFour/Token.svelte @@ -11,18 +11,17 @@ GAME_GRID_ROW_POSITIONS, TOKEN_RADIUS } from './constants'; - import { Player } from './types'; + import { Player, type TokenPos } from './types'; import { gameScale, gameState } from './store'; - import { createEventDispatcher } from 'svelte'; type Props = { player: Player; + ondropped: (e: TokenPos) => void; }; - let { player }: Props = $props(); + let { player, ondropped }: Props = $props(); - let token = $state(); - let dispatch = createEventDispatcher(); + let token: Circle | undefined; const TOKEN_RED_INITIAL_POS = { x: 80, y: 80 }; const TOKEN_BLUE_INITIAL_POS = { x: GAME_BASE_SIZE - 80, y: 80 }; @@ -142,7 +141,7 @@ // Create a tween to animate the drop const tween = new Konva.Tween({ - node: token!, + node: token!.handle, duration: 1, y: GAME_GRID_ROW_POSITIONS[rowPos!], easing: Konva.Easings.BounceEaseOut, @@ -155,8 +154,8 @@ tween.play(); // emit event to parent to signal the end of the move - dispatch('dropped', { colPos, rowPos: rowPos! }); + ondropped({ colPos, rowPos: rowPos! }); } - + diff --git a/src/routes/examples/drawing/Drawing.svelte b/src/routes/examples/drawing/Drawing.svelte index d4698ef..0243406 100644 --- a/src/routes/examples/drawing/Drawing.svelte +++ b/src/routes/examples/drawing/Drawing.svelte @@ -115,7 +115,7 @@ onpointermove={draw} onpointerup={stopDraw} onmouseout={drawMouseOut} - bind:handle={stage} + bind:stage > {#each strokes as stroke} diff --git a/src/routes/examples/transform/Transform.svelte b/src/routes/examples/transform/Transform.svelte index 428da8e..bea1c38 100644 --- a/src/routes/examples/transform/Transform.svelte +++ b/src/routes/examples/transform/Transform.svelte @@ -2,7 +2,6 @@ import Konva from 'konva'; import type { KonvaMouseEvent, KonvaPointerEvent } from 'svelte-konva'; import Stage from '../../ResponsiveStage.svelte'; - import type { KonvaEventObject } from 'konva/lib/Node'; import { getRealPointerPos } from '../../util'; // svelte-konva components @@ -13,10 +12,10 @@ import Transformer from 'svelte-konva/Transformer.svelte'; import Rect from 'svelte-konva/Rect.svelte'; - let stage = $state(); - let layer = $state(); - let transformer = $state(); - let selectionRectangle = $state(); + let stage: Stage | undefined; + let layer: Layer | undefined; + let transformer: Transformer | undefined; + let selectionRectangle: Rect | undefined; const SELECTION_RECTANGLE_NAME = 'selection-rectangle'; @@ -60,7 +59,7 @@ let selectionActive = false; // If the transformer is active eg. something is selected function selectStart(e: KonvaPointerEvent) { - if (!transformer || !stage) return; + if (!transformer || !stage?.handle()) return; // Check if event target is stage (eg. user clicked on empty part of the stage and not any shape) if (e.target.getType() !== 'Stage') { @@ -69,12 +68,12 @@ // If there is already a selection active, cancel it if (selectionActive) { - transformer.nodes([]); + transformer.handle.nodes([]); selectionActive = false; return; } - const pointerPos = getRealPointerPos(stage.getPointerPosition()!, stage); + const pointerPos = getRealPointerPos(stage.handle().getPointerPosition()!, stage.handle()); selectionRectangleConfig.x = pointerPos.x; selectionRectangleConfig.y = pointerPos.y; @@ -86,13 +85,13 @@ } function selectDrag() { - if (!stage) return; + if (!stage?.handle()) return; if (!selectionRectangleConfig.visible) { // Currently no selection is active (eg. user is just moving the cursor around) return; } - const pointerPos = getRealPointerPos(stage.getPointerPosition()!, stage); + const pointerPos = getRealPointerPos(stage?.handle().getPointerPosition()!, stage?.handle()); // Set new x coordinate and width of selection rectangle selectionRectangleConfig.x = Math.min(pointerPos.x, initialSelectionCoordinates.x); @@ -110,16 +109,19 @@ return; } - if (layer.children) { - const selectedEntities = layer!.children.filter( + if (layer.handle.children) { + const selectedEntities = layer.handle.children.filter( (child) => child.name() !== SELECTION_RECTANGLE_NAME && - Konva.Util.haveIntersection(selectionRectangle!.getClientRect(), child.getClientRect()) + Konva.Util.haveIntersection( + selectionRectangle!.handle.getClientRect(), + child.getClientRect() + ) ); if (selectedEntities.length !== 0) { // Add all selected shapes etc. to the transformer - transformer.nodes(selectedEntities); + transformer.handle.nodes(selectedEntities); selectionActive = true; } @@ -146,9 +148,9 @@ onpointermove={selectDrag} onpointerup={selectEnd} onmouseout={selectMouseOut} - bind:handle={stage} + bind:stage > - + {#each configs as _, idx} @@ -162,8 +164,8 @@ /> - + - + From 46acec934616469e989129e360a7cc7b45bc53da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 3 May 2024 19:25:24 +0200 Subject: [PATCH 25/56] Update svelte due to bug that broke svelte-konva context (sveltejs/svelte#11438) --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 503582e..f4bf7e3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", - "svelte": "5.0.0-next.121", + "svelte": "5.0.0-next.123", "svelte-check": "^3.7.0", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", @@ -7091,9 +7091,9 @@ } }, "node_modules/svelte": { - "version": "5.0.0-next.121", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.121.tgz", - "integrity": "sha512-dWxr42t8wv6iUmgKrYDG9RwQd2lf3vF2+ACYT7ziDnLeYItPM4sABmM8ptMaYL8czwtqpNzfCsxQR7ShN5PS9A==", + "version": "5.0.0-next.123", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.123.tgz", + "integrity": "sha512-EKdXcqT795J34V8TyyUO5ExI0amjeKBECA2t7Py8QeDTMgS9//pQElD0jKsCT/sfmKV4HEoOwf7sqPYINKEfUQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", diff --git a/package.json b/package.json index 8db5217..f8fc8a6 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", - "svelte": "5.0.0-next.121", + "svelte": "5.0.0-next.123", "svelte-check": "^3.7.0", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", From 717cb8f20f97f6058fe3c3bfd7974fc17a3b1550 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Sun, 26 May 2024 09:47:10 +0200 Subject: [PATCH 26/56] Dep update, fix free drawing example --- package-lock.json | 465 +++++++++++---------- package.json | 12 +- src/routes/ResponsiveStage.svelte | 1 - src/routes/examples/drawing/Drawing.svelte | 24 +- 4 files changed, 277 insertions(+), 225 deletions(-) diff --git a/package-lock.json b/package-lock.json index f4bf7e3..8b8a978 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "MIT", "devDependencies": { "@sveltejs/adapter-static": "^3.0.1", - "@sveltejs/kit": "^2.5.7", + "@sveltejs/kit": "^2.5.10", "@sveltejs/package": "^2.3.1", "@tailwindcss/typography": "^0.5.7", "@testing-library/svelte": "^5.1.0", @@ -23,21 +23,21 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.38.0", "jsdom": "^24.0.0", - "konva": "^9.2.0", + "konva": "^9.3.11", "lodash.clonedeep": "^4.5.0", "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", - "svelte": "5.0.0-next.123", - "svelte-check": "^3.7.0", + "svelte": "5.0.0-next.141", + "svelte-check": "^3.7.1", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", "svelte-preprocess": "^5.0.4", "tailwindcss": "^3.1.8", "tslib": "^2.5.3", "typescript": "^5.4.2", - "vite": "^5.0.0", - "vitest": "^1.5.3" + "vite": "^5.2.11", + "vitest": "^1.6.0" }, "peerDependencies": { "konva": "8 - 9", @@ -269,9 +269,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.10.tgz", - "integrity": "sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", "cpu": [ "ppc64" ], @@ -285,9 +285,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.10.tgz", - "integrity": "sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", "cpu": [ "arm" ], @@ -301,9 +301,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.10.tgz", - "integrity": "sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", "cpu": [ "arm64" ], @@ -317,9 +317,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.10.tgz", - "integrity": "sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", "cpu": [ "x64" ], @@ -333,9 +333,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.10.tgz", - "integrity": "sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", "cpu": [ "arm64" ], @@ -349,9 +349,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.10.tgz", - "integrity": "sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", "cpu": [ "x64" ], @@ -365,9 +365,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.10.tgz", - "integrity": "sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", "cpu": [ "arm64" ], @@ -381,9 +381,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.10.tgz", - "integrity": "sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", "cpu": [ "x64" ], @@ -397,9 +397,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.10.tgz", - "integrity": "sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", "cpu": [ "arm" ], @@ -413,9 +413,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.10.tgz", - "integrity": "sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", "cpu": [ "arm64" ], @@ -429,9 +429,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.10.tgz", - "integrity": "sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", "cpu": [ "ia32" ], @@ -445,9 +445,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.10.tgz", - "integrity": "sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", "cpu": [ "loong64" ], @@ -461,9 +461,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.10.tgz", - "integrity": "sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", "cpu": [ "mips64el" ], @@ -477,9 +477,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.10.tgz", - "integrity": "sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", "cpu": [ "ppc64" ], @@ -493,9 +493,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.10.tgz", - "integrity": "sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", "cpu": [ "riscv64" ], @@ -509,9 +509,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.10.tgz", - "integrity": "sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", "cpu": [ "s390x" ], @@ -525,9 +525,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.10.tgz", - "integrity": "sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", "cpu": [ "x64" ], @@ -541,9 +541,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.10.tgz", - "integrity": "sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", "cpu": [ "x64" ], @@ -557,9 +557,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.10.tgz", - "integrity": "sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", "cpu": [ "x64" ], @@ -573,9 +573,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.10.tgz", - "integrity": "sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", "cpu": [ "x64" ], @@ -589,9 +589,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.10.tgz", - "integrity": "sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", "cpu": [ "arm64" ], @@ -605,9 +605,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.10.tgz", - "integrity": "sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", "cpu": [ "ia32" ], @@ -621,9 +621,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.10.tgz", - "integrity": "sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", + "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", "cpu": [ "x64" ], @@ -859,9 +859,9 @@ "dev": true }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.9.1.tgz", - "integrity": "sha512-6vMdBZqtq1dVQ4CWdhFwhKZL6E4L1dV6jUjuBvsavvNJSppzi6dLBbuV+3+IyUREaj9ZFvQefnQm28v4OCXlig==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", + "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==", "cpu": [ "arm" ], @@ -872,9 +872,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.9.1.tgz", - "integrity": "sha512-Jto9Fl3YQ9OLsTDWtLFPtaIMSL2kwGyGoVCmPC8Gxvym9TCZm4Sie+cVeblPO66YZsYH8MhBKDMGZ2NDxuk/XQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz", + "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==", "cpu": [ "arm64" ], @@ -885,9 +885,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.9.1.tgz", - "integrity": "sha512-LtYcLNM+bhsaKAIGwVkh5IOWhaZhjTfNOkGzGqdHvhiCUVuJDalvDxEdSnhFzAn+g23wgsycmZk1vbnaibZwwA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz", + "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==", "cpu": [ "arm64" ], @@ -898,9 +898,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.9.1.tgz", - "integrity": "sha512-KyP/byeXu9V+etKO6Lw3E4tW4QdcnzDG/ake031mg42lob5tN+5qfr+lkcT/SGZaH2PdW4Z1NX9GHEkZ8xV7og==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz", + "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==", "cpu": [ "x64" ], @@ -911,9 +911,22 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.9.1.tgz", - "integrity": "sha512-Yqz/Doumf3QTKplwGNrCHe/B2p9xqDghBZSlAY0/hU6ikuDVQuOUIpDP/YcmoT+447tsZTmirmjgG3znvSCR0Q==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz", + "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz", + "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==", "cpu": [ "arm" ], @@ -924,9 +937,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.9.1.tgz", - "integrity": "sha512-u3XkZVvxcvlAOlQJ3UsD1rFvLWqu4Ef/Ggl40WAVCuogf4S1nJPHh5RTgqYFpCOvuGJ7H5yGHabjFKEZGExk5Q==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz", + "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==", "cpu": [ "arm64" ], @@ -937,9 +950,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.9.1.tgz", - "integrity": "sha512-0XSYN/rfWShW+i+qjZ0phc6vZ7UWI8XWNz4E/l+6edFt+FxoEghrJHjX1EY/kcUGCnZzYYRCl31SNdfOi450Aw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz", + "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==", "cpu": [ "arm64" ], @@ -949,10 +962,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz", + "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.9.1.tgz", - "integrity": "sha512-LmYIO65oZVfFt9t6cpYkbC4d5lKHLYv5B4CSHRpnANq0VZUQXGcCPXHzbCXCz4RQnx7jvlYB1ISVNCE/omz5cw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz", + "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==", "cpu": [ "riscv64" ], @@ -962,10 +988,23 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz", + "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.9.1.tgz", - "integrity": "sha512-kr8rEPQ6ns/Lmr/hiw8sEVj9aa07gh1/tQF2Y5HrNCCEPiCBGnBUt9tVusrcBBiJfIt1yNaXN6r1CCmpbFEDpg==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", "cpu": [ "x64" ], @@ -976,9 +1015,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.9.1.tgz", - "integrity": "sha512-t4QSR7gN+OEZLG0MiCgPqMWZGwmeHhsM4AkegJ0Kiy6TnJ9vZ8dEIwHw1LcZKhbHxTY32hp9eVCMdR3/I8MGRw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz", + "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==", "cpu": [ "x64" ], @@ -989,9 +1028,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.9.1.tgz", - "integrity": "sha512-7XI4ZCBN34cb+BH557FJPmh0kmNz2c25SCQeT9OiFWEgf8+dL6ZwJ8f9RnUIit+j01u07Yvrsuu1rZGxJCc51g==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz", + "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==", "cpu": [ "arm64" ], @@ -1002,9 +1041,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.9.1.tgz", - "integrity": "sha512-yE5c2j1lSWOH5jp+Q0qNL3Mdhr8WuqCNVjc6BxbVfS5cAS6zRmdiw7ktb8GNpDCEUJphILY6KACoFoRtKoqNQg==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz", + "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==", "cpu": [ "ia32" ], @@ -1015,9 +1054,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.9.1.tgz", - "integrity": "sha512-PyJsSsafjmIhVgaI1Zdj7m8BB8mMckFah/xbpplObyHfiXzKcI5UOUXRyOdHW7nz4DpMCuzLnF7v5IWHenCwYA==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz", + "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==", "cpu": [ "x64" ], @@ -1043,9 +1082,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.7.tgz", - "integrity": "sha512-6uedTzrb7nQrw6HALxnPrPaXdIN2jJJTzTIl96Z3P5NiG+OAfpdPbrWrvkJ3GN4CfWqrmU4dJqwMMRMTD/C7ow==", + "version": "2.5.10", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.10.tgz", + "integrity": "sha512-OqoyTmFG2cYmCFAdBfW+Qxbg8m23H4dv6KqwEt7ofr/ROcfcIl3Z/VT56L22H9f0uNZyr+9Bs1eh2gedOCK9kA==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -1053,7 +1092,7 @@ "cookie": "^0.6.0", "devalue": "^5.0.0", "esm-env": "^1.0.0", - "import-meta-resolve": "^4.0.0", + "import-meta-resolve": "^4.1.0", "kleur": "^4.1.5", "magic-string": "^0.30.5", "mrmime": "^2.0.0", @@ -1525,13 +1564,13 @@ "dev": true }, "node_modules/@vitest/expect": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.5.3.tgz", - "integrity": "sha512-y+waPz31pOFr3rD7vWTbwiLe5+MgsMm40jTZbQE8p8/qXyBX3CQsIXRx9XK12IbY7q/t5a5aM/ckt33b4PxK2g==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz", + "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==", "dev": true, "dependencies": { - "@vitest/spy": "1.5.3", - "@vitest/utils": "1.5.3", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", "chai": "^4.3.10" }, "funding": { @@ -1539,12 +1578,12 @@ } }, "node_modules/@vitest/runner": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.5.3.tgz", - "integrity": "sha512-7PlfuReN8692IKQIdCxwir1AOaP5THfNkp0Uc4BKr2na+9lALNit7ub9l3/R7MP8aV61+mHKRGiqEKRIwu6iiQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz", + "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==", "dev": true, "dependencies": { - "@vitest/utils": "1.5.3", + "@vitest/utils": "1.6.0", "p-limit": "^5.0.0", "pathe": "^1.1.1" }, @@ -1580,9 +1619,9 @@ } }, "node_modules/@vitest/snapshot": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.5.3.tgz", - "integrity": "sha512-K3mvIsjyKYBhNIDujMD2gfQEzddLe51nNOAf45yKRt/QFJcUIeTQd2trRvv6M6oCBHNVnZwFWbQ4yj96ibiDsA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz", + "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==", "dev": true, "dependencies": { "magic-string": "^0.30.5", @@ -1626,9 +1665,9 @@ "dev": true }, "node_modules/@vitest/spy": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.5.3.tgz", - "integrity": "sha512-Llj7Jgs6lbnL55WoshJUUacdJfjU2honvGcAJBxhra5TPEzTJH8ZuhI3p/JwqqfnTr4PmP7nDmOXP53MS7GJlg==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz", + "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==", "dev": true, "dependencies": { "tinyspy": "^2.2.0" @@ -1638,9 +1677,9 @@ } }, "node_modules/@vitest/utils": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.5.3.tgz", - "integrity": "sha512-rE9DTN1BRhzkzqNQO+kw8ZgfeEBCLXiHJwetk668shmNBpSagQxneT5eSqEBLP+cqSiAeecvQmbpFfdMyLcIQA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz", + "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==", "dev": true, "dependencies": { "diff-sequences": "^29.6.3", @@ -2852,9 +2891,9 @@ "dev": true }, "node_modules/esbuild": { - "version": "0.19.10", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.10.tgz", - "integrity": "sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==", + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", + "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", "dev": true, "hasInstallScript": true, "bin": { @@ -2864,29 +2903,29 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.19.10", - "@esbuild/android-arm": "0.19.10", - "@esbuild/android-arm64": "0.19.10", - "@esbuild/android-x64": "0.19.10", - "@esbuild/darwin-arm64": "0.19.10", - "@esbuild/darwin-x64": "0.19.10", - "@esbuild/freebsd-arm64": "0.19.10", - "@esbuild/freebsd-x64": "0.19.10", - "@esbuild/linux-arm": "0.19.10", - "@esbuild/linux-arm64": "0.19.10", - "@esbuild/linux-ia32": "0.19.10", - "@esbuild/linux-loong64": "0.19.10", - "@esbuild/linux-mips64el": "0.19.10", - "@esbuild/linux-ppc64": "0.19.10", - "@esbuild/linux-riscv64": "0.19.10", - "@esbuild/linux-s390x": "0.19.10", - "@esbuild/linux-x64": "0.19.10", - "@esbuild/netbsd-x64": "0.19.10", - "@esbuild/openbsd-x64": "0.19.10", - "@esbuild/sunos-x64": "0.19.10", - "@esbuild/win32-arm64": "0.19.10", - "@esbuild/win32-ia32": "0.19.10", - "@esbuild/win32-x64": "0.19.10" + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" } }, "node_modules/escape-string-regexp": { @@ -4028,9 +4067,9 @@ } }, "node_modules/import-meta-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", - "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", "dev": true, "funding": { "type": "github", @@ -4819,9 +4858,9 @@ "dev": true }, "node_modules/konva": { - "version": "9.3.3", - "resolved": "https://registry.npmjs.org/konva/-/konva-9.3.3.tgz", - "integrity": "sha512-cg/AHxnfawZ1rKxygCnzx0TZY7hQiQiAKgAHPinEwMn49MVrBkeKLj2d0EaleoFG/0y0XhEKTD0dFZiPPdWlCQ==", + "version": "9.3.11", + "resolved": "https://registry.npmjs.org/konva/-/konva-9.3.11.tgz", + "integrity": "sha512-ZkFF4CXKZCDd2+6sBPA0y3hQ+X4uTqIS6JxTl3BEOFJzKr1tId+rxxJgtsk1FQIH3auuvnMj/rkbatUcf9C2Wg==", "dev": true, "funding": [ { @@ -6527,10 +6566,13 @@ } }, "node_modules/rollup": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.9.1.tgz", - "integrity": "sha512-pgPO9DWzLoW/vIhlSoDByCzcpX92bKEorbgXuZrqxByte3JFk2xSW2JEeAcyLc9Ru9pqcNNW+Ob7ntsk2oT/Xw==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz", + "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==", "dev": true, + "dependencies": { + "@types/estree": "1.0.5" + }, "bin": { "rollup": "dist/bin/rollup" }, @@ -6539,19 +6581,22 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.9.1", - "@rollup/rollup-android-arm64": "4.9.1", - "@rollup/rollup-darwin-arm64": "4.9.1", - "@rollup/rollup-darwin-x64": "4.9.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.9.1", - "@rollup/rollup-linux-arm64-gnu": "4.9.1", - "@rollup/rollup-linux-arm64-musl": "4.9.1", - "@rollup/rollup-linux-riscv64-gnu": "4.9.1", - "@rollup/rollup-linux-x64-gnu": "4.9.1", - "@rollup/rollup-linux-x64-musl": "4.9.1", - "@rollup/rollup-win32-arm64-msvc": "4.9.1", - "@rollup/rollup-win32-ia32-msvc": "4.9.1", - "@rollup/rollup-win32-x64-msvc": "4.9.1", + "@rollup/rollup-android-arm-eabi": "4.18.0", + "@rollup/rollup-android-arm64": "4.18.0", + "@rollup/rollup-darwin-arm64": "4.18.0", + "@rollup/rollup-darwin-x64": "4.18.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.0", + "@rollup/rollup-linux-arm-musleabihf": "4.18.0", + "@rollup/rollup-linux-arm64-gnu": "4.18.0", + "@rollup/rollup-linux-arm64-musl": "4.18.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0", + "@rollup/rollup-linux-riscv64-gnu": "4.18.0", + "@rollup/rollup-linux-s390x-gnu": "4.18.0", + "@rollup/rollup-linux-x64-gnu": "4.18.0", + "@rollup/rollup-linux-x64-musl": "4.18.0", + "@rollup/rollup-win32-arm64-msvc": "4.18.0", + "@rollup/rollup-win32-ia32-msvc": "4.18.0", + "@rollup/rollup-win32-x64-msvc": "4.18.0", "fsevents": "~2.3.2" } }, @@ -7091,9 +7136,9 @@ } }, "node_modules/svelte": { - "version": "5.0.0-next.123", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.123.tgz", - "integrity": "sha512-EKdXcqT795J34V8TyyUO5ExI0amjeKBECA2t7Py8QeDTMgS9//pQElD0jKsCT/sfmKV4HEoOwf7sqPYINKEfUQ==", + "version": "5.0.0-next.141", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.141.tgz", + "integrity": "sha512-zT74TUo0vOOrbxRfdlWXu+ac4O9lqPFG0YoZB3uOfrOewT1GKxKm0qwG/jo9bGvgZ++TSHjR7AtV091LY2FhBA==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", @@ -7115,9 +7160,9 @@ } }, "node_modules/svelte-check": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.7.0.tgz", - "integrity": "sha512-Va6sGL4Vy4znn0K+vaatk98zoBvG2aDee4y3r5X4S80z8DXfbACHvdLlyXa4C4c5tQzK9H0Uq2pbd20wH3ucjQ==", + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/svelte-check/-/svelte-check-3.7.1.tgz", + "integrity": "sha512-U4uJoLCzmz2o2U33c7mPDJNhRYX/DNFV11XTUDlFxaKLsO7P+40gvJHMPpoRfa24jqZfST4/G9fGNcUGMO8NAQ==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.17", @@ -7677,14 +7722,14 @@ } }, "node_modules/vite": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.4.tgz", - "integrity": "sha512-n+MPqzq+d9nMVTKyewqw6kSt+R3CkvF9QAKY8obiQn8g1fwTscKxyfaYnC632HtBXAQGc1Yjomphwn1dtwGAHg==", + "version": "5.2.11", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", + "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", "dev": true, "dependencies": { - "esbuild": "^0.19.3", - "postcss": "^8.4.35", - "rollup": "^4.2.0" + "esbuild": "^0.20.1", + "postcss": "^8.4.38", + "rollup": "^4.13.0" }, "bin": { "vite": "bin/vite.js" @@ -7732,9 +7777,9 @@ } }, "node_modules/vite-node": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.5.3.tgz", - "integrity": "sha512-axFo00qiCpU/JLd8N1gu9iEYL3xTbMbMrbe5nDp9GL0nb6gurIdZLkkFogZXWnE8Oyy5kfSLwNVIcVsnhE7lgQ==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz", + "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==", "dev": true, "dependencies": { "cac": "^6.7.14", @@ -7769,16 +7814,16 @@ } }, "node_modules/vitest": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.5.3.tgz", - "integrity": "sha512-2oM7nLXylw3mQlW6GXnRriw+7YvZFk/YNV8AxIC3Z3MfFbuziLGWP9GPxxu/7nRlXhqyxBikpamr+lEEj1sUEw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz", + "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==", "dev": true, "dependencies": { - "@vitest/expect": "1.5.3", - "@vitest/runner": "1.5.3", - "@vitest/snapshot": "1.5.3", - "@vitest/spy": "1.5.3", - "@vitest/utils": "1.5.3", + "@vitest/expect": "1.6.0", + "@vitest/runner": "1.6.0", + "@vitest/snapshot": "1.6.0", + "@vitest/spy": "1.6.0", + "@vitest/utils": "1.6.0", "acorn-walk": "^8.3.2", "chai": "^4.3.10", "debug": "^4.3.4", @@ -7792,7 +7837,7 @@ "tinybench": "^2.5.1", "tinypool": "^0.8.3", "vite": "^5.0.0", - "vite-node": "1.5.3", + "vite-node": "1.6.0", "why-is-node-running": "^2.2.2" }, "bin": { @@ -7807,8 +7852,8 @@ "peerDependencies": { "@edge-runtime/vm": "*", "@types/node": "^18.0.0 || >=20.0.0", - "@vitest/browser": "1.5.3", - "@vitest/ui": "1.5.3", + "@vitest/browser": "1.6.0", + "@vitest/ui": "1.6.0", "happy-dom": "*", "jsdom": "*" }, diff --git a/package.json b/package.json index f8fc8a6..0dfae0a 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ }, "devDependencies": { "@sveltejs/adapter-static": "^3.0.1", - "@sveltejs/kit": "^2.5.7", + "@sveltejs/kit": "^2.5.10", "@sveltejs/package": "^2.3.1", "@tailwindcss/typography": "^0.5.7", "@testing-library/svelte": "^5.1.0", @@ -57,21 +57,21 @@ "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.38.0", "jsdom": "^24.0.0", - "konva": "^9.2.0", + "konva": "^9.3.11", "lodash.clonedeep": "^4.5.0", "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", - "svelte": "5.0.0-next.123", - "svelte-check": "^3.7.0", + "svelte": "5.0.0-next.141", + "svelte-check": "^3.7.1", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", "svelte-preprocess": "^5.0.4", "tailwindcss": "^3.1.8", "tslib": "^2.5.3", "typescript": "^5.4.2", - "vite": "^5.0.0", - "vitest": "^1.5.3" + "vite": "^5.2.11", + "vitest": "^1.6.0" }, "type": "module", "exports": { diff --git a/src/routes/ResponsiveStage.svelte b/src/routes/ResponsiveStage.svelte index 99d9557..f4fcc3a 100644 --- a/src/routes/ResponsiveStage.svelte +++ b/src/routes/ResponsiveStage.svelte @@ -1,5 +1,4 @@ + + From c8a084ffff8d348db5d6975133dd895f107fc597 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Sun, 26 May 2024 13:41:47 +0200 Subject: [PATCH 28/56] Remove unaltered context tests on components without children as svelte's guarantees on contexts prevent context altering in those components to affect any parent elements --- src/templates/svelteKonvaComponentTests.hbs | 15 -------------- src/tests/arc.test.ts | 15 -------------- src/tests/arrow.test.ts | 15 -------------- src/tests/circle.test.ts | 15 -------------- src/tests/ellipse.test.ts | 15 -------------- src/tests/image.test.ts | 19 ----------------- src/tests/line.test.ts | 15 -------------- src/tests/path.test.ts | 15 -------------- src/tests/rect.test.ts | 15 -------------- src/tests/regularpolygon.test.ts | 15 -------------- src/tests/ring.test.ts | 15 -------------- src/tests/shape.test.ts | 23 --------------------- src/tests/sprite.test.ts | 23 --------------------- src/tests/star.test.ts | 15 -------------- src/tests/tag.test.ts | 15 -------------- src/tests/text.test.ts | 15 -------------- src/tests/textpath.test.ts | 15 -------------- src/tests/wedge.test.ts | 15 -------------- 18 files changed, 290 deletions(-) diff --git a/src/templates/svelteKonvaComponentTests.hbs b/src/templates/svelteKonvaComponentTests.hbs index a7280bb..bdf80d9 100644 --- a/src/templates/svelteKonvaComponentTests.hbs +++ b/src/templates/svelteKonvaComponentTests.hbs @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render({{ componentName }}, { - context: mockContext, - props: { - config: {{{ testConfig }}} - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render({{ componentName }}, { diff --git a/src/tests/arc.test.ts b/src/tests/arc.test.ts index 81440dd..42ab7c7 100644 --- a/src/tests/arc.test.ts +++ b/src/tests/arc.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Arc, { - context: mockContext, - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Arc, { diff --git a/src/tests/arrow.test.ts b/src/tests/arrow.test.ts index 93707de..67fcf94 100644 --- a/src/tests/arrow.test.ts +++ b/src/tests/arrow.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Arrow, { - context: mockContext, - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Arrow, { diff --git a/src/tests/circle.test.ts b/src/tests/circle.test.ts index e2c53e6..974766e 100644 --- a/src/tests/circle.test.ts +++ b/src/tests/circle.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Circle, { - context: mockContext, - props: { - config: { x: 0, radius: 100 } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Circle, { diff --git a/src/tests/ellipse.test.ts b/src/tests/ellipse.test.ts index c295d6e..fd2bb09 100644 --- a/src/tests/ellipse.test.ts +++ b/src/tests/ellipse.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Ellipse, { - context: mockContext, - props: { - config: { x: 0, radiusX: 120, radiusY: 70 } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Ellipse, { diff --git a/src/tests/image.test.ts b/src/tests/image.test.ts index 877a515..6a92b7d 100644 --- a/src/tests/image.test.ts +++ b/src/tests/image.test.ts @@ -214,25 +214,6 @@ test('Does not update config if instantiated with staticConfig prop', async () = expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', async () => { - const testImage = await loadImage(image); - - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(KonvaImage, { - context: mockContext, - props: { - config: { - image: testImage - } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', async () => { const testImage = await loadImage(image); diff --git a/src/tests/line.test.ts b/src/tests/line.test.ts index 3518163..987980d 100644 --- a/src/tests/line.test.ts +++ b/src/tests/line.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Line, { - context: mockContext, - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Line, { diff --git a/src/tests/path.test.ts b/src/tests/path.test.ts index bdaee64..391de0f 100644 --- a/src/tests/path.test.ts +++ b/src/tests/path.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Path, { - context: mockContext, - props: { - config: { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Path, { diff --git a/src/tests/rect.test.ts b/src/tests/rect.test.ts index a77753e..d852e1a 100644 --- a/src/tests/rect.test.ts +++ b/src/tests/rect.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Rect, { - context: mockContext, - props: { - config: { x: 0, width: 100, height: 100 } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Rect, { diff --git a/src/tests/regularpolygon.test.ts b/src/tests/regularpolygon.test.ts index aafbec0..cc0f5f7 100644 --- a/src/tests/regularpolygon.test.ts +++ b/src/tests/regularpolygon.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(RegularPolygon, { - context: mockContext, - props: { - config: { x: 0, sides: 7, radius: 80 } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(RegularPolygon, { diff --git a/src/tests/ring.test.ts b/src/tests/ring.test.ts index e81bafe..b567c6b 100644 --- a/src/tests/ring.test.ts +++ b/src/tests/ring.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Ring, { - context: mockContext, - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100 } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Ring, { diff --git a/src/tests/shape.test.ts b/src/tests/shape.test.ts index b437855..a8e3d1b 100644 --- a/src/tests/shape.test.ts +++ b/src/tests/shape.test.ts @@ -243,29 +243,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Shape, { - context: mockContext, - props: { - config: { - width: 100, - height: 100, - sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { - context.beginPath(); - context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); - context.fillStrokeShape(shape); - } - } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Shape, { diff --git a/src/tests/sprite.test.ts b/src/tests/sprite.test.ts index e02bdaf..2caedde 100644 --- a/src/tests/sprite.test.ts +++ b/src/tests/sprite.test.ts @@ -246,29 +246,6 @@ test('Does not update config if instantiated with staticConfig prop', async () = expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', async () => { - const spriteImage = await loadImage(sprite); - - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Sprite, { - context: mockContext, - props: { - config: { - image: spriteImage, - animation: 'default', - animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, - frameRate: 7, - frameIndex: 0 - } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', async () => { const spriteImage = await loadImage(sprite); diff --git a/src/tests/star.test.ts b/src/tests/star.test.ts index 29514b6..f0b3a55 100644 --- a/src/tests/star.test.ts +++ b/src/tests/star.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Star, { - context: mockContext, - props: { - config: { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Star, { diff --git a/src/tests/tag.test.ts b/src/tests/tag.test.ts index f4d7427..50b9590 100644 --- a/src/tests/tag.test.ts +++ b/src/tests/tag.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Tag, { - context: mockContext, - props: { - config: { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Tag, { diff --git a/src/tests/text.test.ts b/src/tests/text.test.ts index 8f65e69..dc0ece5 100644 --- a/src/tests/text.test.ts +++ b/src/tests/text.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Text, { - context: mockContext, - props: { - config: { x: 0, fontSize: 100, text: 'some text', fill: 'black' } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Text, { diff --git a/src/tests/textpath.test.ts b/src/tests/textpath.test.ts index c290158..5b8bb74 100644 --- a/src/tests/textpath.test.ts +++ b/src/tests/textpath.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(TextPath, { - context: mockContext, - props: { - config: { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(TextPath, { diff --git a/src/tests/wedge.test.ts b/src/tests/wedge.test.ts index 816c4ff..a7b51de 100644 --- a/src/tests/wedge.test.ts +++ b/src/tests/wedge.test.ts @@ -180,21 +180,6 @@ test('Does not update config if instantiated with staticConfig prop', () => { expect(config).toStrictEqual(oldConfig); }); -test('Does not alter the context', () => { - const mockContext = createMockParentContext(Container.Layer); - const rendered = render(Wedge, { - context: mockContext, - props: { - config: { x: 0, radius: 100, angle: 300 } - } - }); - - const component = rendered.component.$$; - const context = component.context; - - expect(context).toStrictEqual(mockContext); -}); - test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Wedge, { From 9a47ab996bffff85c45fefb7e2fa7c193d778008 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Sun, 26 May 2024 14:09:54 +0200 Subject: [PATCH 29/56] Fix context tests for svelte v5, all tests working again --- src/tests/group.test.ts | 34 ++++++++++++------- src/tests/label.test.ts | 28 ++++++++------- src/tests/layer.test.ts | 34 ++++++++++++------- src/tests/stage.test.ts | 32 +++++++++++------ .../wrappers/ContainerContext.test.svelte | 31 +++++++++++++++++ .../wrappers/ContextReporter.test.svelte | 23 +++++++++++++ 6 files changed, 132 insertions(+), 50 deletions(-) create mode 100644 src/tests/wrappers/ContainerContext.test.svelte create mode 100644 src/tests/wrappers/ContextReporter.test.svelte diff --git a/src/tests/group.test.ts b/src/tests/group.test.ts index d53c41e..266d725 100644 --- a/src/tests/group.test.ts +++ b/src/tests/group.test.ts @@ -14,6 +14,7 @@ import type { MockStage } from './mocks/mouse'; // Test Component Wrappers import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; +import ContainerContext from './wrappers/ContainerContext.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { @@ -179,30 +180,37 @@ test('Does not update config if instantiated with staticConfig prop', () => { }); test('sets the correct context', () => { - const rendered = render(Group, { - context: createMockParentContext(Container.Layer) - }); + let childContext: Map | null = null; + let handle: Konva.Group | null = null; - const component = rendered.component.$$; - const context = component.context; - const handle = rendered.component.handle; + render(ContainerContext, { + context: createMockParentContext(Container.Layer), + props: { + component: Group, + getHandle: (hnd) => (handle = hnd), + getComponentContext: (ctxMap) => (childContext = ctxMap) + } + }); - expect(get(context.get(CONTAINER_COMPONENT_KEYS[Container.Group]))).toStrictEqual(handle); + expect(get(childContext!.get(CONTAINER_COMPONENT_KEYS[Container.Group]))).toStrictEqual(handle!); }); test('nulls unused context', () => { - const rendered = render(Group, { - context: createMockParentContext(Container.Layer) - }); + let childContext: Map | null = null; - const component = rendered.component.$$; - const context = component.context; + render(ContainerContext, { + context: createMockParentContext(Container.Layer), + props: { + component: Group, + getComponentContext: (ctxMap) => (childContext = ctxMap) + } + }); const otherKeys = CONTAINER_COMPONENT_KEYS.slice(); otherKeys.splice(Container.Group, 1); otherKeys.forEach((e) => { - expect(context.get(e)).toBe(null); + expect(childContext!.get(e)).toBe(null); }); }); diff --git a/src/tests/label.test.ts b/src/tests/label.test.ts index 0481d55..2aae94b 100644 --- a/src/tests/label.test.ts +++ b/src/tests/label.test.ts @@ -14,6 +14,7 @@ import type { MockStage } from './mocks/mouse'; // Test Component Wrappers import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; +import ContainerContext from './wrappers/ContainerContext.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { @@ -182,36 +183,37 @@ test('Does not update config if instantiated with staticConfig prop', async () = }); test('sets the correct context', () => { - const rendered = render(Label, { + let childContext: Map | null = null; + let handle: Konva.Label | null = null; + + render(ContainerContext, { context: createMockParentContext(Container.Layer), props: { - config: {} + component: Label, + getHandle: (hnd) => (handle = hnd), + getComponentContext: (ctxMap) => (childContext = ctxMap) } }); - const component = rendered.component.$$; - const context = component.context; - const handle = rendered.component.handle; - - expect(get(context.get(CONTAINER_COMPONENT_KEYS[Container.Label]))).toStrictEqual(handle); + expect(get(childContext!.get(CONTAINER_COMPONENT_KEYS[Container.Label]))).toStrictEqual(handle!); }); test('nulls unused context', () => { - const rendered = render(Label, { + let childContext: Map | null = null; + + render(ContainerContext, { context: createMockParentContext(Container.Layer), props: { - config: {} + component: Label, + getComponentContext: (ctxMap) => (childContext = ctxMap) } }); - const component = rendered.component.$$; - const context = component.context; - const otherKeys = CONTAINER_COMPONENT_KEYS.slice(); otherKeys.splice(Container.Label, 1); otherKeys.forEach((e) => { - expect(context.get(e)).toBe(null); + expect(childContext!.get(e)).toBe(null); }); }); diff --git a/src/tests/layer.test.ts b/src/tests/layer.test.ts index 0ee8cfa..572c622 100644 --- a/src/tests/layer.test.ts +++ b/src/tests/layer.test.ts @@ -14,6 +14,7 @@ import type { MockStage } from './mocks/mouse'; // Test Component Wrappers import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; +import ContainerContext from './wrappers/ContainerContext.test.svelte'; test('throws an error if not placed inside a Stage component', () => { expect(() => { @@ -161,31 +162,38 @@ test('Does not update config if instantiated with staticConfig prop', async () = test('sets the correct context', () => { const div = document.createElement('div'); - const rendered = render(Layer, { - context: createMockParentContext(Container.Stage, div) - }); + let childContext: Map | null = null; + let handle: Konva.Layer | null = null; - const component = rendered.component.$$; - const context = component.context; - const handle = rendered.component.handle; + render(ContainerContext, { + context: createMockParentContext(Container.Stage, div), + props: { + component: Layer, + getHandle: (hnd) => (handle = hnd), + getComponentContext: (ctxMap) => (childContext = ctxMap) + } + }); - expect(get(context.get(CONTAINER_COMPONENT_KEYS[Container.Layer]))).toStrictEqual(handle); + expect(get(childContext!.get(CONTAINER_COMPONENT_KEYS[Container.Layer]))).toStrictEqual(handle!); }); test('nulls unused context', () => { const div = document.createElement('div'); - const rendered = render(Layer, { - context: createMockParentContext(Container.Stage, div) - }); + let childContext: Map | null = null; - const component = rendered.component.$$; - const context = component.context; + render(ContainerContext, { + context: createMockParentContext(Container.Stage, div), + props: { + component: Layer, + getComponentContext: (ctxMap) => (childContext = ctxMap) + } + }); const otherKeys = CONTAINER_COMPONENT_KEYS.slice(); otherKeys.splice(Container.Layer, 1); otherKeys.forEach((e) => { - expect(context.get(e)).toBe(null); + expect(childContext!.get(e)).toBe(null); }); }); diff --git a/src/tests/stage.test.ts b/src/tests/stage.test.ts index a19fa4f..000cae0 100644 --- a/src/tests/stage.test.ts +++ b/src/tests/stage.test.ts @@ -13,6 +13,7 @@ import type { MockStage } from './mocks/mouse'; // Test Component Wrappers import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; +import ContainerContext from './wrappers/ContainerContext.test.svelte'; test('creates a div container and forwards rest props to div', () => { const rendered = render(Stage, { @@ -127,28 +128,37 @@ test('Does not update config if instantiated with staticConfig prop', async () = }); test('sets the correct context', () => { - const rendered = render(Stage, { - config: { width: 1000, height: 1000 } - }); - - const component = rendered.component.$$; + let childContext: Map | null = null; + let handle: Konva.Stage | null = null; - const context = component.context; - const handle = rendered.component.handle(); + render(ContainerContext, { + props: { + component: Stage, + config: { width: 1000, height: 1000 }, + getHandle: (hnd) => (handle = hnd()), + getComponentContext: (ctxMap) => (childContext = ctxMap) + } + }); - expect(get(context.get(CONTAINER_COMPONENT_KEYS[Container.Stage]))).toStrictEqual(handle); + expect(get(childContext!.get(CONTAINER_COMPONENT_KEYS[Container.Stage]))).toStrictEqual(handle!); }); test('nulls unused context', () => { - render(Stage, { - props: { config: { width: 1000, height: 1000 } } + let childContext: Map | null = null; + + render(ContainerContext, { + props: { + component: Stage, + config: { width: 1000, height: 1000 }, + getComponentContext: (ctxMap) => (childContext = ctxMap) + } }); const otherKeys = CONTAINER_COMPONENT_KEYS.slice(); otherKeys.splice(Container.Stage, 1); otherKeys.forEach((e) => { - expect(context.get(e)).toBe(null); + expect(childContext!.get(e)).toBe(null); }); }); diff --git a/src/tests/wrappers/ContainerContext.test.svelte b/src/tests/wrappers/ContainerContext.test.svelte new file mode 100644 index 0000000..56e6a1f --- /dev/null +++ b/src/tests/wrappers/ContainerContext.test.svelte @@ -0,0 +1,31 @@ + + + + + + diff --git a/src/tests/wrappers/ContextReporter.test.svelte b/src/tests/wrappers/ContextReporter.test.svelte new file mode 100644 index 0000000..fd56162 --- /dev/null +++ b/src/tests/wrappers/ContextReporter.test.svelte @@ -0,0 +1,23 @@ + + From 5c8c1f138a5991e47b318a0ef7ab33b22ada38be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Sun, 26 May 2024 14:47:07 +0200 Subject: [PATCH 30/56] Fix transform example, update +Layout.svelte to runes and svelte v5 --- src/routes/+layout.svelte | 6 +++-- .../examples/transform/Transform.svelte | 23 ++++++++++++------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte index ae3517b..1203347 100644 --- a/src/routes/+layout.svelte +++ b/src/routes/+layout.svelte @@ -3,6 +3,8 @@ import Link from './Link.svelte'; import { darkMode } from './stores'; + const { children } = $props(); + let examples = [ { name: 'Label', @@ -63,7 +65,7 @@ />
-
diff --git a/src/routes/examples/transform/Transform.svelte b/src/routes/examples/transform/Transform.svelte index bea1c38..6aa3232 100644 --- a/src/routes/examples/transform/Transform.svelte +++ b/src/routes/examples/transform/Transform.svelte @@ -1,7 +1,7 @@ - - + From d7a755d2d45b2847b32f6af6902b6b6794493a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Sun, 26 May 2024 15:53:17 +0200 Subject: [PATCH 31/56] Move getting started guide of svelte-konva v0 into own file (legacy), create svelte-konva v1 migration guide (WIP) --- docs/svelte-konva-v0-guide.md | 207 ++++++++++++++++++++++++++++++ docs/svelte-konva-v1-migration.md | 90 +++++++++++++ 2 files changed, 297 insertions(+) create mode 100644 docs/svelte-konva-v0-guide.md create mode 100644 docs/svelte-konva-v1-migration.md diff --git a/docs/svelte-konva-v0-guide.md b/docs/svelte-konva-v0-guide.md new file mode 100644 index 0000000..a316c41 --- /dev/null +++ b/docs/svelte-konva-v0-guide.md @@ -0,0 +1,207 @@ +# svelte-konva v0 getting started guide (legacy) + +This guide covers the basics of svelte-konva v0. For the newer svelte-konva v1 supporting Svelte v5, please consult the [README](../README.md). + +## Compatibility + +svelte-konva v0 is compatible with Svelte v3 & 4, SvelteKit v1 and Konva v8 & 9. + +## Install + +```npm +npm i svelte-konva@0 konva +``` + +## Quick start + +```svelte + + + + + + + +``` + +### Events + +You can listen to Konva events by using the Svelte `on:event` Syntax. All [Konva events](https://konvajs.org/docs/events/Binding_Events.html) are supported. + +```svelte + + + + + + + +``` + +### Accessing the underlying Konva node + +In various cases it is useful and required to be able to access the underlying Konva node object. In svelte-konva you can do this by binding the `handle` prop. + +```svelte + + + + + + + +``` + +### Binding the config prop + +By default svelte-konva keeps your config in sync (position, rotation, scale, etc.) with the Konva node after `dragend` and `transformend` events. If you bind the config prop any reactive blocks depending on the config will also be triggered once such changes happen. In case you don't want svelte-konva to sync those changes you can pass the `staticConfig` prop to the component. + +```svelte + + + + + + + +``` + +### Usage with SvelteKit + +Generally svelte-konva is a client-side only library. When using SvelteKit, special care needs to be taken if svelte-konva/Konva functionality is used on prerendered and server side rendered (SSR) components. Prerendering and SSR happens in a Node.js environment which causes Konva to require the [canvas](https://www.npmjs.com/package/canvas) library as Konva can also be used in Node.js environments. When you use svelte-konva in such conditions you'll likely run into the following error: + +> Error: Cannot find module 'canvas' + +There are multiple solutions to this problem: + +**Installing canvas:** + +Simplest solution is to install canvas: + +```npm +npm i canvas +``` + +This will satisfy the canvas dependency of Konva and you can use svelte-konva components in prerendered and SSR SvelteKit pages. The solution is a bit messy though, as you now have installed a package you don't really need which adds unnecessary overhead. Alternatively use one of the following solutions: + +**Dynamically import your svelte-konva stage:** + +A better approach is to dynamically import your svelte-konva canvas on the client-side only. Suppose you have a Svelte component containing your stage with various svelte-konva components: + +_MyCanvas.svelte_ + +```svelte + + + + + + + + + +``` + +To use this component inside a SvelteKit prerendered/SSR page you can dynamically import it inside `onMount()` and render it using ``: + +_+page.svelte_ + +```svelte + + +
+

This is my fancy server side rendered (or prerendered) page.

+ + + +
+``` + +**Dynamically import svelte-konva using vite:** + +The [vite-plugin-iso-import](https://www.npmjs.com/package/vite-plugin-iso-import) allows you to make client-side only imports without needing the manual approach in `onMount()` described above. Please follow the installation instructions in the [README](https://www.npmjs.com/package/vite-plugin-iso-import) then you can dynamically import your component like so: + +_+page.svelte_ + +```svelte + + +
+

This is my fancy server side rendered (or prerendered) page.

+ + + +
+``` + +Currently vite-plugin-iso-import cannot automatically fix intellisense inside .svelte files with TypeScript. Consult the [README](https://www.npmjs.com/package/vite-plugin-iso-import) for a workaround to this problem. + +For further examples please consult the [docs](https://konvajs.org/docs/svelte) or clone the repo and run `npm i && npm run examples`. diff --git a/docs/svelte-konva-v1-migration.md b/docs/svelte-konva-v1-migration.md new file mode 100644 index 0000000..13c018b --- /dev/null +++ b/docs/svelte-konva-v1-migration.md @@ -0,0 +1,90 @@ +# Migration to svelte-konva v1 + +## Event handlers + +In Svelte v5 usage of the `on:event` syntax is deprecated. svelte-konva provides all Konva events now as callback props using the `on` syntax. The deprecated `on:event` syntax will no longer work for svelte-konva events: + +```diff + +``` + +### Event payloads + +Additionally the event payload data has changed. Instead of being wrapped in a `CustomEvent` under the `detail` property the whole Konva event payload is now directly accessible: + +```diff +function handleClick(e) { +- const konvaEvent = e.detail; +- window.alert(`Clicked on rectangle: ${konvaEvent.type}`); ++ window.alert(`Clicked on rectangle: ${e.type}`); +} +``` + +## Accessing the underlying Konva handle + +The way to access the corresponding Konva handle in a svelte-konva component has changed. You can no longer bind the `handle` prop to access it. Instead `handle` is now exposed directly on the component instance. To access it use `bind:this` and then access the `handle` property on the component object: + +```diff + + + + + + + +``` + +Additionally, you no longer need to wait a tick before accessing `handle` as it will be immediately defined on component instantiation. + +## Stage handle + +The stage `handle` needs special treatment, as it only becomes defined once the canvas HTML element has been rendered to the DOM. Due to this, the `handle` property on the stage component is a function which can be called to retrieve the Konva handle. It returns `null` if the stage object has not been created yet: + +```svelte + + + + + + + +``` + +## Svelte runes-only mode + +svelte-konva is now fully compatible with Svelte's runes-only compile mode which means it will work out of the box for runes-only projects. It will also continue to work for all projects without runes-only mode enabled. From 7eae45b94d29590970f49e2dffbb2828a20a1368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Sat, 1 Jun 2024 11:49:06 +0200 Subject: [PATCH 32/56] Fix non reactive in stage due to _handle not being --- src/lib/Stage.svelte | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib/Stage.svelte b/src/lib/Stage.svelte index 194530b..23ca148 100644 --- a/src/lib/Stage.svelte +++ b/src/lib/Stage.svelte @@ -64,7 +64,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), ...restProps }: Props & PropsContainer & PropsStage = $props(); - let _handle: Konva.Stage | null = null; + let _handle: Konva.Stage | null = $state(null); export function handle() { return _handle; } @@ -141,7 +141,6 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), setContainerContext(Container.Stage, inner); -
{#if isReady && children} {@render children()} From cfe0f8500043172307af11652d1a59e0d238a4f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 7 Jun 2024 08:52:20 +0200 Subject: [PATCH 33/56] update svelte --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 8b8a978..5bab52f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", - "svelte": "5.0.0-next.141", + "svelte": "5.0.0-next.151", "svelte-check": "^3.7.1", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", @@ -7136,9 +7136,9 @@ } }, "node_modules/svelte": { - "version": "5.0.0-next.141", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.141.tgz", - "integrity": "sha512-zT74TUo0vOOrbxRfdlWXu+ac4O9lqPFG0YoZB3uOfrOewT1GKxKm0qwG/jo9bGvgZ++TSHjR7AtV091LY2FhBA==", + "version": "5.0.0-next.151", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.151.tgz", + "integrity": "sha512-1XmoL74CYNpWQZI8o6IqXJQbIL+eVA+MIyfis0ErlEmO7p8+DxdsGREIyg2Qpr1CgT+Eva9R1zfMA9KG/Nd8wg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", diff --git a/package.json b/package.json index 0dfae0a..8c1fb12 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", - "svelte": "5.0.0-next.141", + "svelte": "5.0.0-next.151", "svelte-check": "^3.7.1", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", From fb9cb56883cf5b3f18f98a9611f5dc4904774b32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Mon, 10 Jun 2024 15:35:42 +0200 Subject: [PATCH 34/56] Fix: transformer config prop was not optional --- src/lib/Transformer.svelte | 4 ++-- src/routes/examples/transform/Transform.svelte | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/Transformer.svelte b/src/lib/Transformer.svelte index 191c2e0..07913f2 100644 --- a/src/lib/Transformer.svelte +++ b/src/lib/Transformer.svelte @@ -30,13 +30,13 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Transformer. import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; import { copyExistingKeys } from '$lib/util/object'; - import { type Props } from '$lib/util/props'; + import { type PropsOptionalConfig } from '$lib/util/props'; let { config = $bindable({}), staticConfig = false, ...eventHooks - }: Props = $props(); + }: PropsOptionalConfig = $props(); export const handle = new Konva.Transformer(config); diff --git a/src/routes/examples/transform/Transform.svelte b/src/routes/examples/transform/Transform.svelte index 6aa3232..55e2053 100644 --- a/src/routes/examples/transform/Transform.svelte +++ b/src/routes/examples/transform/Transform.svelte @@ -171,7 +171,7 @@ /> - + From b6003b3befe671b3014d31d46a63c6e0e00801ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Mon, 15 Jul 2024 19:43:23 +0200 Subject: [PATCH 35/56] Update Svelte & Kit --- package-lock.json | 32 ++++++++++++++++---------------- package.json | 10 +++++----- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5bab52f..24f8ba1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,9 +9,9 @@ "version": "0.3.1", "license": "MIT", "devDependencies": { - "@sveltejs/adapter-static": "^3.0.1", - "@sveltejs/kit": "^2.5.10", - "@sveltejs/package": "^2.3.1", + "@sveltejs/adapter-static": "^3.0.2", + "@sveltejs/kit": "^2.5.18", + "@sveltejs/package": "^2.3.2", "@tailwindcss/typography": "^0.5.7", "@testing-library/svelte": "^5.1.0", "@types/lodash.clonedeep": "^4.5.7", @@ -28,7 +28,7 @@ "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", - "svelte": "5.0.0-next.151", + "svelte": "5.0.0-next.184", "svelte-check": "^3.7.1", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", @@ -1073,18 +1073,18 @@ "dev": true }, "node_modules/@sveltejs/adapter-static": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.1.tgz", - "integrity": "sha512-6lMvf7xYEJ+oGeR5L8DFJJrowkefTK6ZgA4JiMqoClMkKq0s6yvsd3FZfCFvX1fQ0tpCD7fkuRVHsnUVgsHyNg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@sveltejs/adapter-static/-/adapter-static-3.0.2.tgz", + "integrity": "sha512-/EBFydZDwfwFfFEuF1vzUseBoRziwKP7AoHAwv+Ot3M084sE/HTVBHf9mCmXfdM9ijprY5YEugZjleflncX5fQ==", "dev": true, "peerDependencies": { "@sveltejs/kit": "^2.0.0" } }, "node_modules/@sveltejs/kit": { - "version": "2.5.10", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.10.tgz", - "integrity": "sha512-OqoyTmFG2cYmCFAdBfW+Qxbg8m23H4dv6KqwEt7ofr/ROcfcIl3Z/VT56L22H9f0uNZyr+9Bs1eh2gedOCK9kA==", + "version": "2.5.18", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.5.18.tgz", + "integrity": "sha512-+g06hvpVAnH7b4CDjhnTDgFWBKBiQJpuSmQeGYOuzbO3SC3tdYjRNlDCrafvDtKbGiT2uxY5Dn9qdEUGVZdWOQ==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -1114,9 +1114,9 @@ } }, "node_modules/@sveltejs/package": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@sveltejs/package/-/package-2.3.1.tgz", - "integrity": "sha512-JvR2J4ost1oCn1CSdqenYRwGX/1RX+7LN+VZ71aPnz3JAlIFaEKQd1pBxlb+OSQTfeugJO0W39gB9voAbBO5ow==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@sveltejs/package/-/package-2.3.2.tgz", + "integrity": "sha512-6M8/Te7iXRG7SiH92wugqfyoJpuepjn78L433LnXicUeMso9M/N4vdL9DPK3MfTkVVY4klhNRptVqme3p4oZWA==", "dev": true, "dependencies": { "chokidar": "^3.6.0", @@ -7136,9 +7136,9 @@ } }, "node_modules/svelte": { - "version": "5.0.0-next.151", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.151.tgz", - "integrity": "sha512-1XmoL74CYNpWQZI8o6IqXJQbIL+eVA+MIyfis0ErlEmO7p8+DxdsGREIyg2Qpr1CgT+Eva9R1zfMA9KG/Nd8wg==", + "version": "5.0.0-next.184", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.184.tgz", + "integrity": "sha512-oHWNajXOytt/5s2Ark3o/CP7bHLx+o/QZjTkCtU1dECqSmYyGqrIsoZi0Cx0VBdXAHMqI+1/T70ppaL1cL7LEw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", diff --git a/package.json b/package.json index 8c1fb12..86c2e70 100644 --- a/package.json +++ b/package.json @@ -43,9 +43,9 @@ "svelte": "5" }, "devDependencies": { - "@sveltejs/adapter-static": "^3.0.1", - "@sveltejs/kit": "^2.5.10", - "@sveltejs/package": "^2.3.1", + "@sveltejs/adapter-static": "^3.0.2", + "@sveltejs/kit": "^2.5.18", + "@sveltejs/package": "^2.3.2", "@tailwindcss/typography": "^0.5.7", "@testing-library/svelte": "^5.1.0", "@types/lodash.clonedeep": "^4.5.7", @@ -62,7 +62,7 @@ "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", - "svelte": "5.0.0-next.151", + "svelte": "5.0.0-next.184", "svelte-check": "^3.7.1", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", @@ -269,4 +269,4 @@ ] } } -} +} \ No newline at end of file From c901334efb8208dcf0d03a11f78c0ae325ab8639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Mon, 15 Jul 2024 19:45:26 +0200 Subject: [PATCH 36/56] Update daisyUI --- package-lock.json | 8 ++++---- package.json | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 24f8ba1..ad54d43 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,7 +18,7 @@ "@typescript-eslint/eslint-plugin": "^7.7.1", "@typescript-eslint/parser": "^7.7.1", "canvas": "^2.11.2", - "daisyui": "^4.4.2", + "daisyui": "^4.12.10", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.38.0", @@ -2488,9 +2488,9 @@ } }, "node_modules/daisyui": { - "version": "4.4.24", - "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.4.24.tgz", - "integrity": "sha512-u/B3484J08V7N0rIYymnC+SyxOjlYQL+2vyhHWV+/KC+VaUcbEF2Z3H06eCPgdTiZ0J+ml44aH7wBhIymPFQ+g==", + "version": "4.12.10", + "resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.12.10.tgz", + "integrity": "sha512-jp1RAuzbHhGdXmn957Z2XsTZStXGHzFfF0FgIOZj3Wv9sH7OZgLfXTRZNfKVYxltGUOBsG1kbWAdF5SrqjebvA==", "dev": true, "dependencies": { "css-selector-tokenizer": "^0.8", diff --git a/package.json b/package.json index 86c2e70..4e0bc0e 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "@typescript-eslint/eslint-plugin": "^7.7.1", "@typescript-eslint/parser": "^7.7.1", "canvas": "^2.11.2", - "daisyui": "^4.4.2", + "daisyui": "^4.12.10", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.38.0", @@ -269,4 +269,4 @@ ] } } -} \ No newline at end of file +} From 4e005c0e32813d49249889d5a5cd6f483f240418 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Thu, 25 Jul 2024 15:21:32 +0200 Subject: [PATCH 37/56] Split config prop properties into individual props --- docs/svelte-konva-v1-migration.md | 4 + plopfile.js | 38 ++-- src/lib/Arc.svelte | 80 +++++++-- src/lib/Arrow.svelte | 80 +++++++-- src/lib/Circle.svelte | 80 +++++++-- src/lib/Ellipse.svelte | 80 +++++++-- src/lib/Group.svelte | 83 +++++++-- src/lib/Image.svelte | 80 +++++++-- src/lib/Label.svelte | 77 ++++++-- src/lib/Layer.svelte | 84 +++++++-- src/lib/Line.svelte | 80 +++++++-- src/lib/Path.svelte | 80 +++++++-- src/lib/Rect.svelte | 80 +++++++-- src/lib/RegularPolygon.svelte | 80 +++++++-- src/lib/Ring.svelte | 80 +++++++-- src/lib/Shape.svelte | 80 +++++++-- src/lib/Sprite.svelte | 80 +++++++-- src/lib/Stage.svelte | 165 +++++++++++++++++- src/lib/Star.svelte | 80 +++++++-- src/lib/Tag.svelte | 80 +++++++-- src/lib/Text.svelte | 80 +++++++-- src/lib/TextPath.svelte | 80 +++++++-- src/lib/Transformer.svelte | 82 +++++++-- src/lib/Wedge.svelte | 80 +++++++-- src/lib/util/props.ts | 12 +- src/routes/ResponsiveStage.svelte | 8 +- src/routes/examples/connectFour/Game.svelte | 9 +- .../examples/connectFour/GameGrid.svelte | 14 +- src/routes/examples/connectFour/Token.svelte | 8 +- src/routes/examples/drawing/Drawing.svelte | 2 +- src/routes/examples/group/Group.svelte | 5 +- src/routes/examples/label/Label.svelte | 28 ++- .../examples/transform/Transform.svelte | 13 +- src/templates/svelteKonvaComponent.hbs | 78 +++++++-- 34 files changed, 1724 insertions(+), 346 deletions(-) diff --git a/docs/svelte-konva-v1-migration.md b/docs/svelte-konva-v1-migration.md index 13c018b..f2f23b9 100644 --- a/docs/svelte-konva-v1-migration.md +++ b/docs/svelte-konva-v1-migration.md @@ -88,3 +88,7 @@ The stage `handle` needs special treatment, as it only becomes defined once the ## Svelte runes-only mode svelte-konva is now fully compatible with Svelte's runes-only compile mode which means it will work out of the box for runes-only projects. It will also continue to work for all projects without runes-only mode enabled. + +## Changes to `config` prop reactivity + +TBD diff --git a/plopfile.js b/plopfile.js index 9fda372..f5070ef 100644 --- a/plopfile.js +++ b/plopfile.js @@ -2,93 +2,89 @@ const COMPONENT_LIST = [ { componentName: 'Circle', - example: '', + example: '', testConfig: '{ x: 0, radius: 100 }' }, { componentName: 'Rect', - example: '', + example: '', testConfig: '{ x: 0, width: 100, height: 100 }' }, { componentName: 'Ellipse', - example: '', + example: '', testConfig: '{ x: 0, radiusX: 120, radiusY: 70 }' }, { componentName: 'Wedge', - example: '', + example: '', testConfig: '{ x: 0, radius: 100, angle: 300 }' }, { componentName: 'Line', - example: - '', + example: '', testConfig: "{ x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }" }, { componentName: 'Sprite', example: - '' + '' }, { componentName: 'Image', - example: '' + example: '' }, { componentName: 'Text', - example: '', + example: '', testConfig: "{ x: 0, fontSize: 100, text: 'some text', fill: 'black' }" }, { componentName: 'TextPath', example: - '', + '', testConfig: "{ x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' }" }, { componentName: 'Star', - example: - '', + example: '', testConfig: '{ x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 }' }, { componentName: 'Ring', - example: '', + example: '', testConfig: '{ x: 0, innerRadius: 20, outerRadius: 100 }' }, { componentName: 'Arc', - example: - '', + example: '', testConfig: '{ x: 0, innerRadius: 20, outerRadius: 100, angle: 300 }' }, { componentName: 'Path', example: - '', + '', testConfig: "{ x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' }" }, { componentName: 'RegularPolygon', - example: '', + example: '', testConfig: '{ x: 0, sides: 7, radius: 80 }' }, { componentName: 'Arrow', example: - '', + '', testConfig: "{ x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }" }, { componentName: 'Shape', - example: - ' {} }} />' + example: ' {}} />' }, { componentName: 'Tag', example: - '', + '', testConfig: "{ x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 }" } ]; diff --git a/src/lib/Arc.svelte b/src/lib/Arc.svelte index 653b18d..29aeee4 100644 --- a/src/lib/Arc.svelte +++ b/src/lib/Arc.svelte @@ -4,7 +4,7 @@ The Arc component needs to be placed either inside a svelte-konva Layer or Group ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Arc.html), [ import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Arc(config); + export const handle = new Konva.Arc({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Arrow.svelte b/src/lib/Arrow.svelte index c698d49..42877e8 100644 --- a/src/lib/Arrow.svelte +++ b/src/lib/Arrow.svelte @@ -4,7 +4,7 @@ The Arrow component needs to be placed either inside a svelte-konva Layer or Gro ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Arrow.html), import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Arrow(config); + export const handle = new Konva.Arrow({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Circle.svelte b/src/lib/Circle.svelte index 8bc8907..262a8a7 100644 --- a/src/lib/Circle.svelte +++ b/src/lib/Circle.svelte @@ -4,7 +4,7 @@ The Circle component needs to be placed either inside a svelte-konva Layer or Gr ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Circle.html) import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Circle(config); + export const handle = new Konva.Circle({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Ellipse.svelte b/src/lib/Ellipse.svelte index 4436ca7..6c7267c 100644 --- a/src/lib/Ellipse.svelte +++ b/src/lib/Ellipse.svelte @@ -4,7 +4,7 @@ The Ellipse component needs to be placed either inside a svelte-konva Layer or G ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Ellipse.html import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Ellipse(config); + export const handle = new Konva.Ellipse({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Group.svelte b/src/lib/Group.svelte index f04919d..c995369 100644 --- a/src/lib/Group.svelte +++ b/src/lib/Group.svelte @@ -30,41 +30,98 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Group.html), } from '$lib/util/manageContext'; import { registerEvents } from '$lib/util/events'; import { copyExistingKeys } from '$lib/util/object'; - import { type PropsContainer, type PropsOptionalConfig } from '$lib/util/props'; + import { type PropsContainer, type Props } from '$lib/util/props'; let { children, - config = $bindable({}), staticConfig = false, - ...eventHooks - }: PropsOptionalConfig & PropsContainer = $props(); - - export const handle = new Konva.Group(config); + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps + }: Props & PropsContainer = $props(); + + export const handle = new Konva.Group({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const inner = writable(null); let isReady = $state(false); - $effect(() => { - handle.setAttrs(config); - }); - const parent: Writable = getParentContainer(); onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); inner.set(handle); isReady = true; diff --git a/src/lib/Image.svelte b/src/lib/Image.svelte index 91518f1..31d5362 100644 --- a/src/lib/Image.svelte +++ b/src/lib/Image.svelte @@ -4,7 +4,7 @@ The Image component needs to be placed either inside a svelte-konva Layer or Gro ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Image.html), import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Image(config); + export const handle = new Konva.Image({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Label.svelte b/src/lib/Label.svelte index 9fb64c7..8888cb7 100644 --- a/src/lib/Label.svelte +++ b/src/lib/Label.svelte @@ -35,37 +35,94 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Label.html), let { children, - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props & PropsContainer = $props(); - export const handle = new Konva.Label(config); + export const handle = new Konva.Label({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const inner = writable(null); let isReady = $state(false); - $effect(() => { - handle.setAttrs(config); - }); - const parent: Writable = getParentContainer(); onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); inner.set(handle); isReady = true; diff --git a/src/lib/Layer.svelte b/src/lib/Layer.svelte index f26aef1..43aebd9 100644 --- a/src/lib/Layer.svelte +++ b/src/lib/Layer.svelte @@ -26,42 +26,98 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Layer.html), import { type Writable, writable } from 'svelte/store'; import { Container, getParentStage, setContainerContext } from '$lib/util/manageContext'; import { registerEvents } from '$lib/util/events'; - import { copyExistingKeys } from '$lib/util/object'; - import { type PropsContainer, type PropsOptionalConfig } from '$lib/util/props'; + import { type PropsContainer, type Props } from '$lib/util/props'; let { children, - config = $bindable({}), staticConfig = false, - ...eventHooks - }: PropsOptionalConfig & PropsContainer = $props(); - - export const handle = new Konva.Layer(config); + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps + }: Props & PropsContainer = $props(); + + export const handle = new Konva.Layer({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const inner = writable(null); let isReady = $state(false); - $effect(() => { - handle.setAttrs(config); - }); - let parent: Writable = getParentStage(); onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); inner.set(handle); isReady = true; diff --git a/src/lib/Line.svelte b/src/lib/Line.svelte index c0ea819..40ebe48 100644 --- a/src/lib/Line.svelte +++ b/src/lib/Line.svelte @@ -4,7 +4,7 @@ The Line component needs to be placed either inside a svelte-konva Layer or Grou ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Line.html), import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Line(config); + export const handle = new Konva.Line({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Path.svelte b/src/lib/Path.svelte index 12c8794..a1c32fa 100644 --- a/src/lib/Path.svelte +++ b/src/lib/Path.svelte @@ -4,7 +4,7 @@ The Path component needs to be placed either inside a svelte-konva Layer or Grou ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Path.html), import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Path(config); + export const handle = new Konva.Path({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Rect.svelte b/src/lib/Rect.svelte index bb9721a..d40ee07 100644 --- a/src/lib/Rect.svelte +++ b/src/lib/Rect.svelte @@ -4,7 +4,7 @@ The Rect component needs to be placed either inside a svelte-konva Layer or Grou ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Rect.html), import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Rect(config); + export const handle = new Konva.Rect({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/RegularPolygon.svelte b/src/lib/RegularPolygon.svelte index 9f670b0..2b31297 100644 --- a/src/lib/RegularPolygon.svelte +++ b/src/lib/RegularPolygon.svelte @@ -4,7 +4,7 @@ The RegularPolygon component needs to be placed either inside a svelte-konva Lay ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.RegularPolyg import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.RegularPolygon(config); + export const handle = new Konva.RegularPolygon({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Ring.svelte b/src/lib/Ring.svelte index 0ccb6b5..d3244d9 100644 --- a/src/lib/Ring.svelte +++ b/src/lib/Ring.svelte @@ -4,7 +4,7 @@ The Ring component needs to be placed either inside a svelte-konva Layer or Grou ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Ring.html), import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Ring(config); + export const handle = new Konva.Ring({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Shape.svelte b/src/lib/Shape.svelte index 2a7c46b..7a9aeaa 100644 --- a/src/lib/Shape.svelte +++ b/src/lib/Shape.svelte @@ -4,7 +4,7 @@ The Shape component needs to be placed either inside a svelte-konva Layer or Gro ### Usage: ```tsx - {} }} /> + {}} /> ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Shape.html), import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Shape(config); + export const handle = new Konva.Shape({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Sprite.svelte b/src/lib/Sprite.svelte index 096b714..22ba6d2 100644 --- a/src/lib/Sprite.svelte +++ b/src/lib/Sprite.svelte @@ -4,7 +4,7 @@ The Sprite component needs to be placed either inside a svelte-konva Layer or Gr ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Sprite.html) import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Sprite(config); + export const handle = new Konva.Sprite({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Stage.svelte b/src/lib/Stage.svelte index 23ca148..c261518 100644 --- a/src/lib/Stage.svelte +++ b/src/lib/Stage.svelte @@ -23,12 +23,10 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), import { writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { Container, setContainerContext } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props, type PropsContainer, type PropsStage } from '$lib/util/props'; let { children, - config = $bindable(), staticConfig = false, onclick, ondblclick, @@ -61,6 +59,36 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), ontransformend, ontransformstart, onwheel, + y, + x, + width, + visible, + skewY, + skewX, + scaleY, + scaleX, + scale, + rotation, + preventDefault, + opacity, + offsetY, + offsetX, + offset, + name, + listening, + id, + height, + globalCompositeOperation, + filters, + draggable, + dragDistance, + dragBoundFunc, + clipY, + clipX, + clipWidth, + clipHeight, + clearBeforeDraw, + clipFunc, ...restProps }: Props & PropsContainer & PropsStage = $props(); @@ -75,22 +103,143 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), let isReady = $state(false); - $effect(() => { - if (_handle) _handle.setAttrs(config); - }); - onMount(() => { + console.log(x, y); _handle = new Konva.Stage({ container: stage, - ...config + y, + x, + width, + visible, + skewY, + skewX, + scaleY, + scaleX, + scale, + rotation, + preventDefault, + opacity, + offsetY, + offsetX, + offset, + name, + listening, + id, + height, + globalCompositeOperation, + filters, + draggable, + dragDistance, + dragBoundFunc, + clipY, + clipX, + clipWidth, + clipHeight, + clearBeforeDraw, + clipFunc }); if (!staticConfig) { + const attrs = _handle.getAttrs(); + _handle.on('dragend', () => { - copyExistingKeys(config, _handle!.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } + $effect(() => { + _handle!.setAttr('x', x); + }); + $effect(() => { + _handle!.setAttr('y', y); + }); + $effect(() => { + _handle!.setAttr('width', width); + console.log('stage change width', width); + }); + $effect(() => { + _handle!.setAttr('visible', visible); + }); + $effect(() => { + _handle!.setAttr('skewY', skewY); + }); + $effect(() => { + _handle!.setAttr('skewX', skewX); + }); + $effect(() => { + _handle!.setAttr('scaleY', scaleY); + }); + $effect(() => { + _handle!.setAttr('scaleX', scaleX); + }); + $effect(() => { + _handle!.setAttr('scale', scale); + }); + $effect(() => { + _handle!.setAttr('rotation', rotation); + }); + $effect(() => { + _handle!.setAttr('preventDefault', preventDefault); + }); + $effect(() => { + _handle!.setAttr('opacity', opacity); + }); + $effect(() => { + _handle!.setAttr('offsetY', offsetY); + }); + $effect(() => { + _handle!.setAttr('offsetX', offsetX); + }); + $effect(() => { + _handle!.setAttr('offset', offset); + }); + $effect(() => { + _handle!.setAttr('name', name); + }); + $effect(() => { + _handle!.setAttr('listening', listening); + }); + $effect(() => { + _handle!.setAttr('id', id); + }); + $effect(() => { + _handle!.setAttr('height', height); + }); + $effect(() => { + _handle!.setAttr('globalCompositeOperation', globalCompositeOperation); + }); + $effect(() => { + _handle!.setAttr('filters', filters); + }); + $effect(() => { + _handle!.setAttr('draggable', draggable); + }); + $effect(() => { + _handle!.setAttr('dragDistance', dragDistance); + }); + $effect(() => { + _handle!.setAttr('dragBoundFunc', dragBoundFunc); + }); + $effect(() => { + _handle!.setAttr('clipY', clipY); + }); + $effect(() => { + _handle!.setAttr('clipX', clipX); + }); + $effect(() => { + _handle!.setAttr('clipWidth', clipWidth); + }); + $effect(() => { + _handle!.setAttr('clipHeight', clipHeight); + }); + $effect(() => { + _handle!.setAttr('clearBeforeDraw', clearBeforeDraw); + }); + $effect(() => { + _handle!.setAttr('clipFunc', clipFunc); + }); + registerEvents( { onclick, diff --git a/src/lib/Star.svelte b/src/lib/Star.svelte index b642df6..72c6eb4 100644 --- a/src/lib/Star.svelte +++ b/src/lib/Star.svelte @@ -4,7 +4,7 @@ The Star component needs to be placed either inside a svelte-konva Layer or Grou ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Star.html), import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Star(config); + export const handle = new Konva.Star({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Tag.svelte b/src/lib/Tag.svelte index 550ec9a..17507fa 100644 --- a/src/lib/Tag.svelte +++ b/src/lib/Tag.svelte @@ -4,7 +4,7 @@ The Tag component needs to be placed either inside a svelte-konva Layer or Group ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Tag.html), [ import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Tag(config); + export const handle = new Konva.Tag({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Text.svelte b/src/lib/Text.svelte index 74ad1bf..6f52d31 100644 --- a/src/lib/Text.svelte +++ b/src/lib/Text.svelte @@ -4,7 +4,7 @@ The Text component needs to be placed either inside a svelte-konva Layer or Grou ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Text.html), import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Text(config); + export const handle = new Konva.Text({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/TextPath.svelte b/src/lib/TextPath.svelte index 44c45fe..710409b 100644 --- a/src/lib/TextPath.svelte +++ b/src/lib/TextPath.svelte @@ -4,7 +4,7 @@ The TextPath component needs to be placed either inside a svelte-konva Layer or ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.TextPath.htm import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.TextPath(config); + export const handle = new Konva.TextPath({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Transformer.svelte b/src/lib/Transformer.svelte index 07913f2..a63b523 100644 --- a/src/lib/Transformer.svelte +++ b/src/lib/Transformer.svelte @@ -29,37 +29,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Transformer. import type { Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; - import { type PropsOptionalConfig } from '$lib/util/props'; + import { type Props } from '$lib/util/props'; let { - config = $bindable({}), staticConfig = false, - ...eventHooks - }: PropsOptionalConfig = $props(); + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps + }: Props = $props(); - export const handle = new Konva.Transformer(config); + export const handle = new Konva.Transformer({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/Wedge.svelte b/src/lib/Wedge.svelte index 93e48be..34492fc 100644 --- a/src/lib/Wedge.svelte +++ b/src/lib/Wedge.svelte @@ -4,7 +4,7 @@ The Wedge component needs to be placed either inside a svelte-konva Layer or Gro ### Usage: ```tsx - + ``` ### Static config: @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Wedge.html), import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.Wedge(config); + export const handle = new Konva.Wedge({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { diff --git a/src/lib/util/props.ts b/src/lib/util/props.ts index c87ef46..1456a3e 100644 --- a/src/lib/util/props.ts +++ b/src/lib/util/props.ts @@ -5,17 +5,9 @@ import { type KonvaEventHooks } from '$lib/util/events'; * Shared props type used on all svelte-konva components */ export type Props = { - config: Config; staticConfig?: boolean; -} & KonvaEventHooks; - -/** - * Same as Props but with optional Config - */ -export type PropsOptionalConfig = { - config?: Config; - staticConfig?: boolean; -} & KonvaEventHooks; +} & KonvaEventHooks & + Omit; // rotationDeg is deprecated by Konva /** * Props extension for konva container types which can hold more konva nodes diff --git a/src/routes/ResponsiveStage.svelte b/src/routes/ResponsiveStage.svelte index f4fcc3a..fe3469c 100644 --- a/src/routes/ResponsiveStage.svelte +++ b/src/routes/ResponsiveStage.svelte @@ -22,12 +22,12 @@ const STAGE_BASE_WIDTH = 1000; // Base width of the stage used to calculate the required scale at any container width to make sure that the examples are all appropriately scaled on each window size - let config = { + let config = $state({ width: STAGE_BASE_WIDTH, height: 1000, scaleX: 1, scaleY: 1 - }; + }); function updateStageSize() { if (!container) { @@ -40,6 +40,8 @@ let scale = config.width / STAGE_BASE_WIDTH; config.scaleX = scale; config.scaleY = scale; + + console.log('new width', config.width); } onMount(() => { @@ -51,7 +53,7 @@
+ {/each} {/if} diff --git a/src/routes/examples/connectFour/GameGrid.svelte b/src/routes/examples/connectFour/GameGrid.svelte index 3cf018f..cc746d9 100644 --- a/src/routes/examples/connectFour/GameGrid.svelte +++ b/src/routes/examples/connectFour/GameGrid.svelte @@ -18,12 +18,12 @@ let container: HTMLDivElement; - let stageConfig: Konva.ContainerConfig = { + let stageConfig: Konva.ContainerConfig = $state({ width: GAME_BASE_SIZE, height: GAME_BASE_SIZE, scaleX: $gameScale, scaleY: $gameScale - }; + }); let gameGrid = $state(); let gridImageAvailable = $state(false); @@ -43,6 +43,8 @@ gameScale.set(size / GAME_BASE_SIZE); stageConfig.scaleX = $gameScale; stageConfig.scaleY = $gameScale; + + console.log('change game width', stageConfig.width); } onMount(() => { @@ -57,6 +59,8 @@ adjustScaleAndSize(); }); + + $inspect(stageConfig);
- + {@render children()} - + {#if gridImageAvailable} - + {/if} diff --git a/src/routes/examples/connectFour/Token.svelte b/src/routes/examples/connectFour/Token.svelte index 3c3fe10..972bde2 100644 --- a/src/routes/examples/connectFour/Token.svelte +++ b/src/routes/examples/connectFour/Token.svelte @@ -158,4 +158,10 @@ } - + diff --git a/src/routes/examples/drawing/Drawing.svelte b/src/routes/examples/drawing/Drawing.svelte index 89987bc..0c949d0 100644 --- a/src/routes/examples/drawing/Drawing.svelte +++ b/src/routes/examples/drawing/Drawing.svelte @@ -127,7 +127,7 @@ > {#each strokes as stroke} - + {/each} diff --git a/src/routes/examples/group/Group.svelte b/src/routes/examples/group/Group.svelte index e28f597..7c25aa5 100644 --- a/src/routes/examples/group/Group.svelte +++ b/src/routes/examples/group/Group.svelte @@ -30,9 +30,10 @@ - + {#each configs as _, idx} - + + {/each} diff --git a/src/routes/examples/label/Label.svelte b/src/routes/examples/label/Label.svelte index a508359..18ba8df 100644 --- a/src/routes/examples/label/Label.svelte +++ b/src/routes/examples/label/Label.svelte @@ -74,25 +74,23 @@ {#each circles as config} - + {/each} - diff --git a/src/routes/examples/transform/Transform.svelte b/src/routes/examples/transform/Transform.svelte index 55e2053..cbaec72 100644 --- a/src/routes/examples/transform/Transform.svelte +++ b/src/routes/examples/transform/Transform.svelte @@ -11,6 +11,7 @@ import RegularPolygon from 'svelte-konva/RegularPolygon.svelte'; import Transformer from 'svelte-konva/Transformer.svelte'; import Rect from 'svelte-konva/Rect.svelte'; + import { untrack } from 'svelte'; let stage: Stage | undefined; let layer: Layer | undefined; @@ -158,21 +159,19 @@ bind:stage > - + {#each configs as _, idx} - + {/each} - + - + - + diff --git a/src/templates/svelteKonvaComponent.hbs b/src/templates/svelteKonvaComponent.hbs index 3f25bd0..d535a98 100644 --- a/src/templates/svelteKonvaComponent.hbs +++ b/src/templates/svelteKonvaComponent.hbs @@ -24,37 +24,93 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.{{ component import { type Writable } from 'svelte/store'; import { registerEvents } from '$lib/util/events'; import { getParentContainer, type KonvaParent } from '$lib/util/manageContext'; - import { copyExistingKeys } from '$lib/util/object'; import { type Props } from '$lib/util/props'; let { - config = $bindable(), staticConfig = false, - ...eventHooks + x = $bindable(), + y = $bindable(), + scale = $bindable(), + scaleX = $bindable(), + scaleY = $bindable(), + rotation = $bindable(), + skewX = $bindable(), + skewY = $bindable(), + ...restProps }: Props = $props(); - export const handle = new Konva.{{ componentName }}(config); + export const handle = new Konva.{{ componentName }}({ + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY, + ...restProps + }); const parent: Writable = getParentContainer(); - $effect(() => { - handle.setAttrs(config); - }); - onMount(() => { $parent!.add(handle); if (!staticConfig) { + const attrs = handle.getAttrs(); + handle.on('transformend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; + if (scale !== undefined) scale = attrs.scale; + if (scaleX !== undefined) scaleX = attrs.scaleX; + if (scaleY !== undefined) scaleY = attrs.scaleY; + if (rotation !== undefined) rotation = attrs.rotation; + if (skewX !== undefined) skewX = attrs.skewX; + if (skewY !== undefined) skewY = attrs.skewY; }); handle.on('dragend', () => { - copyExistingKeys(config, handle.getAttrs()); + if (x !== undefined) x = attrs.x; + if (y !== undefined) y = attrs.y; }); } - registerEvents(eventHooks, handle); + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + handle.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) + $effect(() => { + handle.setAttr('x', x); + }); + $effect(() => { + handle.setAttr('y', y); + }); + $effect(() => { + handle.setAttr('scale', scale); + }); + $effect(() => { + handle.setAttr('scaleX', scaleX); + }); + $effect(() => { + handle.setAttr('scaleY', scaleY); + }); + $effect(() => { + handle.setAttr('rotation', rotation); + }); + $effect(() => { + handle.setAttr('skewX', skewX); + }); + $effect(() => { + handle.setAttr('skewY', skewY); + }); + + registerEvents(restProps, handle); }); onDestroy(() => { From 93fafaca7880c23358999ea9cb20f812c9239e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Sat, 27 Jul 2024 18:15:35 +0200 Subject: [PATCH 38/56] Update Svelte, Force runes only in lib --- package-lock.json | 8 ++++---- package.json | 2 +- svelte.config.js | 10 ++++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index ad54d43..0e6814e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,7 +28,7 @@ "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", - "svelte": "5.0.0-next.184", + "svelte": "5.0.0-next.200", "svelte-check": "^3.7.1", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", @@ -7136,9 +7136,9 @@ } }, "node_modules/svelte": { - "version": "5.0.0-next.184", - "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.184.tgz", - "integrity": "sha512-oHWNajXOytt/5s2Ark3o/CP7bHLx+o/QZjTkCtU1dECqSmYyGqrIsoZi0Cx0VBdXAHMqI+1/T70ppaL1cL7LEw==", + "version": "5.0.0-next.200", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-5.0.0-next.200.tgz", + "integrity": "sha512-Tf1cOsl2WTmn/TB7k151OFRdoYTIVtAwVThVPeuI+hymUkNd4esn3ApEPxV9r5loqfItBI0z4+EX1nbH4EeEAg==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.2.1", diff --git a/package.json b/package.json index 4e0bc0e..e211664 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "plop": "^4.0.1", "prettier": "^3.1.1", "prettier-plugin-svelte": "^3.2.3", - "svelte": "5.0.0-next.184", + "svelte": "5.0.0-next.200", "svelte-check": "^3.7.1", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", diff --git a/svelte.config.js b/svelte.config.js index 03a8c99..0720243 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -11,6 +11,12 @@ const config = { }) ], + vitePlugin: { + dynamicCompileOptions({ filename }) { + if (filename.includes('node_modules')) return { runes: false }; // Do not opt-in for runes only mode on deps + } + }, + kit: { adapter: adapter({ pages: 'build', @@ -20,6 +26,10 @@ const config = { alias: { 'svelte-konva': 'src/lib' } + }, + + compilerOptions: { + runes: true } }; From 07c2d57a7b5b8220b04c0c65c699b020012d1810 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Sat, 27 Jul 2024 18:19:43 +0200 Subject: [PATCH 39/56] Fix wrong bindings in group example --- src/routes/examples/group/Group.svelte | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/routes/examples/group/Group.svelte b/src/routes/examples/group/Group.svelte index 7c25aa5..9269aa4 100644 --- a/src/routes/examples/group/Group.svelte +++ b/src/routes/examples/group/Group.svelte @@ -32,8 +32,7 @@ {#each configs as _, idx} - - + {/each} From 9d27277071c9431346e2693d3fa113ccaa0714c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Sat, 27 Jul 2024 18:24:42 +0200 Subject: [PATCH 40/56] Fix wrong bindings and missing state rune in transformer example --- src/routes/examples/transform/Transform.svelte | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/routes/examples/transform/Transform.svelte b/src/routes/examples/transform/Transform.svelte index cbaec72..0385fd4 100644 --- a/src/routes/examples/transform/Transform.svelte +++ b/src/routes/examples/transform/Transform.svelte @@ -11,9 +11,8 @@ import RegularPolygon from 'svelte-konva/RegularPolygon.svelte'; import Transformer from 'svelte-konva/Transformer.svelte'; import Rect from 'svelte-konva/Rect.svelte'; - import { untrack } from 'svelte'; - let stage: Stage | undefined; + let stage: Stage | undefined = $state(); let layer: Layer | undefined; let transformer: Transformer | undefined; let selectionRectangle: Rect | undefined; @@ -161,7 +160,7 @@ {#each configs as _, idx} - + {/each} From ec4366820f58997accdb3a4499f7e0c175ccc8f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Sat, 27 Jul 2024 19:11:12 +0200 Subject: [PATCH 41/56] Fix most tests to use split config props --- plopfile.js | 28 +++--- src/templates/svelteKonvaComponentTests.hbs | 50 ++++------ src/tests/arc.test.ts | 54 +++++----- src/tests/arrow.test.ts | 54 +++++----- src/tests/circle.test.ts | 54 +++++----- src/tests/ellipse.test.ts | 54 +++++----- src/tests/group.test.ts | 4 +- src/tests/image.test.ts | 28 ++---- src/tests/label.test.ts | 23 +---- src/tests/layer.test.ts | 4 +- src/tests/line.test.ts | 54 +++++----- src/tests/path.test.ts | 54 +++++----- src/tests/rect.test.ts | 54 +++++----- src/tests/regularpolygon.test.ts | 54 +++++----- src/tests/ring.test.ts | 54 +++++----- src/tests/shape.test.ts | 98 ++++++++----------- src/tests/sprite.test.ts | 86 +++++++--------- src/tests/stage.test.ts | 36 ++++--- src/tests/star.test.ts | 54 +++++----- src/tests/tag.test.ts | 54 +++++----- src/tests/text.test.ts | 54 +++++----- src/tests/textpath.test.ts | 54 +++++----- src/tests/wedge.test.ts | 54 +++++----- src/tests/wrappers/ConfigBinding.test.svelte | 29 +++++- .../wrappers/ContainerContext.test.svelte | 8 +- 25 files changed, 502 insertions(+), 648 deletions(-) diff --git a/plopfile.js b/plopfile.js index f5070ef..a6ead0e 100644 --- a/plopfile.js +++ b/plopfile.js @@ -3,27 +3,27 @@ const COMPONENT_LIST = [ { componentName: 'Circle', example: '', - testConfig: '{ x: 0, radius: 100 }' + testConfig: '{ x: 0, y: 0, radius: 100 }' }, { componentName: 'Rect', example: '', - testConfig: '{ x: 0, width: 100, height: 100 }' + testConfig: '{ x: 0, y: 0, width: 100, height: 100 }' }, { componentName: 'Ellipse', example: '', - testConfig: '{ x: 0, radiusX: 120, radiusY: 70 }' + testConfig: '{ x: 0, y: 0, radiusX: 120, radiusY: 70 }' }, { componentName: 'Wedge', example: '', - testConfig: '{ x: 0, radius: 100, angle: 300 }' + testConfig: '{ x: 0, y: 0, radius: 100, angle: 300 }' }, { componentName: 'Line', example: '', - testConfig: "{ x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }" + testConfig: "{ x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }" }, { componentName: 'Sprite', @@ -37,45 +37,45 @@ const COMPONENT_LIST = [ { componentName: 'Text', example: '', - testConfig: "{ x: 0, fontSize: 100, text: 'some text', fill: 'black' }" + testConfig: "{ x: 0, y: 0, fontSize: 100, text: 'some text', fill: 'black' }" }, { componentName: 'TextPath', example: '', - testConfig: "{ x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' }" + testConfig: "{ x: 0, y: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' }" }, { componentName: 'Star', example: '', - testConfig: '{ x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 }' + testConfig: '{ x: 0, y: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 }' }, { componentName: 'Ring', example: '', - testConfig: '{ x: 0, innerRadius: 20, outerRadius: 100 }' + testConfig: '{ x: 0, y: 0, innerRadius: 20, outerRadius: 100 }' }, { componentName: 'Arc', example: '', - testConfig: '{ x: 0, innerRadius: 20, outerRadius: 100, angle: 300 }' + testConfig: '{ x: 0, y: 0, innerRadius: 20, outerRadius: 100, angle: 300 }' }, { componentName: 'Path', example: '', - testConfig: "{ x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' }" + testConfig: "{ x: 0, y: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' }" }, { componentName: 'RegularPolygon', example: '', - testConfig: '{ x: 0, sides: 7, radius: 80 }' + testConfig: '{ x: 0, y: 0, sides: 7, radius: 80 }' }, { componentName: 'Arrow', example: '', - testConfig: "{ x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }" + testConfig: "{ x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }" }, { componentName: 'Shape', @@ -85,7 +85,7 @@ const COMPONENT_LIST = [ componentName: 'Tag', example: '', - testConfig: "{ x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 }" + testConfig: "{ x: 0, y: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 }" } ]; diff --git a/src/templates/svelteKonvaComponentTests.hbs b/src/templates/svelteKonvaComponentTests.hbs index bdf80d9..66f4f7a 100644 --- a/src/templates/svelteKonvaComponentTests.hbs +++ b/src/templates/svelteKonvaComponentTests.hbs @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render({{ componentName }}, { - props: { - config: {{{ testConfig }}} - } + props: {{{ testConfig }}} }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render({{ componentName }}, { context: createMockParentContext(Container.Stage, div), - props: { - config: {{{ testConfig }}} - } + props: {{{ testConfig }}} }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render({{ componentName }}, { context: mockContext, - props: { - config: {{{ testConfig }}} - } + props: {{{ testConfig }}} }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render({{ componentName }}, { context: mockContext, - props: { - config: {{{ testConfig }}} - } + props: {{{ testConfig }}} }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render({{ componentName }}, { context: mockContext, - props: { - config: {{{ testConfig }}} - } + props:{{{ testConfig }}} }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render({{ componentName }}, { context: createMockParentContext(Container.Layer), props: { - config: {{{ testConfig }}}, + ...{{{ testConfig }}}, onmousedown: mockFn } }); @@ -123,14 +113,17 @@ test('Can listen to Konva events', () => { test('Correctly updates bound config on dragend', () => { const rawConfig = {{{ testConfig }}}; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.{{ componentName }} | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: {{ componentName }}, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { const rawConfig = {{{ testConfig }}}; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.{{ componentName }} | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: {{ componentName }}, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render({{ componentName }}, { context: mockContext, - props: { - config: {{{ testConfig }}} - } + props: {{{ testConfig }}} }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/arc.test.ts b/src/tests/arc.test.ts index 42ab7c7..d18c851 100644 --- a/src/tests/arc.test.ts +++ b/src/tests/arc.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Arc, { - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 } - } + props: { x: 0, y: 0, innerRadius: 20, outerRadius: 100, angle: 300 } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Arc, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 } - } + props: { x: 0, y: 0, innerRadius: 20, outerRadius: 100, angle: 300 } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Arc, { context: mockContext, - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 } - } + props: { x: 0, y: 0, innerRadius: 20, outerRadius: 100, angle: 300 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Arc, { context: mockContext, - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 } - } + props: { x: 0, y: 0, innerRadius: 20, outerRadius: 100, angle: 300 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Arc, { context: mockContext, - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 } - } + props: { x: 0, y: 0, innerRadius: 20, outerRadius: 100, angle: 300 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(Arc, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 }, + ...{ x: 0, y: 0, innerRadius: 20, outerRadius: 100, angle: 300 }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 }; + const rawConfig = { x: 0, y: 0, innerRadius: 20, outerRadius: 100, angle: 300 }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Arc | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Arc, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 }; + const rawConfig = { x: 0, y: 0, innerRadius: 20, outerRadius: 100, angle: 300 }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Arc | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Arc, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Arc, { context: mockContext, - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100, angle: 300 } - } + props: { x: 0, y: 0, innerRadius: 20, outerRadius: 100, angle: 300 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/arrow.test.ts b/src/tests/arrow.test.ts index 67fcf94..638ace7 100644 --- a/src/tests/arrow.test.ts +++ b/src/tests/arrow.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Arrow, { - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } + props: { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Arrow, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } + props: { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Arrow, { context: mockContext, - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } + props: { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Arrow, { context: mockContext, - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } + props: { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Arrow, { context: mockContext, - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } + props: { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(Arrow, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }, + ...{ x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }; + const rawConfig = { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Arrow | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Arrow, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }; + const rawConfig = { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Arrow | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Arrow, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Arrow, { context: mockContext, - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } + props: { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/circle.test.ts b/src/tests/circle.test.ts index 974766e..1e9f72a 100644 --- a/src/tests/circle.test.ts +++ b/src/tests/circle.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Circle, { - props: { - config: { x: 0, radius: 100 } - } + props: { x: 0, y: 0, radius: 100 } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Circle, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, radius: 100 } - } + props: { x: 0, y: 0, radius: 100 } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Circle, { context: mockContext, - props: { - config: { x: 0, radius: 100 } - } + props: { x: 0, y: 0, radius: 100 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Circle, { context: mockContext, - props: { - config: { x: 0, radius: 100 } - } + props: { x: 0, y: 0, radius: 100 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Circle, { context: mockContext, - props: { - config: { x: 0, radius: 100 } - } + props: { x: 0, y: 0, radius: 100 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(Circle, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, radius: 100 }, + ...{ x: 0, y: 0, radius: 100 }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, radius: 100 }; + const rawConfig = { x: 0, y: 0, radius: 100 }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Circle | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Circle, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, radius: 100 }; + const rawConfig = { x: 0, y: 0, radius: 100 }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Circle | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Circle, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Circle, { context: mockContext, - props: { - config: { x: 0, radius: 100 } - } + props: { x: 0, y: 0, radius: 100 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/ellipse.test.ts b/src/tests/ellipse.test.ts index fd2bb09..9e1080e 100644 --- a/src/tests/ellipse.test.ts +++ b/src/tests/ellipse.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Ellipse, { - props: { - config: { x: 0, radiusX: 120, radiusY: 70 } - } + props: { x: 0, y: 0, radiusX: 120, radiusY: 70 } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Ellipse, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, radiusX: 120, radiusY: 70 } - } + props: { x: 0, y: 0, radiusX: 120, radiusY: 70 } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Ellipse, { context: mockContext, - props: { - config: { x: 0, radiusX: 120, radiusY: 70 } - } + props: { x: 0, y: 0, radiusX: 120, radiusY: 70 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Ellipse, { context: mockContext, - props: { - config: { x: 0, radiusX: 120, radiusY: 70 } - } + props: { x: 0, y: 0, radiusX: 120, radiusY: 70 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Ellipse, { context: mockContext, - props: { - config: { x: 0, radiusX: 120, radiusY: 70 } - } + props: { x: 0, y: 0, radiusX: 120, radiusY: 70 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(Ellipse, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, radiusX: 120, radiusY: 70 }, + ...{ x: 0, y: 0, radiusX: 120, radiusY: 70 }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, radiusX: 120, radiusY: 70 }; + const rawConfig = { x: 0, y: 0, radiusX: 120, radiusY: 70 }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Ellipse | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Ellipse, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, radiusX: 120, radiusY: 70 }; + const rawConfig = { x: 0, y: 0, radiusX: 120, radiusY: 70 }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Ellipse | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Ellipse, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Ellipse, { context: mockContext, - props: { - config: { x: 0, radiusX: 120, radiusY: 70 } - } + props: { x: 0, y: 0, radiusX: 120, radiusY: 70 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/group.test.ts b/src/tests/group.test.ts index 266d725..35f2cc2 100644 --- a/src/tests/group.test.ts +++ b/src/tests/group.test.ts @@ -32,9 +32,7 @@ test('passes the config prop', () => { const rendered = render(Group, { context: createMockParentContext(Container.Layer), - props: { - config: CONFIG - } + props: CONFIG }); const handle = rendered.component.handle; diff --git a/src/tests/image.test.ts b/src/tests/image.test.ts index 6a92b7d..bd3ff50 100644 --- a/src/tests/image.test.ts +++ b/src/tests/image.test.ts @@ -26,9 +26,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(KonvaImage, { props: { - config: { - image: testImage - } + image: testImage } }); }).toThrow(CONTAINER_ERROR); @@ -38,9 +36,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com render(KonvaImage, { context: createMockParentContext(Container.Stage, div), props: { - config: { - image: testImage - } + image: testImage } }); }).toThrow(CONTAINER_ERROR); @@ -53,9 +49,7 @@ test('is correctly added to the parent Layer', async () => { const rendered = render(KonvaImage, { context: mockContext, props: { - config: { - image: testImage - } + image: testImage } }); @@ -77,9 +71,7 @@ test('is correctly added to the parent Group', async () => { const rendered = render(KonvaImage, { context: mockContext, props: { - config: { - image: testImage - } + image: testImage } }); @@ -101,9 +93,7 @@ test('is correctly added to the parent Label', async () => { const rendered = render(KonvaImage, { context: mockContext, props: { - config: { - image: testImage - } + image: testImage } }); @@ -125,9 +115,7 @@ test('Can listen to Konva events', async () => { const rendered = render(KonvaImage, { context: createMockParentContext(Container.Layer), props: { - config: { - image: testImage - }, + image: testImage, onmousedown: mockFn } }); @@ -221,9 +209,7 @@ test('Konva instance is correctly destroyed on component unmount', async () => { const rendered = render(KonvaImage, { context: mockContext, props: { - config: { - image: testImage - } + image: testImage } }); diff --git a/src/tests/label.test.ts b/src/tests/label.test.ts index 2aae94b..3638140 100644 --- a/src/tests/label.test.ts +++ b/src/tests/label.test.ts @@ -19,9 +19,7 @@ import ContainerContext from './wrappers/ContainerContext.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Label, { - props: { - config: {} - } + props: {} }); }).toThrow(CONTAINER_ERROR); @@ -40,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Label, { context: mockContext, - props: { - config: {} - } + props: {} }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -60,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Label, { context: mockContext, - props: { - config: {} - } + props: {} }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -80,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Label, { context: mockContext, - props: { - config: {} - } + props: {} }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -101,7 +93,6 @@ test('Can listen to Konva events', () => { const rendered = render(Label, { context: createMockParentContext(Container.Layer), props: { - config: {}, onmousedown: mockFn } }); @@ -221,9 +212,7 @@ test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Label, { context: mockContext, - props: { - config: {} - } + props: {} }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -236,8 +225,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/layer.test.ts b/src/tests/layer.test.ts index 572c622..b93f0c3 100644 --- a/src/tests/layer.test.ts +++ b/src/tests/layer.test.ts @@ -40,9 +40,7 @@ test('passes the config prop', () => { const div = document.createElement('div'); const rendered = render(Layer, { context: createMockParentContext(Container.Stage, div), - props: { - config: CONFIG - } + props: CONFIG }); const handle = rendered.component.handle; diff --git a/src/tests/line.test.ts b/src/tests/line.test.ts index 987980d..b3468cd 100644 --- a/src/tests/line.test.ts +++ b/src/tests/line.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Line, { - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } + props: { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Line, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } + props: { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Line, { context: mockContext, - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } + props: { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Line, { context: mockContext, - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } + props: { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Line, { context: mockContext, - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } + props: { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(Line, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }, + ...{ x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }; + const rawConfig = { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Line | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Line, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }; + const rawConfig = { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Line | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Line, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Line, { context: mockContext, - props: { - config: { x: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } - } + props: { x: 0, y: 0, points: [0, 0, 100, 100], strokeWidth: 10, stroke: 'black' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/path.test.ts b/src/tests/path.test.ts index 391de0f..7b7ccd2 100644 --- a/src/tests/path.test.ts +++ b/src/tests/path.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Path, { - props: { - config: { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } - } + props: { x: 0, y: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Path, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } - } + props: { x: 0, y: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Path, { context: mockContext, - props: { - config: { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } - } + props: { x: 0, y: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Path, { context: mockContext, - props: { - config: { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } - } + props: { x: 0, y: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Path, { context: mockContext, - props: { - config: { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } - } + props: { x: 0, y: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(Path, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' }, + ...{ x: 0, y: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' }; + const rawConfig = { x: 0, y: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Path | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Path, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' }; + const rawConfig = { x: 0, y: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Path | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Path, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Path, { context: mockContext, - props: { - config: { x: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } - } + props: { x: 0, y: 0, data: 'M 2 2 H 100 V 60 H 2 V 2 Z' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/rect.test.ts b/src/tests/rect.test.ts index d852e1a..5d498ad 100644 --- a/src/tests/rect.test.ts +++ b/src/tests/rect.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Rect, { - props: { - config: { x: 0, width: 100, height: 100 } - } + props: { x: 0, y: 0, width: 100, height: 100 } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Rect, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, width: 100, height: 100 } - } + props: { x: 0, y: 0, width: 100, height: 100 } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Rect, { context: mockContext, - props: { - config: { x: 0, width: 100, height: 100 } - } + props: { x: 0, y: 0, width: 100, height: 100 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Rect, { context: mockContext, - props: { - config: { x: 0, width: 100, height: 100 } - } + props: { x: 0, y: 0, width: 100, height: 100 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Rect, { context: mockContext, - props: { - config: { x: 0, width: 100, height: 100 } - } + props: { x: 0, y: 0, width: 100, height: 100 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(Rect, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, width: 100, height: 100 }, + ...{ x: 0, y: 0, width: 100, height: 100 }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, width: 100, height: 100 }; + const rawConfig = { x: 0, y: 0, width: 100, height: 100 }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Rect | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Rect, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, width: 100, height: 100 }; + const rawConfig = { x: 0, y: 0, width: 100, height: 100 }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Rect | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Rect, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Rect, { context: mockContext, - props: { - config: { x: 0, width: 100, height: 100 } - } + props: { x: 0, y: 0, width: 100, height: 100 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/regularpolygon.test.ts b/src/tests/regularpolygon.test.ts index cc0f5f7..dcdfa1b 100644 --- a/src/tests/regularpolygon.test.ts +++ b/src/tests/regularpolygon.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(RegularPolygon, { - props: { - config: { x: 0, sides: 7, radius: 80 } - } + props: { x: 0, y: 0, sides: 7, radius: 80 } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(RegularPolygon, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, sides: 7, radius: 80 } - } + props: { x: 0, y: 0, sides: 7, radius: 80 } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(RegularPolygon, { context: mockContext, - props: { - config: { x: 0, sides: 7, radius: 80 } - } + props: { x: 0, y: 0, sides: 7, radius: 80 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(RegularPolygon, { context: mockContext, - props: { - config: { x: 0, sides: 7, radius: 80 } - } + props: { x: 0, y: 0, sides: 7, radius: 80 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(RegularPolygon, { context: mockContext, - props: { - config: { x: 0, sides: 7, radius: 80 } - } + props: { x: 0, y: 0, sides: 7, radius: 80 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(RegularPolygon, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, sides: 7, radius: 80 }, + ...{ x: 0, y: 0, sides: 7, radius: 80 }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, sides: 7, radius: 80 }; + const rawConfig = { x: 0, y: 0, sides: 7, radius: 80 }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.RegularPolygon | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: RegularPolygon, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, sides: 7, radius: 80 }; + const rawConfig = { x: 0, y: 0, sides: 7, radius: 80 }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.RegularPolygon | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: RegularPolygon, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(RegularPolygon, { context: mockContext, - props: { - config: { x: 0, sides: 7, radius: 80 } - } + props: { x: 0, y: 0, sides: 7, radius: 80 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/ring.test.ts b/src/tests/ring.test.ts index b567c6b..4124bb4 100644 --- a/src/tests/ring.test.ts +++ b/src/tests/ring.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Ring, { - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100 } - } + props: { x: 0, y: 0, innerRadius: 20, outerRadius: 100 } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Ring, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100 } - } + props: { x: 0, y: 0, innerRadius: 20, outerRadius: 100 } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Ring, { context: mockContext, - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100 } - } + props: { x: 0, y: 0, innerRadius: 20, outerRadius: 100 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Ring, { context: mockContext, - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100 } - } + props: { x: 0, y: 0, innerRadius: 20, outerRadius: 100 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Ring, { context: mockContext, - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100 } - } + props: { x: 0, y: 0, innerRadius: 20, outerRadius: 100 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(Ring, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, innerRadius: 20, outerRadius: 100 }, + ...{ x: 0, y: 0, innerRadius: 20, outerRadius: 100 }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, innerRadius: 20, outerRadius: 100 }; + const rawConfig = { x: 0, y: 0, innerRadius: 20, outerRadius: 100 }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Ring | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Ring, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, innerRadius: 20, outerRadius: 100 }; + const rawConfig = { x: 0, y: 0, innerRadius: 20, outerRadius: 100 }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Ring | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Ring, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Ring, { context: mockContext, - props: { - config: { x: 0, innerRadius: 20, outerRadius: 100 } - } + props: { x: 0, y: 0, innerRadius: 20, outerRadius: 100 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/shape.test.ts b/src/tests/shape.test.ts index a8e3d1b..b757cee 100644 --- a/src/tests/shape.test.ts +++ b/src/tests/shape.test.ts @@ -19,14 +19,12 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Shape, { props: { - config: { - width: 100, - height: 100, - sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { - context.beginPath(); - context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); - context.fillStrokeShape(shape); - } + width: 100, + height: 100, + sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { + context.beginPath(); + context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); + context.fillStrokeShape(shape); } } }); @@ -37,14 +35,12 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com render(Shape, { context: createMockParentContext(Container.Stage, div), props: { - config: { - width: 100, - height: 100, - sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { - context.beginPath(); - context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); - context.fillStrokeShape(shape); - } + width: 100, + height: 100, + sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { + context.beginPath(); + context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); + context.fillStrokeShape(shape); } } }); @@ -56,14 +52,12 @@ test('is correctly added to the parent Layer', () => { const rendered = render(Shape, { context: mockContext, props: { - config: { - width: 100, - height: 100, - sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { - context.beginPath(); - context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); - context.fillStrokeShape(shape); - } + width: 100, + height: 100, + sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { + context.beginPath(); + context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); + context.fillStrokeShape(shape); } } }); @@ -84,14 +78,12 @@ test('is correctly added to the parent Group', () => { const rendered = render(Shape, { context: mockContext, props: { - config: { - width: 100, - height: 100, - sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { - context.beginPath(); - context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); - context.fillStrokeShape(shape); - } + width: 100, + height: 100, + sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { + context.beginPath(); + context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); + context.fillStrokeShape(shape); } } }); @@ -112,14 +104,12 @@ test('is correctly added to the parent Label', () => { const rendered = render(Shape, { context: mockContext, props: { - config: { - width: 100, - height: 100, - sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { - context.beginPath(); - context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); - context.fillStrokeShape(shape); - } + width: 100, + height: 100, + sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { + context.beginPath(); + context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); + context.fillStrokeShape(shape); } } }); @@ -140,14 +130,12 @@ test('Can listen to Konva events', () => { const rendered = render(Shape, { context: createMockParentContext(Container.Layer), props: { - config: { - width: 100, - height: 100, - sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { - context.beginPath(); - context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); - context.fillStrokeShape(shape); - } + width: 100, + height: 100, + sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { + context.beginPath(); + context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); + context.fillStrokeShape(shape); }, onmousedown: mockFn } @@ -248,14 +236,12 @@ test('Konva instance is correctly destroyed on component unmount', () => { const rendered = render(Shape, { context: mockContext, props: { - config: { - width: 100, - height: 100, - sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { - context.beginPath(); - context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); - context.fillStrokeShape(shape); - } + width: 100, + height: 100, + sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { + context.beginPath(); + context.rect(0, 0, shape.getAttr('width'), shape.getAttr('height')); + context.fillStrokeShape(shape); } } }); diff --git a/src/tests/sprite.test.ts b/src/tests/sprite.test.ts index 2caedde..eb9466b 100644 --- a/src/tests/sprite.test.ts +++ b/src/tests/sprite.test.ts @@ -26,13 +26,11 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Sprite, { props: { - config: { - image: spriteImage, - animation: 'default', - animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, - frameRate: 7, - frameIndex: 0 - } + image: spriteImage, + animation: 'default', + animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, + frameRate: 7, + frameIndex: 0 } }); }).toThrow(CONTAINER_ERROR); @@ -42,13 +40,11 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com render(Sprite, { context: createMockParentContext(Container.Stage, div), props: { - config: { - image: spriteImage, - animation: 'default', - animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, - frameRate: 7, - frameIndex: 0 - } + image: spriteImage, + animation: 'default', + animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, + frameRate: 7, + frameIndex: 0 } }); }).toThrow(CONTAINER_ERROR); @@ -61,13 +57,11 @@ test('is correctly added to the parent Layer', async () => { const rendered = render(Sprite, { context: mockContext, props: { - config: { - image: spriteImage, - animation: 'default', - animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, - frameRate: 7, - frameIndex: 0 - } + image: spriteImage, + animation: 'default', + animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, + frameRate: 7, + frameIndex: 0 } }); @@ -89,13 +83,11 @@ test('is correctly added to the parent Group', async () => { const rendered = render(Sprite, { context: mockContext, props: { - config: { - image: spriteImage, - animation: 'default', - animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, - frameRate: 7, - frameIndex: 0 - } + image: spriteImage, + animation: 'default', + animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, + frameRate: 7, + frameIndex: 0 } }); @@ -117,13 +109,11 @@ test('is correctly added to the parent Label', async () => { const rendered = render(Sprite, { context: mockContext, props: { - config: { - image: spriteImage, - animation: 'default', - animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, - frameRate: 7, - frameIndex: 0 - } + image: spriteImage, + animation: 'default', + animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, + frameRate: 7, + frameIndex: 0 } }); @@ -145,13 +135,11 @@ test('Can listen to Konva events', async () => { const rendered = render(Sprite, { context: createMockParentContext(Container.Layer), props: { - config: { - image: spriteImage, - animation: 'default', - animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, - frameRate: 7, - frameIndex: 0 - }, + image: spriteImage, + animation: 'default', + animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, + frameRate: 7, + frameIndex: 0, onmousedown: mockFn } }); @@ -253,13 +241,11 @@ test('Konva instance is correctly destroyed on component unmount', async () => { const rendered = render(Sprite, { context: mockContext, props: { - config: { - image: spriteImage, - animation: 'default', - animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, - frameRate: 7, - frameIndex: 0 - } + image: spriteImage, + animation: 'default', + animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, + frameRate: 7, + frameIndex: 0 } }); @@ -273,8 +259,6 @@ test('Konva instance is correctly destroyed on component unmount', async () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/stage.test.ts b/src/tests/stage.test.ts index 000cae0..39f86a0 100644 --- a/src/tests/stage.test.ts +++ b/src/tests/stage.test.ts @@ -17,9 +17,12 @@ import ContainerContext from './wrappers/ContainerContext.test.svelte'; test('creates a div container and forwards rest props to div', () => { const rendered = render(Stage, { - config: { width: 1000, height: 1000 }, - id: 'container', - restProp: false + props: { + width: 1000, + height: 1000, + id: 'container', + restProp: false + } }); const div = rendered.container.querySelector('#container'); @@ -32,8 +35,11 @@ test('creates a div container and forwards rest props to div', () => { test('creates a Konva canvas instance inside of the div', () => { const rendered = render(Stage, { - config: { width: 1000, height: 1000 }, - id: 'container' + props: { + width: 1000, + height: 1000, + id: 'container' + } }); const div = rendered.container.querySelector('#container'); @@ -53,8 +59,10 @@ test('creates a konva stage instance and passes config prop', () => { const CONFIG = { width: 1000, height: 1000 }; const rendered = render(Stage, { - config: CONFIG, - id: 'container' + props: { + ...CONFIG, + id: 'container' + } }); const handle = rendered.component.handle(); @@ -70,7 +78,8 @@ test('Can listen to Konva events', () => { const mockFn = vi.fn(); const rendered = render(Stage, { - config: { width: 1000, height: 1000 }, + width: 1000, + height: 1000, onmousedown: mockFn }); @@ -134,7 +143,8 @@ test('sets the correct context', () => { render(ContainerContext, { props: { component: Stage, - config: { width: 1000, height: 1000 }, + width: 1000, + height: 1000, getHandle: (hnd) => (handle = hnd()), getComponentContext: (ctxMap) => (childContext = ctxMap) } @@ -149,7 +159,8 @@ test('nulls unused context', () => { render(ContainerContext, { props: { component: Stage, - config: { width: 1000, height: 1000 }, + width: 1000, + height: 1000, getComponentContext: (ctxMap) => (childContext = ctxMap) } }); @@ -167,7 +178,10 @@ test('Konva instance is correctly destroyed on component unmount', () => { const previousStageCount = Konva.stages.length; const rendered = render(Stage, { - config: { width: 1000, height: 1000 } + props: { + width: 1000, + height: 1000 + } }); expect(Konva.stages.length).toBe(previousStageCount + 1); diff --git a/src/tests/star.test.ts b/src/tests/star.test.ts index f0b3a55..d1e0e1d 100644 --- a/src/tests/star.test.ts +++ b/src/tests/star.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Star, { - props: { - config: { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } - } + props: { x: 0, y: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Star, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } - } + props: { x: 0, y: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Star, { context: mockContext, - props: { - config: { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } - } + props: { x: 0, y: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Star, { context: mockContext, - props: { - config: { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } - } + props: { x: 0, y: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Star, { context: mockContext, - props: { - config: { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } - } + props: { x: 0, y: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(Star, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 }, + ...{ x: 0, y: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 }; + const rawConfig = { x: 0, y: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Star | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Star, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 }; + const rawConfig = { x: 0, y: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Star | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Star, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Star, { context: mockContext, - props: { - config: { x: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } - } + props: { x: 0, y: 0, innerRadius: 100, outerRadius: 200, numPoints: 5 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/tag.test.ts b/src/tests/tag.test.ts index 50b9590..7168115 100644 --- a/src/tests/tag.test.ts +++ b/src/tests/tag.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Tag, { - props: { - config: { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } - } + props: { x: 0, y: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Tag, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } - } + props: { x: 0, y: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Tag, { context: mockContext, - props: { - config: { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } - } + props: { x: 0, y: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Tag, { context: mockContext, - props: { - config: { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } - } + props: { x: 0, y: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Tag, { context: mockContext, - props: { - config: { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } - } + props: { x: 0, y: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(Tag, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 }, + ...{ x: 0, y: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 }; + const rawConfig = { x: 0, y: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Tag | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Tag, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 }; + const rawConfig = { x: 0, y: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Tag | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Tag, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Tag, { context: mockContext, - props: { - config: { x: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } - } + props: { x: 0, y: 0, pointerDirection: 'down', pointerWidth: 500, pointerHeight: 200 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/text.test.ts b/src/tests/text.test.ts index dc0ece5..b4aa6d7 100644 --- a/src/tests/text.test.ts +++ b/src/tests/text.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Text, { - props: { - config: { x: 0, fontSize: 100, text: 'some text', fill: 'black' } - } + props: { x: 0, y: 0, fontSize: 100, text: 'some text', fill: 'black' } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Text, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, fontSize: 100, text: 'some text', fill: 'black' } - } + props: { x: 0, y: 0, fontSize: 100, text: 'some text', fill: 'black' } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Text, { context: mockContext, - props: { - config: { x: 0, fontSize: 100, text: 'some text', fill: 'black' } - } + props: { x: 0, y: 0, fontSize: 100, text: 'some text', fill: 'black' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Text, { context: mockContext, - props: { - config: { x: 0, fontSize: 100, text: 'some text', fill: 'black' } - } + props: { x: 0, y: 0, fontSize: 100, text: 'some text', fill: 'black' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Text, { context: mockContext, - props: { - config: { x: 0, fontSize: 100, text: 'some text', fill: 'black' } - } + props: { x: 0, y: 0, fontSize: 100, text: 'some text', fill: 'black' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(Text, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, fontSize: 100, text: 'some text', fill: 'black' }, + ...{ x: 0, y: 0, fontSize: 100, text: 'some text', fill: 'black' }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, fontSize: 100, text: 'some text', fill: 'black' }; + const rawConfig = { x: 0, y: 0, fontSize: 100, text: 'some text', fill: 'black' }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Text | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Text, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, fontSize: 100, text: 'some text', fill: 'black' }; + const rawConfig = { x: 0, y: 0, fontSize: 100, text: 'some text', fill: 'black' }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Text | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Text, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Text, { context: mockContext, - props: { - config: { x: 0, fontSize: 100, text: 'some text', fill: 'black' } - } + props: { x: 0, y: 0, fontSize: 100, text: 'some text', fill: 'black' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/textpath.test.ts b/src/tests/textpath.test.ts index 5b8bb74..f7ac9fe 100644 --- a/src/tests/textpath.test.ts +++ b/src/tests/textpath.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(TextPath, { - props: { - config: { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } - } + props: { x: 0, y: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(TextPath, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } - } + props: { x: 0, y: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(TextPath, { context: mockContext, - props: { - config: { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } - } + props: { x: 0, y: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(TextPath, { context: mockContext, - props: { - config: { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } - } + props: { x: 0, y: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(TextPath, { context: mockContext, - props: { - config: { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } - } + props: { x: 0, y: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(TextPath, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' }, + ...{ x: 0, y: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' }; + const rawConfig = { x: 0, y: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.TextPath | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: TextPath, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' }; + const rawConfig = { x: 0, y: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.TextPath | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: TextPath, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(TextPath, { context: mockContext, - props: { - config: { x: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } - } + props: { x: 0, y: 0, fontSize: 100, text: 'some text', data: 'M 1 60 H 168 Z' } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/wedge.test.ts b/src/tests/wedge.test.ts index a7b51de..4fe70d8 100644 --- a/src/tests/wedge.test.ts +++ b/src/tests/wedge.test.ts @@ -21,9 +21,7 @@ import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; test('throws an error if not placed inside a Container (Layer, Group, Label) component', () => { expect(() => { render(Wedge, { - props: { - config: { x: 0, radius: 100, angle: 300 } - } + props: { x: 0, y: 0, radius: 100, angle: 300 } }); }).toThrow(CONTAINER_ERROR); @@ -31,9 +29,7 @@ test('throws an error if not placed inside a Container (Layer, Group, Label) com expect(() => { render(Wedge, { context: createMockParentContext(Container.Stage, div), - props: { - config: { x: 0, radius: 100, angle: 300 } - } + props: { x: 0, y: 0, radius: 100, angle: 300 } }); }).toThrow(CONTAINER_ERROR); }); @@ -42,9 +38,7 @@ test('is correctly added to the parent Layer', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Wedge, { context: mockContext, - props: { - config: { x: 0, radius: 100, angle: 300 } - } + props: { x: 0, y: 0, radius: 100, angle: 300 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); @@ -62,9 +56,7 @@ test('is correctly added to the parent Group', () => { const mockContext = createMockParentContext(Container.Group); const rendered = render(Wedge, { context: mockContext, - props: { - config: { x: 0, radius: 100, angle: 300 } - } + props: { x: 0, y: 0, radius: 100, angle: 300 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Group])!); @@ -82,9 +74,7 @@ test('is correctly added to the parent Label', () => { const mockContext = createMockParentContext(Container.Label); const rendered = render(Wedge, { context: mockContext, - props: { - config: { x: 0, radius: 100, angle: 300 } - } + props: { x: 0, y: 0, radius: 100, angle: 300 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Label])!); @@ -103,7 +93,7 @@ test('Can listen to Konva events', () => { const rendered = render(Wedge, { context: createMockParentContext(Container.Layer), props: { - config: { x: 0, radius: 100, angle: 300 }, + ...{ x: 0, y: 0, radius: 100, angle: 300 }, onmousedown: mockFn } }); @@ -121,16 +111,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const rawConfig = { x: 0, radius: 100, angle: 300 }; + const rawConfig = { x: 0, y: 0, radius: 100, angle: 300 }; const CONFIG = { ...rawConfig, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Wedge | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Wedge, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -144,23 +137,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const rawConfig = { x: 0, radius: 100, angle: 300 }; + const rawConfig = { x: 0, y: 0, radius: 100, angle: 300 }; const CONFIG = { ...rawConfig, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Wedge | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Wedge, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -175,18 +170,15 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { const mockContext = createMockParentContext(Container.Layer); const rendered = render(Wedge, { context: mockContext, - props: { - config: { x: 0, radius: 100, angle: 300 } - } + props: { x: 0, y: 0, radius: 100, angle: 300 } }); const parent: Konva.Container = get(mockContext.get(CONTAINER_COMPONENT_KEYS[Container.Layer])!); diff --git a/src/tests/wrappers/ConfigBinding.test.svelte b/src/tests/wrappers/ConfigBinding.test.svelte index ee7b6a0..cc50fe9 100644 --- a/src/tests/wrappers/ConfigBinding.test.svelte +++ b/src/tests/wrappers/ConfigBinding.test.svelte @@ -8,12 +8,26 @@ Wraps the to be tested svelte-konva component so that the binding of the config const { component, - boundConfigWritable, getHandle, - staticConfig = false + staticConfig = false, + x, + y, + scale, + scaleX, + scaleY, + rotation, + skewX, + skewY }: { component: any; - boundConfigWritable: Writable; + x: Writable; + y: Writable; + scale?: Writable; + scaleX?: Writable; + scaleY?: Writable; + rotation?: Writable; + skewX?: Writable; + skewY?: Writable; getHandle: (handle: any) => void; staticConfig?: boolean; } = $props(); @@ -29,6 +43,13 @@ Wraps the to be tested svelte-konva component so that the binding of the config diff --git a/src/tests/wrappers/ContainerContext.test.svelte b/src/tests/wrappers/ContainerContext.test.svelte index 56e6a1f..3761a48 100644 --- a/src/tests/wrappers/ContainerContext.test.svelte +++ b/src/tests/wrappers/ContainerContext.test.svelte @@ -8,14 +8,14 @@ Wraps the to be tested svelte-konva component so that the context of the svelte- const { component, - config, getHandle, - getComponentContext + getComponentContext, + ...restProps }: { component: any; - config?: any; getHandle?: (handle: any) => void; getComponentContext: (ctx: Map) => void; + [key: string]: any; } = $props(); let boundComponent: any; @@ -26,6 +26,6 @@ Wraps the to be tested svelte-konva component so that the context of the svelte- }); - + From 839841e63b37296a2833f42de51d6aa8af27d5b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Wed, 31 Jul 2024 12:17:55 +0200 Subject: [PATCH 42/56] Fix binding tests to work with new split config props --- src/tests/group.test.ts | 28 +++++++++++--------- src/tests/image.test.ts | 26 +++++++++++------- src/tests/label.test.ts | 28 +++++++++++--------- src/tests/layer.test.ts | 28 +++++++++++--------- src/tests/shape.test.ts | 26 +++++++++++------- src/tests/sprite.test.ts | 26 +++++++++++------- src/tests/stage.test.ts | 28 +++++++++++--------- src/tests/wrappers/ConfigBinding.test.svelte | 7 +++-- 8 files changed, 117 insertions(+), 80 deletions(-) diff --git a/src/tests/group.test.ts b/src/tests/group.test.ts index 35f2cc2..29f3f98 100644 --- a/src/tests/group.test.ts +++ b/src/tests/group.test.ts @@ -116,15 +116,18 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const CONFIG = { x: 0, draggable: true }; - const configWritable = writable(CONFIG); + const CONFIG = { x: 0, y: 0, draggable: true }; + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Group | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Group, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -140,22 +143,24 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { - const CONFIG = { x: 0, draggable: true }; + const CONFIG = { x: 0, y: 0, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Group | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Group, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -172,9 +177,8 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('sets the correct context', () => { diff --git a/src/tests/image.test.ts b/src/tests/image.test.ts index bd3ff50..caae558 100644 --- a/src/tests/image.test.ts +++ b/src/tests/image.test.ts @@ -137,17 +137,21 @@ test('Correctly updates bound config on dragend', async () => { const CONFIG = { x: 0, + y: 0, image: testImage, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Image | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: KonvaImage, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -161,9 +165,8 @@ test('Correctly updates bound config on dragend', async () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', async () => { @@ -171,18 +174,22 @@ test('Does not update config if instantiated with staticConfig prop', async () = const CONFIG = { x: 0, + y: 0, image: testImage, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Image | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: KonvaImage, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -197,9 +204,8 @@ test('Does not update config if instantiated with staticConfig prop', async () = (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', async () => { diff --git a/src/tests/label.test.ts b/src/tests/label.test.ts index 3638140..0eb8209 100644 --- a/src/tests/label.test.ts +++ b/src/tests/label.test.ts @@ -112,15 +112,18 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const CONFIG = { x: 0, draggable: true }; - const configWritable = writable(CONFIG); + const CONFIG = { x: 0, y: 0, draggable: true }; + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Label | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Label, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -136,22 +139,24 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', async () => { - const CONFIG = { x: 0, draggable: true }; + const CONFIG = { x: 0, y: 0, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Label | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Label, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -168,9 +173,8 @@ test('Does not update config if instantiated with staticConfig prop', async () = (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('sets the correct context', () => { diff --git a/src/tests/layer.test.ts b/src/tests/layer.test.ts index b93f0c3..00cfad4 100644 --- a/src/tests/layer.test.ts +++ b/src/tests/layer.test.ts @@ -95,16 +95,19 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const CONFIG = { x: 0, draggable: true }; + const CONFIG = { x: 0, y: 0, draggable: true }; const div = document.createElement('div'); - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Layer | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Stage, div), props: { component: Layer, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -120,23 +123,25 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', async () => { - const CONFIG = { x: 0, draggable: true }; + const CONFIG = { x: 0, y: 0, draggable: true }; const oldConfig = { ...CONFIG }; const div = document.createElement('div'); - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Layer | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Stage, div), props: { component: Layer, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -153,9 +158,8 @@ test('Does not update config if instantiated with staticConfig prop', async () = (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('sets the correct context', () => { diff --git a/src/tests/shape.test.ts b/src/tests/shape.test.ts index b757cee..7927eba 100644 --- a/src/tests/shape.test.ts +++ b/src/tests/shape.test.ts @@ -156,6 +156,7 @@ test('Can listen to Konva events', () => { test('Correctly updates bound config on dragend', () => { const CONFIG = { x: 0, + y: 0, width: 100, height: 100, sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { @@ -165,14 +166,17 @@ test('Correctly updates bound config on dragend', () => { }, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Shape | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Shape, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -186,14 +190,14 @@ test('Correctly updates bound config on dragend', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', () => { const CONFIG = { x: 0, + y: 0, width: 100, height: 100, sceneFunc: function (context: Konva.Context, shape: Konva.Shape) { @@ -204,14 +208,17 @@ test('Does not update config if instantiated with staticConfig prop', () => { draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Shape | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Shape, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -226,9 +233,8 @@ test('Does not update config if instantiated with staticConfig prop', () => { (stage as MockStage).simulateMouseMove({ x: 100, y: 100 }); (stage as MockStage).simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', () => { diff --git a/src/tests/sprite.test.ts b/src/tests/sprite.test.ts index eb9466b..d2852b5 100644 --- a/src/tests/sprite.test.ts +++ b/src/tests/sprite.test.ts @@ -161,6 +161,7 @@ test('Correctly updates bound config on dragend', async () => { const CONFIG = { x: 0, + y: 0, image: spriteImage, animation: 'default', animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, @@ -168,14 +169,17 @@ test('Correctly updates bound config on dragend', async () => { frameIndex: 0, draggable: true }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Sprite | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Sprite, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd) } }); @@ -189,9 +193,8 @@ test('Correctly updates bound config on dragend', async () => { (stage as MockStage).simulateMouseMove({ x: 70, y: 70 }); (stage as MockStage).simulateMouseUp({ x: 70, y: 70 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', async () => { @@ -199,6 +202,7 @@ test('Does not update config if instantiated with staticConfig prop', async () = const CONFIG = { x: 0, + y: 0, image: spriteImage, animation: 'default', animations: { default: [0, 0, 50, 100, 50, 0, 50, 100] }, @@ -207,14 +211,17 @@ test('Does not update config if instantiated with staticConfig prop', async () = draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: Konva.Sprite | null = null; render(ConfigBinding, { context: createMockParentContext(Container.Layer), props: { component: Sprite, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd), staticConfig: true } @@ -229,9 +236,8 @@ test('Does not update config if instantiated with staticConfig prop', async () = (stage as MockStage).simulateMouseMove({ x: 70, y: 70 }); (stage as MockStage).simulateMouseUp({ x: 70, y: 70 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('Konva instance is correctly destroyed on component unmount', async () => { diff --git a/src/tests/stage.test.ts b/src/tests/stage.test.ts index 39f86a0..794e58e 100644 --- a/src/tests/stage.test.ts +++ b/src/tests/stage.test.ts @@ -91,14 +91,17 @@ test('Can listen to Konva events', () => { }); test('Correctly updates bound config on dragend', () => { - const CONFIG = { x: 0, width: 1000, height: 1000, draggable: true }; - const configWritable = writable(CONFIG); + const CONFIG = { x: 0, y: 0, width: 1000, height: 1000, draggable: true }; + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: MockStage | null = null; render(ConfigBinding, { props: { component: Stage, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd()) } }); @@ -107,21 +110,23 @@ test('Correctly updates bound config on dragend', () => { handle!.simulateMouseMove({ x: 100, y: 100 }); handle!.simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual({ ...CONFIG, x: 50 }); + expect(get(xWritable)).toEqual(50); + expect(get(yWritable)).toEqual(50); }); test('Does not update config if instantiated with staticConfig prop', async () => { - const CONFIG = { x: 0, width: 1000, height: 1000, draggable: true }; + const CONFIG = { x: 0, y: 0, width: 1000, height: 1000, draggable: true }; const oldConfig = { ...CONFIG }; - const configWritable = writable(CONFIG); + const xWritable = writable(CONFIG.x); + const yWritable = writable(CONFIG.y); let handle: MockStage | null = null; render(ConfigBinding, { props: { component: Stage, - boundConfigWritable: configWritable, + ...CONFIG, + x: xWritable, + y: yWritable, getHandle: (hnd) => (handle = hnd()), staticConfig: true } @@ -131,9 +136,8 @@ test('Does not update config if instantiated with staticConfig prop', async () = handle!.simulateMouseMove({ x: 100, y: 100 }); handle!.simulateMouseUp({ x: 100, y: 100 }); - const config = get(configWritable); - - expect(config).toStrictEqual(oldConfig); + expect(get(xWritable)).toEqual(oldConfig.x); + expect(get(yWritable)).toEqual(oldConfig.y); }); test('sets the correct context', () => { diff --git a/src/tests/wrappers/ConfigBinding.test.svelte b/src/tests/wrappers/ConfigBinding.test.svelte index cc50fe9..5b11c45 100644 --- a/src/tests/wrappers/ConfigBinding.test.svelte +++ b/src/tests/wrappers/ConfigBinding.test.svelte @@ -6,7 +6,7 @@ Wraps the to be tested svelte-konva component so that the binding of the config import { onMount } from 'svelte'; import type { Writable } from 'svelte/store'; - const { + let { component, getHandle, staticConfig = false, @@ -17,7 +17,8 @@ Wraps the to be tested svelte-konva component so that the binding of the config scaleY, rotation, skewX, - skewY + skewY, + ...restProps }: { component: any; x: Writable; @@ -30,6 +31,7 @@ Wraps the to be tested svelte-konva component so that the binding of the config skewY?: Writable; getHandle: (handle: any) => void; staticConfig?: boolean; + [key: string]: any; } = $props(); let boundComponent: any; @@ -52,4 +54,5 @@ Wraps the to be tested svelte-konva component so that the binding of the config bind:skewX={$skewX} bind:skewY={$skewY} {staticConfig} + {...restProps} > From 3ffb059bbfb205f229efade73be11dd90610f2fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Wed, 31 Jul 2024 12:27:42 +0200 Subject: [PATCH 43/56] Make stage x and y props bindable. Fix stage bindable tests --- src/lib/Stage.svelte | 18 ++++--- src/tests/stage.test.ts | 6 +-- .../wrappers/ConfigBindingStage.test.svelte | 48 +++++++++++++++++++ 3 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 src/tests/wrappers/ConfigBindingStage.test.svelte diff --git a/src/lib/Stage.svelte b/src/lib/Stage.svelte index c261518..7b3cdf6 100644 --- a/src/lib/Stage.svelte +++ b/src/lib/Stage.svelte @@ -59,16 +59,16 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), ontransformend, ontransformstart, onwheel, - y, - x, - width, - visible, - skewY, - skewX, - scaleY, - scaleX, + x = $bindable(), + y = $bindable(), scale, + scaleX, + scaleY, rotation, + skewX, + skewY, + width, + visible, preventDefault, opacity, offsetY, @@ -104,7 +104,6 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), let isReady = $state(false); onMount(() => { - console.log(x, y); _handle = new Konva.Stage({ container: stage, y, @@ -156,7 +155,6 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), }); $effect(() => { _handle!.setAttr('width', width); - console.log('stage change width', width); }); $effect(() => { _handle!.setAttr('visible', visible); diff --git a/src/tests/stage.test.ts b/src/tests/stage.test.ts index 794e58e..8ce3894 100644 --- a/src/tests/stage.test.ts +++ b/src/tests/stage.test.ts @@ -12,7 +12,7 @@ import './mocks/mouse'; import type { MockStage } from './mocks/mouse'; // Test Component Wrappers -import ConfigBinding from './wrappers/ConfigBinding.test.svelte'; +import ConfigBindingStage from './wrappers/ConfigBindingStage.test.svelte'; import ContainerContext from './wrappers/ContainerContext.test.svelte'; test('creates a div container and forwards rest props to div', () => { @@ -96,7 +96,7 @@ test('Correctly updates bound config on dragend', () => { const yWritable = writable(CONFIG.y); let handle: MockStage | null = null; - render(ConfigBinding, { + render(ConfigBindingStage, { props: { component: Stage, ...CONFIG, @@ -121,7 +121,7 @@ test('Does not update config if instantiated with staticConfig prop', async () = const yWritable = writable(CONFIG.y); let handle: MockStage | null = null; - render(ConfigBinding, { + render(ConfigBindingStage, { props: { component: Stage, ...CONFIG, diff --git a/src/tests/wrappers/ConfigBindingStage.test.svelte b/src/tests/wrappers/ConfigBindingStage.test.svelte new file mode 100644 index 0000000..446eff1 --- /dev/null +++ b/src/tests/wrappers/ConfigBindingStage.test.svelte @@ -0,0 +1,48 @@ + + + + From 7d76fae18ec7b20dc1fe81ab5caf1a2de6ea46aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Wed, 31 Jul 2024 12:43:34 +0200 Subject: [PATCH 44/56] New divWrapperId prop to expose stage div id to user (id prop already used by stage config). Tests all passing --- src/lib/Stage.svelte | 4 +++- src/lib/util/props.ts | 1 + src/tests/stage.test.ts | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/lib/Stage.svelte b/src/lib/Stage.svelte index 7b3cdf6..a1c4941 100644 --- a/src/lib/Stage.svelte +++ b/src/lib/Stage.svelte @@ -89,6 +89,8 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), clipHeight, clearBeforeDraw, clipFunc, + // Props forwarded to wrapper div: + divWrapperId, ...restProps }: Props & PropsContainer & PropsStage = $props(); @@ -288,7 +290,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), setContainerContext(Container.Stage, inner); -
+
{#if isReady && children} {@render children()} {/if} diff --git a/src/lib/util/props.ts b/src/lib/util/props.ts index 1456a3e..8825c31 100644 --- a/src/lib/util/props.ts +++ b/src/lib/util/props.ts @@ -20,5 +20,6 @@ export type PropsContainer = { * Special props extension for svelte-konva Stage (Forwards rest props to canvas div container) */ export type PropsStage = { + divWrapperId?: string; // Required to enable user to set/change ID of wrapper div as `id` prop is already used by stage config [key: string]: any; }; diff --git a/src/tests/stage.test.ts b/src/tests/stage.test.ts index 8ce3894..fcafb42 100644 --- a/src/tests/stage.test.ts +++ b/src/tests/stage.test.ts @@ -20,7 +20,7 @@ test('creates a div container and forwards rest props to div', () => { props: { width: 1000, height: 1000, - id: 'container', + divWrapperId: 'container', restProp: false } }); @@ -38,11 +38,12 @@ test('creates a Konva canvas instance inside of the div', () => { props: { width: 1000, height: 1000, - id: 'container' + divWrapperId: 'container' } }); const div = rendered.container.querySelector('#container'); + console.log(rendered.container.innerHTML); expect(div).toBeTruthy(); if (div) { From 3a4cfbb6688942a7e2eafd31c91bbefc257ee348 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Wed, 31 Jul 2024 13:11:19 +0200 Subject: [PATCH 45/56] Forward all stage wrapper div props through prop, cleanup messy stage code --- src/lib/Stage.svelte | 224 ++---------------- src/lib/util/props.ts | 5 +- src/routes/ResponsiveStage.svelte | 4 +- .../examples/connectFour/GameGrid.svelte | 4 - src/tests/stage.test.ts | 14 +- 5 files changed, 28 insertions(+), 223 deletions(-) diff --git a/src/lib/Stage.svelte b/src/lib/Stage.svelte index a1c4941..9e79688 100644 --- a/src/lib/Stage.svelte +++ b/src/lib/Stage.svelte @@ -28,69 +28,10 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), let { children, staticConfig = false, - onclick, - ondblclick, - ondbltap, - ondragend, - ondragmove, - ondragstart, - onmousedown, - onmouseenter, - onmouseleave, - onmousemove, - onmouseout, - onmouseover, - onmouseup, - onpointercancel, - onpointerclick, - onpointerdblclick, - onpointerdown, - onpointerenter, - onpointerleave, - onpointermove, - onpointerout, - onpointerover, - onpointerup, - ontap, - ontouchend, - ontouchmove, - ontouchstart, - ontransform, - ontransformend, - ontransformstart, - onwheel, x = $bindable(), y = $bindable(), - scale, - scaleX, - scaleY, - rotation, - skewX, - skewY, - width, - visible, - preventDefault, - opacity, - offsetY, - offsetX, - offset, - name, - listening, - id, - height, - globalCompositeOperation, - filters, - draggable, - dragDistance, - dragBoundFunc, - clipY, - clipX, - clipWidth, - clipHeight, - clearBeforeDraw, - clipFunc, // Props forwarded to wrapper div: - divWrapperId, + divWrapperProps, ...restProps }: Props & PropsContainer & PropsStage = $props(); @@ -110,34 +51,7 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), container: stage, y, x, - width, - visible, - skewY, - skewX, - scaleY, - scaleX, - scale, - rotation, - preventDefault, - opacity, - offsetY, - offsetX, - offset, - name, - listening, - id, - height, - globalCompositeOperation, - filters, - draggable, - dragDistance, - dragBoundFunc, - clipY, - clipX, - clipWidth, - clipHeight, - clearBeforeDraw, - clipFunc + ...restProps }); if (!staticConfig) { @@ -149,133 +63,23 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), }); } + Object.keys(restProps) + .filter((e) => !e.startsWith('on')) // Do not register svelte-konva event hooks as node attributes (Currently no konva config property starts with "on" so this is the fastest and most inexpensive way to filter out the event hooks from the provided props) + .forEach((e) => { + $effect(() => { + _handle!.setAttr(e, restProps[e]); + }); + }); + + // Register explicit props (not included in restProps) $effect(() => { _handle!.setAttr('x', x); }); $effect(() => { _handle!.setAttr('y', y); }); - $effect(() => { - _handle!.setAttr('width', width); - }); - $effect(() => { - _handle!.setAttr('visible', visible); - }); - $effect(() => { - _handle!.setAttr('skewY', skewY); - }); - $effect(() => { - _handle!.setAttr('skewX', skewX); - }); - $effect(() => { - _handle!.setAttr('scaleY', scaleY); - }); - $effect(() => { - _handle!.setAttr('scaleX', scaleX); - }); - $effect(() => { - _handle!.setAttr('scale', scale); - }); - $effect(() => { - _handle!.setAttr('rotation', rotation); - }); - $effect(() => { - _handle!.setAttr('preventDefault', preventDefault); - }); - $effect(() => { - _handle!.setAttr('opacity', opacity); - }); - $effect(() => { - _handle!.setAttr('offsetY', offsetY); - }); - $effect(() => { - _handle!.setAttr('offsetX', offsetX); - }); - $effect(() => { - _handle!.setAttr('offset', offset); - }); - $effect(() => { - _handle!.setAttr('name', name); - }); - $effect(() => { - _handle!.setAttr('listening', listening); - }); - $effect(() => { - _handle!.setAttr('id', id); - }); - $effect(() => { - _handle!.setAttr('height', height); - }); - $effect(() => { - _handle!.setAttr('globalCompositeOperation', globalCompositeOperation); - }); - $effect(() => { - _handle!.setAttr('filters', filters); - }); - $effect(() => { - _handle!.setAttr('draggable', draggable); - }); - $effect(() => { - _handle!.setAttr('dragDistance', dragDistance); - }); - $effect(() => { - _handle!.setAttr('dragBoundFunc', dragBoundFunc); - }); - $effect(() => { - _handle!.setAttr('clipY', clipY); - }); - $effect(() => { - _handle!.setAttr('clipX', clipX); - }); - $effect(() => { - _handle!.setAttr('clipWidth', clipWidth); - }); - $effect(() => { - _handle!.setAttr('clipHeight', clipHeight); - }); - $effect(() => { - _handle!.setAttr('clearBeforeDraw', clearBeforeDraw); - }); - $effect(() => { - _handle!.setAttr('clipFunc', clipFunc); - }); - registerEvents( - { - onclick, - ondblclick, - ondbltap, - ondragend, - ondragmove, - ondragstart, - onmousedown, - onmouseenter, - onmouseleave, - onmousemove, - onmouseout, - onmouseover, - onmouseup, - onpointercancel, - onpointerclick, - onpointerdblclick, - onpointerdown, - onpointerenter, - onpointerleave, - onpointermove, - onpointerout, - onpointerover, - onpointerup, - ontap, - ontouchend, - ontouchmove, - ontouchstart, - ontransform, - ontransformend, - ontransformstart, - onwheel - }, - _handle - ); + registerEvents(restProps, _handle); inner.set(_handle); isReady = true; @@ -288,9 +92,11 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Stage.html), }); setContainerContext(Container.Stage, inner); + + HTMLDivElement; -
+
{#if isReady && children} {@render children()} {/if} diff --git a/src/lib/util/props.ts b/src/lib/util/props.ts index 8825c31..a93b6be 100644 --- a/src/lib/util/props.ts +++ b/src/lib/util/props.ts @@ -20,6 +20,7 @@ export type PropsContainer = { * Special props extension for svelte-konva Stage (Forwards rest props to canvas div container) */ export type PropsStage = { - divWrapperId?: string; // Required to enable user to set/change ID of wrapper div as `id` prop is already used by stage config - [key: string]: any; + divWrapperProps: { + [key: string]: any; // Everything in this object is forwarded to the wrapper div + }; }; diff --git a/src/routes/ResponsiveStage.svelte b/src/routes/ResponsiveStage.svelte index fe3469c..b6d1889 100644 --- a/src/routes/ResponsiveStage.svelte +++ b/src/routes/ResponsiveStage.svelte @@ -40,8 +40,6 @@ let scale = config.width / STAGE_BASE_WIDTH; config.scaleX = scale; config.scaleY = scale; - - console.log('new width', config.width); } onMount(() => { @@ -54,7 +52,7 @@
{ @@ -59,8 +57,6 @@ adjustScaleAndSize(); }); - - $inspect(stageConfig);
{ +test('creates a div container and forwards divWrapperProps props to div', () => { const rendered = render(Stage, { props: { width: 1000, height: 1000, - divWrapperId: 'container', - restProp: false + divWrapperProps: { + id: 'container', + someProp: false + } } }); @@ -30,7 +32,7 @@ test('creates a div container and forwards rest props to div', () => { expect(div).toBeInstanceOf(HTMLDivElement); - if (div) expect(div.getAttribute('restProp')).toBe('false'); + if (div) expect(div.getAttribute('someProp')).toBe('false'); }); test('creates a Konva canvas instance inside of the div', () => { @@ -38,7 +40,9 @@ test('creates a Konva canvas instance inside of the div', () => { props: { width: 1000, height: 1000, - divWrapperId: 'container' + divWrapperProps: { + id: 'container' + } } }); From 1d1126bddc7ebe27a766734f4df435ca3036e645 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Wed, 31 Jul 2024 14:54:55 +0200 Subject: [PATCH 46/56] Update migration guide with split config props and divWrapperProps --- docs/svelte-konva-v1-migration.md | 99 +++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 6 deletions(-) diff --git a/docs/svelte-konva-v1-migration.md b/docs/svelte-konva-v1-migration.md index f2f23b9..94fdeba 100644 --- a/docs/svelte-konva-v1-migration.md +++ b/docs/svelte-konva-v1-migration.md @@ -1,12 +1,80 @@ # Migration to svelte-konva v1 +The following document outlines all breaking changes for svelte-konva v1 and how to migrate from svelte-konva v0. + +## `config` prop is now splitted into individual props + +In svelte-konva v0 the `config` prop contained an object whith all configurabe properties of a Konva node (similar to [vue-konva](https://github.com/konvajs/vue-konva)). With v1 this has now been changed so that the properties of the konva Node are now exposed directly as individual props (similar to [react-konva](https://github.com/konvajs/react-konva)): + +```diff + +``` + +### Migration examples + +As this is a big API change that requires manual migration work, the most common migration examples are outlined in the examples below: + +**Spreading the old config object:** + +```diff + + + +``` + +**Bound config prop:** + +```diff + + + +``` + +You can also bind other properties such as `skewX`, `scaleY`, `rotation`, etc. to receive updates after transformation of the shape. + +### Why this was changed: + +There are some important reasons that warrant this change, namely: + +- By splitting the config prop into individual props svelte-konva can fully leverage the "fine-grainded reactivity" approach of Svelte 5. Changes to an individual configuration property do not lead to the invalidation of the entire configuration. +- Binding/not binding the `config` prop has always had certain caveats and hard to understand side-effects such as changes to properties of the `config` prop made by svelte-konva "leaking" into user code even when the `config` prop was not bound. With splitted props this can no longer happen and binding individual props is now clearly defined and limited to props that can actually be modified by svelte-konva. No more leaking/unexpected changes coming from svelte-konva code if the respective prop is not bound. +- The change brings svelte-konva API-wise more in line with other popular Svelte component libraries (such as [threlte](https://github.com/threlte/threlte)) + ## Event handlers In Svelte v5 usage of the `on:event` syntax is deprecated. svelte-konva provides all Konva events now as callback props using the `on` syntax. The deprecated `on:event` syntax will no longer work for svelte-konva events: ```diff @@ -41,14 +109,14 @@ The way to access the corresponding Konva handle in a svelte-konva component has - - const json = rectangle.toJSON(); + const json = rectangle.handle.toJSON(); - window.alert(`Rectangle as JSON: ${json}`); + window.alert(`Rectangle as JSON: ${json}`); }); - + @@ -78,13 +146,32 @@ The stage `handle` needs special treatment, as it only becomes defined once the }); - + - + ``` +## Passing props to the wrapping stage div + +When using the svelte-konva `Stage` component, svelte-konva automatically creates a HTML div element which contains the Konva stage. Previously you could pass props to this div by using the rest props on the `Stage` component. With v1 this is changed such that you can now pass props directly using the new `divWrapperProps` prop on the `Stage` component. It accepts an object containing all props that are directly passed to the wrapper div: + +```diff + + +``` + +This has been changed due to Konva configuration props colliding with certain div props (for example `id`) which made it impossible to distinguish whether the prop was aimed at the Konva node or the div wrapper. + ## Svelte runes-only mode svelte-konva is now fully compatible with Svelte's runes-only compile mode which means it will work out of the box for runes-only projects. It will also continue to work for all projects without runes-only mode enabled. From ca4b716675b51ae0ff73a4c0a45fc0077eb500fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Wed, 31 Jul 2024 15:00:33 +0200 Subject: [PATCH 47/56] make divWrapperProps optional --- src/lib/util/props.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/util/props.ts b/src/lib/util/props.ts index a93b6be..da38936 100644 --- a/src/lib/util/props.ts +++ b/src/lib/util/props.ts @@ -20,7 +20,7 @@ export type PropsContainer = { * Special props extension for svelte-konva Stage (Forwards rest props to canvas div container) */ export type PropsStage = { - divWrapperProps: { + divWrapperProps?: { [key: string]: any; // Everything in this object is forwarded to the wrapper div }; }; From da6b1817a895483642b53a7d9589bbe23c77328a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Wed, 31 Jul 2024 15:08:50 +0200 Subject: [PATCH 48/56] Fix linter dep issue --- package-lock.json | 69 ++++++++++++++++++++++++----------------------- package.json | 1 + 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0e6814e..5e0c939 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,7 @@ "prettier-plugin-svelte": "^3.2.3", "svelte": "5.0.0-next.200", "svelte-check": "^3.7.1", + "svelte-eslint-parser": "^0.41.0", "svelte-highlight": "^7.3.0", "svelte-persisted-store": "^0.9.2", "svelte-preprocess": "^5.0.4", @@ -3070,33 +3071,6 @@ "node": ">=4" } }, - "node_modules/eslint-plugin-svelte/node_modules/svelte-eslint-parser": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.35.0.tgz", - "integrity": "sha512-CtbPseajW0gjwEvHiuzYJkPDjAcHz2FaHt540j6RVYrZgnE6xWkzUBodQ4I3nV+G5AS0Svt8K6aIA/CIU9xT2Q==", - "dev": true, - "dependencies": { - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "postcss": "^8.4.38", - "postcss-scss": "^4.0.9" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ota-meshi" - }, - "peerDependencies": { - "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.112" - }, - "peerDependenciesMeta": { - "svelte": { - "optional": true - } - } - }, "node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", @@ -6039,9 +6013,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", "dev": true }, "node_modules/picomatch": { @@ -6120,9 +6094,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.40", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.40.tgz", + "integrity": "sha512-YF2kKIUzAofPMpfH6hOi2cGnv/HrUlfucspc7pDyvv7kGdqXrfj8SCl/t8owkEgKEuu8ZcRjSOxFxVLqwChZ2Q==", "dev": true, "funding": [ { @@ -6140,7 +6114,7 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -7181,6 +7155,33 @@ "svelte": "^3.55.0 || ^4.0.0-next.0 || ^4.0.0 || ^5.0.0-next.0" } }, + "node_modules/svelte-eslint-parser": { + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/svelte-eslint-parser/-/svelte-eslint-parser-0.41.0.tgz", + "integrity": "sha512-L6f4hOL+AbgfBIB52Z310pg1d2QjRqm7wy3kI1W6hhdhX5bvu7+f0R6w4ykp5HoDdzq+vGhIJmsisaiJDGmVfA==", + "dev": true, + "dependencies": { + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "postcss": "^8.4.39", + "postcss-scss": "^4.0.9" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + }, + "peerDependencies": { + "svelte": "^3.37.0 || ^4.0.0 || ^5.0.0-next.191" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + } + } + }, "node_modules/svelte-highlight": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/svelte-highlight/-/svelte-highlight-7.4.6.tgz", diff --git a/package.json b/package.json index e211664..6ba94ac 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-svelte": "^2.38.0", + "svelte-eslint-parser": "^0.41.0", "jsdom": "^24.0.0", "konva": "^9.3.11", "lodash.clonedeep": "^4.5.0", From 3d2626235765cac48a9e3cc5b32727d646a38654 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Wed, 31 Jul 2024 15:10:08 +0200 Subject: [PATCH 49/56] Remove unused function --- src/lib/Group.svelte | 1 - src/lib/Label.svelte | 1 - src/lib/util/object.ts | 14 -------------- 3 files changed, 16 deletions(-) delete mode 100644 src/lib/util/object.ts diff --git a/src/lib/Group.svelte b/src/lib/Group.svelte index c995369..5729161 100644 --- a/src/lib/Group.svelte +++ b/src/lib/Group.svelte @@ -29,7 +29,6 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Group.html), type KonvaParent } from '$lib/util/manageContext'; import { registerEvents } from '$lib/util/events'; - import { copyExistingKeys } from '$lib/util/object'; import { type PropsContainer, type Props } from '$lib/util/props'; let { diff --git a/src/lib/Label.svelte b/src/lib/Label.svelte index 8888cb7..f81d1fb 100644 --- a/src/lib/Label.svelte +++ b/src/lib/Label.svelte @@ -23,7 +23,6 @@ Further information: [Konva API docs](https://konvajs.org/api/Konva.Label.html), import Konva from 'konva'; import { onMount, onDestroy } from 'svelte'; import { writable, type Writable } from 'svelte/store'; - import { copyExistingKeys } from '$lib/util/object'; import { Container, getParentContainer, diff --git a/src/lib/util/object.ts b/src/lib/util/object.ts deleted file mode 100644 index 049feb0..0000000 --- a/src/lib/util/object.ts +++ /dev/null @@ -1,14 +0,0 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ - -/** - * Only copies fields from the source object that already exist on the target object, skipping everything else - * @param target - * @param source - */ -export function copyExistingKeys(target: { [key: string]: any }, source: { [key: string]: any }) { - for (const key in target) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } -} From b0931c6c4e216d0b9e7321d3e15f4edc7a7d238f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Wed, 31 Jul 2024 15:22:44 +0200 Subject: [PATCH 50/56] Fix or ignore most linter errors --- .eslintrc.cjs | 5 ++++- src/lib/util/props.ts | 2 ++ src/templates/svelteKonvaComponentTests.hbs | 2 -- src/tests/arc.test.ts | 2 -- src/tests/arrow.test.ts | 2 -- src/tests/circle.test.ts | 2 -- src/tests/ellipse.test.ts | 2 -- src/tests/group.test.ts | 2 ++ src/tests/label.test.ts | 2 ++ src/tests/layer.test.ts | 2 ++ src/tests/line.test.ts | 2 -- src/tests/path.test.ts | 2 -- src/tests/rect.test.ts | 2 -- src/tests/regularpolygon.test.ts | 2 -- src/tests/ring.test.ts | 2 -- src/tests/stage.test.ts | 2 ++ src/tests/star.test.ts | 2 -- src/tests/tag.test.ts | 2 -- src/tests/text.test.ts | 2 -- src/tests/textpath.test.ts | 2 -- src/tests/wedge.test.ts | 2 -- src/tests/wrappers/ConfigBinding.test.svelte | 1 + src/tests/wrappers/ConfigBindingStage.test.svelte | 7 +------ src/tests/wrappers/ContainerContext.test.svelte | 1 + src/tests/wrappers/ContextReporter.test.svelte | 1 + 25 files changed, 18 insertions(+), 37 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index ef24476..02eb364 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -46,7 +46,10 @@ module.exports = { '@typescript-eslint/no-unused-vars': [ 'warn', { - varsIgnorePattern: '\\$\\$Events' + varsIgnorePattern: '^_', + argsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_' } ] } diff --git a/src/lib/util/props.ts b/src/lib/util/props.ts index da38936..d999b17 100644 --- a/src/lib/util/props.ts +++ b/src/lib/util/props.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + import type { Snippet } from 'svelte'; import { type KonvaEventHooks } from '$lib/util/events'; diff --git a/src/templates/svelteKonvaComponentTests.hbs b/src/templates/svelteKonvaComponentTests.hbs index 66f4f7a..47455fb 100644 --- a/src/templates/svelteKonvaComponentTests.hbs +++ b/src/templates/svelteKonvaComponentTests.hbs @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/arc.test.ts b/src/tests/arc.test.ts index d18c851..9bd7fef 100644 --- a/src/tests/arc.test.ts +++ b/src/tests/arc.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/arrow.test.ts b/src/tests/arrow.test.ts index 638ace7..5b0e714 100644 --- a/src/tests/arrow.test.ts +++ b/src/tests/arrow.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/circle.test.ts b/src/tests/circle.test.ts index 1e9f72a..5d8e289 100644 --- a/src/tests/circle.test.ts +++ b/src/tests/circle.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/ellipse.test.ts b/src/tests/ellipse.test.ts index 9e1080e..a1ab121 100644 --- a/src/tests/ellipse.test.ts +++ b/src/tests/ellipse.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/group.test.ts b/src/tests/group.test.ts index 29f3f98..82e1b21 100644 --- a/src/tests/group.test.ts +++ b/src/tests/group.test.ts @@ -182,6 +182,7 @@ test('Does not update config if instantiated with staticConfig prop', () => { }); test('sets the correct context', () => { + /* eslint-disable @typescript-eslint/no-explicit-any */ let childContext: Map | null = null; let handle: Konva.Group | null = null; @@ -198,6 +199,7 @@ test('sets the correct context', () => { }); test('nulls unused context', () => { + /* eslint-disable @typescript-eslint/no-explicit-any */ let childContext: Map | null = null; render(ContainerContext, { diff --git a/src/tests/label.test.ts b/src/tests/label.test.ts index 0eb8209..fdfd97f 100644 --- a/src/tests/label.test.ts +++ b/src/tests/label.test.ts @@ -178,6 +178,7 @@ test('Does not update config if instantiated with staticConfig prop', async () = }); test('sets the correct context', () => { + /* eslint-disable @typescript-eslint/no-explicit-any */ let childContext: Map | null = null; let handle: Konva.Label | null = null; @@ -194,6 +195,7 @@ test('sets the correct context', () => { }); test('nulls unused context', () => { + /* eslint-disable @typescript-eslint/no-explicit-any */ let childContext: Map | null = null; render(ContainerContext, { diff --git a/src/tests/layer.test.ts b/src/tests/layer.test.ts index 00cfad4..202a24b 100644 --- a/src/tests/layer.test.ts +++ b/src/tests/layer.test.ts @@ -163,6 +163,7 @@ test('Does not update config if instantiated with staticConfig prop', async () = }); test('sets the correct context', () => { + /* eslint-disable @typescript-eslint/no-explicit-any */ const div = document.createElement('div'); let childContext: Map | null = null; let handle: Konva.Layer | null = null; @@ -180,6 +181,7 @@ test('sets the correct context', () => { }); test('nulls unused context', () => { + /* eslint-disable @typescript-eslint/no-explicit-any */ const div = document.createElement('div'); let childContext: Map | null = null; diff --git a/src/tests/line.test.ts b/src/tests/line.test.ts index b3468cd..c9db56c 100644 --- a/src/tests/line.test.ts +++ b/src/tests/line.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/path.test.ts b/src/tests/path.test.ts index 7b7ccd2..d681990 100644 --- a/src/tests/path.test.ts +++ b/src/tests/path.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/rect.test.ts b/src/tests/rect.test.ts index 5d498ad..88cdb4f 100644 --- a/src/tests/rect.test.ts +++ b/src/tests/rect.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/regularpolygon.test.ts b/src/tests/regularpolygon.test.ts index dcdfa1b..724be36 100644 --- a/src/tests/regularpolygon.test.ts +++ b/src/tests/regularpolygon.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/ring.test.ts b/src/tests/ring.test.ts index 4124bb4..d436e43 100644 --- a/src/tests/ring.test.ts +++ b/src/tests/ring.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/stage.test.ts b/src/tests/stage.test.ts index ea34ffc..2296e7c 100644 --- a/src/tests/stage.test.ts +++ b/src/tests/stage.test.ts @@ -146,6 +146,7 @@ test('Does not update config if instantiated with staticConfig prop', async () = }); test('sets the correct context', () => { + /* eslint-disable @typescript-eslint/no-explicit-any */ let childContext: Map | null = null; let handle: Konva.Stage | null = null; @@ -163,6 +164,7 @@ test('sets the correct context', () => { }); test('nulls unused context', () => { + /* eslint-disable @typescript-eslint/no-explicit-any */ let childContext: Map | null = null; render(ContainerContext, { diff --git a/src/tests/star.test.ts b/src/tests/star.test.ts index d1e0e1d..e9db4b7 100644 --- a/src/tests/star.test.ts +++ b/src/tests/star.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/tag.test.ts b/src/tests/tag.test.ts index 7168115..28e13ec 100644 --- a/src/tests/tag.test.ts +++ b/src/tests/tag.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/text.test.ts b/src/tests/text.test.ts index b4aa6d7..efd747a 100644 --- a/src/tests/text.test.ts +++ b/src/tests/text.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/textpath.test.ts b/src/tests/textpath.test.ts index f7ac9fe..7731c5e 100644 --- a/src/tests/textpath.test.ts +++ b/src/tests/textpath.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/wedge.test.ts b/src/tests/wedge.test.ts index 4fe70d8..f4f9a08 100644 --- a/src/tests/wedge.test.ts +++ b/src/tests/wedge.test.ts @@ -191,8 +191,6 @@ test('Konva instance is correctly destroyed on component unmount', () => { rendered.unmount(); - const handle = rendered.component.handle; - expect(parent.children).toBeTruthy(); if (parent.children) { diff --git a/src/tests/wrappers/ConfigBinding.test.svelte b/src/tests/wrappers/ConfigBinding.test.svelte index 5b11c45..a43fbf9 100644 --- a/src/tests/wrappers/ConfigBinding.test.svelte +++ b/src/tests/wrappers/ConfigBinding.test.svelte @@ -3,6 +3,7 @@ Wraps the to be tested svelte-konva component so that the binding of the config prop can be tested --> - + ``` ### Static config: -By default svelte-konva will automatically update your config prop on `dragend` and `transformend` events to match the config state (position, rotation, scale, ...) with the internal Konva state. -If you additionally bind the config prop your reactive blocks will also be triggered once this happens. -There might be cases where this behavior is not beneficial in this case you can disable it by passing the `staticConfig = true` prop to the component. +By default svelte-konva will automatically update all changed props on `dragend` and `transformend` events to match the prop values (position, rotation, scale, ...) with the internal Konva state. +If you bind those props they will be updated automatically, otherwise no update of the changed values happens. +In cases this is not needed (eg. the respective values are not bound) or not beneficial you can disable it by passing the `staticConfig = true` prop to the component. +It is recommended to only pass `staticConfig = true` if you indeed run into performance problems connected to dragging and transforming of nodes. Further information: [Konva API docs](https://konvajs.org/api/Konva.Transformer.html), [svelte-konva docs](https://konvajs.org/docs/svelte) --> diff --git a/src/lib/Wedge.svelte b/src/lib/Wedge.svelte index 34492fc..b4f8ce6 100644 --- a/src/lib/Wedge.svelte +++ b/src/lib/Wedge.svelte @@ -8,9 +8,10 @@ The Wedge component needs to be placed either inside a svelte-konva Layer or Gro ``` ### Static config: -By default svelte-konva will automatically update your config prop on `dragend` and `transformend` events to match the config state (position, rotation, scale, ...) with the internal Konva state. -If you additionally bind the config prop your reactive blocks will also be triggered once this happens. -There might be cases where this behavior is not beneficial in this case you can disable it by passing the `staticConfig = true` prop to the component. +By default svelte-konva will automatically update all changed props on `dragend` and `transformend` events to match the prop values (position, rotation, scale, ...) with the internal Konva state. +If you bind those props they will be updated automatically, otherwise no update of the changed values happens. +In cases this is not needed (eg. the respective values are not bound) or not beneficial you can disable it by passing the `staticConfig = true` prop to the component. +It is recommended to only pass `staticConfig = true` if you indeed run into performance problems connected to dragging and transforming of nodes. Further information: [Konva API docs](https://konvajs.org/api/Konva.Wedge.html), [svelte-konva docs](https://konvajs.org/docs/svelte) --> diff --git a/src/templates/svelteKonvaComponent.hbs b/src/templates/svelteKonvaComponent.hbs index d535a98..95d0c60 100644 --- a/src/templates/svelteKonvaComponent.hbs +++ b/src/templates/svelteKonvaComponent.hbs @@ -8,9 +8,10 @@ The {{ componentName }} component needs to be placed either inside a svelte-konv ``` ### Static config: -By default svelte-konva will automatically update your config prop on `dragend` and `transformend` events to match the config state (position, rotation, scale, ...) with the internal Konva state. -If you additionally bind the config prop your reactive blocks will also be triggered once this happens. -There might be cases where this behavior is not beneficial in this case you can disable it by passing the `staticConfig = true` prop to the component. +By default svelte-konva will automatically update all changed props on `dragend` and `transformend` events to match the prop values (position, rotation, scale, ...) with the internal Konva state. +If you bind those props they will be updated automatically, otherwise no update of the changed values happens. +In cases this is not needed (eg. the respective values are not bound) or not beneficial you can disable it by passing the `staticConfig = true` prop to the component. +It is recommended to only pass `staticConfig = true` if you indeed run into performance problems connected to dragging and transforming of nodes. Further information: [Konva API docs](https://konvajs.org/api/Konva.{{ componentName }}.html), [svelte-konva docs](https://konvajs.org/docs/svelte) --> From e2ba060dc3314bd8f05e9a597d5e8d042d46fa5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 2 Aug 2024 20:33:11 +0200 Subject: [PATCH 54/56] Fix missing reactive declarations in transformer example --- src/routes/examples/transform/Transform.svelte | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/routes/examples/transform/Transform.svelte b/src/routes/examples/transform/Transform.svelte index 0385fd4..d3b73ea 100644 --- a/src/routes/examples/transform/Transform.svelte +++ b/src/routes/examples/transform/Transform.svelte @@ -40,7 +40,7 @@ } ]; - let selectionRectangleConfig = { + let selectionRectangleConfig = $state({ fill: 'rgba(0,0,255,0.5)', visible: false, x: 0, @@ -48,15 +48,15 @@ width: 0, height: 0, name: SELECTION_RECTANGLE_NAME - }; + }); // Used to calculate the position and size of the selection rectangle during selection - let initialSelectionCoordinates: Konva.Vector2d = { + let initialSelectionCoordinates: Konva.Vector2d = $state({ x: 0, y: 0 - }; + }); - let selectionActive = false; // If the transformer is active eg. something is selected + let selectionActive = $state(false); // If the transformer is active eg. something is selected function selectStart(e: KonvaPointerEvent) { if (!transformer || !stage) return; From 972424633b84c5d420f23064aa09a22fb9211bb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 2 Aug 2024 21:36:56 +0200 Subject: [PATCH 55/56] Add reactivity changes to migration guide, add Svelte 5 release candidate info to readme --- README.md | 12 +++++++ docs/svelte-konva-v1-migration.md | 55 ++++++++++++++++++++++++++++--- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index b64b75f..b35a2db 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,18 @@ svelte-konva is a component-based svelte wrapper for the [Konva HTML5 2D canvas Currently compatible with Svelte v3 & 4, SvelteKit v1 and Konva v8 & 9. +### Experimental Svelte 5 support + +There is now experimental support for Svelte v5. It is not production-ready and should be used for testing purposes only. Svelte 5 support is currently published under the `v1.0.0-next` tag. To use it simply add the following dependency to your package.json in your Svelte 5 project: + +``` +"svelte-konva": "^1.0.0-next.0" +``` + +Please see the [migration guide](./docs/svelte-konva-v1-migration.md) for all relevant (and breaking) changes. + +If you encounter bugs or difficulties while migrating/testing please open an issue. + ## Install ```npm diff --git a/docs/svelte-konva-v1-migration.md b/docs/svelte-konva-v1-migration.md index 94fdeba..c02c340 100644 --- a/docs/svelte-konva-v1-migration.md +++ b/docs/svelte-konva-v1-migration.md @@ -68,6 +68,57 @@ There are some important reasons that warrant this change, namely: - Binding/not binding the `config` prop has always had certain caveats and hard to understand side-effects such as changes to properties of the `config` prop made by svelte-konva "leaking" into user code even when the `config` prop was not bound. With splitted props this can no longer happen and binding individual props is now clearly defined and limited to props that can actually be modified by svelte-konva. No more leaking/unexpected changes coming from svelte-konva code if the respective prop is not bound. - The change brings svelte-konva API-wise more in line with other popular Svelte component libraries (such as [threlte](https://github.com/threlte/threlte)) +## Changes to `config` prop reactivity + +As the `config` prop has now been splitted into individual props there are some changes in how reactivity works when not using `staticConfig = true`. Consider the following svelte-konva v0 example: + +```svelte + + + + + + + +``` + +In the above code the `Rect` component is draggable. Each time it is dragged (on `dragend` Konva event) svelte-konva updates the `x` and `y` coordinates of the config prop. Due to how JavaScript works, this internal change also "leaks" into the `myConfig` object despite it not being bound (`bind:config={myConfig}`) due to JavaScript passing the config prop as reference (because it is an object). In the above example, the reactive code block with the `console.log` statement would never be triggered on drag end as Svelte 3/4 had no way of knowing that the value of `x` changed under the hood. It would only trigger if the `config` prop was bound in which case Svelte knows that the config prop could be changed by svelte-konva. Which is why it was recommended in the docs to always bind the config prop if not using `staticConfig = true` in order to avoid this confusing behavior. + +This behavior is now alltogether eliminated in svelte-konva v1 due to the splitted config prop. This now allows you to benefit from fine-grained reactivity without any internal svelte-konva changes "leaking" into the parent component. Directly migrated to Svelte 5 the same example would look like this (with runes): + +```svelte + + + + + + + +``` + +When dragging the `Rect` component now, svelte-konva still updates its internal state of the `x` and `y` coordinates on drag end. However, this time `myX` and `myY` variables are never updated by svelte-konva as they are not bound (They stay 100 and no reactive dependencies are triggered). Thus there is no "leaking" change. In case you want to keep your `myX` and `myY` variables automatically in sync with their acutal position after drag and transform of the `Rect` shape you simply have to bind them. This then allows the changes to the `x` and `y` prop by svelte-konva to propagate up into the `myX` and `myY` state as well as triggering any connected reactive code (such as the `$effect` in the above example). + +This now also enables fine-grained reactivity where you are able to run reactive code for individual changes to the `x`, `y`, ... props instead of everytime any property in the `config` object changed. In case you still need to be able to react to any change made by svelte-konva after transform or dragging you should use the `ondragend` and `ontransformend` event hooks of the svelte-konva component directly. + +### Changes to the `staticConfig` prop + +As the svelte-konva updates on drag and transform end are no more "leaking" into the parent component when the properties are not bound the use of the `staticConfig` prop changes slightly. The behavior of `staticConfig = true` in svelte-konva v0 can now be simply achieved by not binding any props in svelte-konva v1. Thus it is generally recommended to not use `staticConfig = true` for normal usage. When using `staticConfig = true` svelte-konva does not listen to the `dragend` and `transformend` event of the node and does not update its internal state. This can lead to slight performance improvements in case the user does not use any bindings. + ## Event handlers In Svelte v5 usage of the `on:event` syntax is deprecated. svelte-konva provides all Konva events now as callback props using the `on` syntax. The deprecated `on:event` syntax will no longer work for svelte-konva events: @@ -175,7 +226,3 @@ This has been changed due to Konva configuration props colliding with certain di ## Svelte runes-only mode svelte-konva is now fully compatible with Svelte's runes-only compile mode which means it will work out of the box for runes-only projects. It will also continue to work for all projects without runes-only mode enabled. - -## Changes to `config` prop reactivity - -TBD From 028b373740cd8c7957e9288ef6cba3d520dd252f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thierry=20K=C3=BChni?= Date: Fri, 2 Aug 2024 21:54:03 +0200 Subject: [PATCH 56/56] Update changelog --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00fde86..88b0d52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ # Unreleased +# v1.0.0-next.0 + +**breaking changes** please refer to the [migration guide](./docs/svelte-konva-v1-migration.md) for detailed examples on how to update. + +- Breaking: `config` prop is now splitted into individual props +- Breaking: Deprecated Svelte `on:event` syntax is no longer supported and replaced by event hooks named `on` +- Breaking: The Konva event object is now directly provided as payload on the new event hooks instead of being provided under the `detail` property of the payload +- Breaking: Changes in how reactivity works on dragend and transformend events with `staticConfig = false`. State changes are now only propagated if the corresponding prop is bound. +- Breaking: The Konva handle is now a component property that can be accessed directly on the component instance (read only) - Improved handle prop safety by preventing the user from overwriting the internal handle of the svelte-konva components (see #136) +- Breaking: Passing restProps to the wrapper div of the `Stage` component is no longer supported. Instead props can be passed to the wrapper div using the new `divWrapperProps` prop on the `Stage` component. +- svelte-konva is now a runes-only library and fully compatible with Svelte 5 runes-only projects - Update to SvelteKit v2 - Various dependency updates