@ikenga/contract 0.6.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -11
- package/dist/canvas/Canvas.d.ts +7 -0
- package/dist/canvas/Canvas.d.ts.map +1 -0
- package/dist/canvas/Canvas.js +115 -0
- package/dist/canvas/Canvas.js.map +1 -0
- package/dist/canvas/canvas.css +579 -0
- package/dist/canvas/index.d.ts +7 -0
- package/dist/canvas/index.d.ts.map +1 -0
- package/dist/canvas/index.js +4 -0
- package/dist/canvas/index.js.map +1 -0
- package/dist/canvas/types.d.ts +45 -0
- package/dist/canvas/types.d.ts.map +1 -0
- package/dist/canvas/types.js +2 -0
- package/dist/canvas/types.js.map +1 -0
- package/dist/canvas/use-drag-snap.d.ts +33 -0
- package/dist/canvas/use-drag-snap.d.ts.map +1 -0
- package/dist/canvas/use-drag-snap.js +73 -0
- package/dist/canvas/use-drag-snap.js.map +1 -0
- package/dist/canvas/use-pan-zoom.d.ts +32 -0
- package/dist/canvas/use-pan-zoom.d.ts.map +1 -0
- package/dist/canvas/use-pan-zoom.js +161 -0
- package/dist/canvas/use-pan-zoom.js.map +1 -0
- package/dist/engine/index.d.ts +2 -0
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +2 -0
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/portability.d.ts +113 -0
- package/dist/engine/portability.d.ts.map +1 -0
- package/dist/engine/portability.js +17 -0
- package/dist/engine/portability.js.map +1 -0
- package/dist/engine/subagent-transcoder.d.ts +24 -0
- package/dist/engine/subagent-transcoder.d.ts.map +1 -0
- package/dist/engine/subagent-transcoder.js +341 -0
- package/dist/engine/subagent-transcoder.js.map +1 -0
- package/dist/engine.d.ts +574 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +85 -0
- package/dist/engine.js.map +1 -0
- package/dist/host-verbs.d.ts +194 -0
- package/dist/host-verbs.d.ts.map +1 -0
- package/dist/host-verbs.js +15 -0
- package/dist/host-verbs.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +376 -19
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +95 -4
- package/dist/manifest.js.map +1 -1
- package/dist/registry.d.ts +364 -36
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +9 -0
- package/dist/registry.js.map +1 -1
- package/dist/scopes.js +1 -1
- package/dist/scopes.js.map +1 -1
- package/package.json +36 -10
- package/schemas/registry/index-v1.json +11 -0
- package/src/canvas/Canvas.tsx +161 -0
- package/src/canvas/canvas.css +579 -0
- package/src/canvas/index.ts +14 -0
- package/src/canvas/types.ts +48 -0
- package/src/canvas/use-drag-snap.ts +107 -0
- package/src/canvas/use-pan-zoom.ts +211 -0
- package/src/engine/index.ts +2 -0
- package/src/engine/portability.ts +123 -0
- package/src/engine/subagent-transcoder.test.ts +306 -0
- package/src/engine/subagent-transcoder.ts +333 -0
- package/src/host-verbs.ts +207 -0
- package/src/index.ts +1 -0
- package/src/manifest.test.ts +97 -0
- package/src/manifest.ts +109 -4
- package/src/registry.ts +9 -0
- package/src/scopes.ts +1 -1
package/dist/registry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAeA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,uBAAuB,EAAG,CAAU,CAAC;AAIlD;;;;GAIG;AACH,eAAO,MAAM,YAAY;IACvB,4DAA4D;;IAE5D,0DAA0D;;;;;;;;EAE1D,CAAC;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;EAGjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE,eAAO,MAAM,gBAAgB;IAC3B,4BAA4B;;IAE5B,iDAAiD;;IAEjD,yEAAyE;;IAEzE,2DAA2D;;IAE3D,mFAAmF;;IAEnF,4DAA4D
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/registry.js
CHANGED
|
@@ -92,6 +92,15 @@ export const RegistryEntrySchema = z.object({
|
|
|
92
92
|
* Lets the shell render a thumb without fetching the per-pkg detail file.
|
|
93
93
|
*/
|
|
94
94
|
screenshot: z.string().url().optional(),
|
|
95
|
+
/**
|
|
96
|
+
* Catalog visibility. `"hidden"` keeps the pkg installable by exact name
|
|
97
|
+
* (CLI `add`/`update`, registry install, update detection) but omits it
|
|
98
|
+
* from the default browse/catalog surfaces — used for dev/test fixtures
|
|
99
|
+
* and scaffolds (e.g. `pkg-hello`, `pkg-engine-noop`, the cursor-agent
|
|
100
|
+
* scaffold). Absent ⇒ treated as `"public"`. Set by the publish pipeline's
|
|
101
|
+
* curation step (`ikenga-pkgs/scripts/update-registry-index.mjs`).
|
|
102
|
+
*/
|
|
103
|
+
visibility: z.enum(['public', 'hidden']).optional(),
|
|
95
104
|
});
|
|
96
105
|
export const RegistryIndexSchema = z.object({
|
|
97
106
|
$schemaVersion: z.literal(REGISTRY_SCHEMA_VERSION),
|
package/dist/registry.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,kDAAkD;AAClD,EAAE;AACF,2EAA2E;AAC3E,qEAAqE;AACrE,yEAAyE;AACzE,qEAAqE;AACrE,uEAAuE;AACvE,UAAU;AACV,EAAE;AACF,2EAA2E;AAC3E,2EAA2E;AAC3E,qEAAqE;AACrE,mCAAmC;AAEnC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAU,CAAC;AAElD,gEAAgE;AAEhE;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC,4DAA4D;IAC5D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,0DAA0D;IAC1D,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAC;AAGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACrB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,4BAA4B;IAC5B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,iDAAiD;IACjD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE;IACvB,yEAAyE;IACzE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IACzB,2DAA2D;IAC3D,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,mFAAmF;IACnF,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;IAC/C,4DAA4D;IAC5D,QAAQ,EAAE,cAAc;IACxB,gFAAgF;IAChF,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;IACvC;;;;;;OAMG;IACH,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACzD,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,cAAc,EAAE,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC;IAClD,4DAA4D;IAC5D,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,sDAAsD;IACtD,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,mDAAmD;IACnD,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CAC3C,CAAC,CAAC;AAGH,gDAAgD;AAEhD,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,qBAAqB;IACrB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,qBAAqB;IACrB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB;;;;;OAKG;IACH,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,4EAA4E;IAC5E,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAClC,2EAA2E;IAC3E,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B;;;;OAIG;IACH,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/scopes.js
CHANGED
|
@@ -27,7 +27,7 @@ export const SCOPE_CATALOGUE = [
|
|
|
27
27
|
{ scope: 'fs:read', description: 'Read files inside the shell-managed sandbox.' },
|
|
28
28
|
{ scope: 'fs:write', description: 'Write files inside the shell-managed sandbox.', sensitive: true },
|
|
29
29
|
// engine
|
|
30
|
-
{ scope: 'engine:invoke', description: 'Start sessions and stream from the active AI engine.' },
|
|
30
|
+
{ scope: 'engine:invoke', description: 'Start sessions and stream from the active AI engine.', sensitive: true },
|
|
31
31
|
{ scope: 'engine:register_mcp', description: 'Register additional MCP servers with the engine.', sensitive: true },
|
|
32
32
|
// shell chrome
|
|
33
33
|
{ scope: 'shell:notify', description: 'Show notifications in the shell UI.' },
|
package/dist/scopes.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scopes.js","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,8DAA8D;AAC9D,2DAA2D;AAC3D,EAAE;AACF,2EAA2E;AAC3E,EAAE;AACF,oDAAoD;AACpD,sDAAsD;AACtD,yEAAyE;AASzE,MAAM,CAAC,MAAM,eAAe,GAAe;IACzC,WAAW;IACX,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,0CAA0C,EAAE;IAEnF,QAAQ;IACR,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,sBAAsB,EAAE;IAC5D,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,iCAAiC,EAAE;IAExE,WAAW;IACX,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,8BAA8B,EAAE;IACvE,EAAE,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,4BAA4B,EAAE,SAAS,EAAE,IAAI,EAAE;IAEvF,QAAQ;IACR,EAAE,KAAK,EAAE,mBAAmB,EAAE,WAAW,EAAE,iCAAiC,EAAE;IAC9E,EAAE,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,0BAA0B,EAAE;IACxE,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,8CAA8C,EAAE,SAAS,EAAE,IAAI,EAAE;IAErG,SAAS;IACT,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,sCAAsC,EAAE;IAC7E,EAAE,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,uCAAuC,EAAE,SAAS,EAAE,IAAI,EAAE;IAElG,8BAA8B;IAC9B,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,8CAA8C,EAAE;IACjF,EAAE,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,+CAA+C,EAAE,SAAS,EAAE,IAAI,EAAE;IAEpG,SAAS;IACT,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,sDAAsD,EAAE;
|
|
1
|
+
{"version":3,"file":"scopes.js","sourceRoot":"","sources":["../src/scopes.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ikenga/contract",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Shared contract for the Ikenga pkg system: manifest schema, RPC types, Engine interface, capability scopes.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -39,6 +39,11 @@
|
|
|
39
39
|
"types": "./dist/artifact.d.ts",
|
|
40
40
|
"import": "./dist/artifact.js"
|
|
41
41
|
},
|
|
42
|
+
"./canvas": {
|
|
43
|
+
"types": "./dist/canvas/index.d.ts",
|
|
44
|
+
"import": "./dist/canvas/index.js"
|
|
45
|
+
},
|
|
46
|
+
"./canvas/canvas.css": "./dist/canvas/canvas.css",
|
|
42
47
|
"./registry": {
|
|
43
48
|
"types": "./dist/registry.d.ts",
|
|
44
49
|
"import": "./dist/registry.js"
|
|
@@ -46,7 +51,12 @@
|
|
|
46
51
|
"./browser": {
|
|
47
52
|
"types": "./dist/browser.d.ts",
|
|
48
53
|
"import": "./dist/browser.js"
|
|
49
|
-
}
|
|
54
|
+
},
|
|
55
|
+
"./canvas": {
|
|
56
|
+
"types": "./dist/canvas/index.d.ts",
|
|
57
|
+
"import": "./dist/canvas/index.js"
|
|
58
|
+
},
|
|
59
|
+
"./canvas/canvas.css": "./dist/canvas/canvas.css"
|
|
50
60
|
},
|
|
51
61
|
"files": [
|
|
52
62
|
"dist",
|
|
@@ -54,22 +64,38 @@
|
|
|
54
64
|
"schemas",
|
|
55
65
|
"README.md"
|
|
56
66
|
],
|
|
67
|
+
"scripts": {
|
|
68
|
+
"build": "tsc -p tsconfig.json && node scripts/copy-assets.mjs",
|
|
69
|
+
"dev": "tsc -p tsconfig.json --watch",
|
|
70
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
71
|
+
"generate:schemas": "node scripts/generate-schemas.mjs",
|
|
72
|
+
"test": "node --test --import=tsx 'src/**/*.test.ts'"
|
|
73
|
+
},
|
|
57
74
|
"dependencies": {
|
|
58
75
|
"zod": "^3.23.0",
|
|
59
76
|
"zod-to-json-schema": "^3.25.2"
|
|
60
77
|
},
|
|
78
|
+
"peerDependencies": {
|
|
79
|
+
"react": "^19.0.0",
|
|
80
|
+
"react-dom": "^19.0.0"
|
|
81
|
+
},
|
|
82
|
+
"peerDependenciesMeta": {
|
|
83
|
+
"react": {
|
|
84
|
+
"optional": true
|
|
85
|
+
},
|
|
86
|
+
"react-dom": {
|
|
87
|
+
"optional": true
|
|
88
|
+
}
|
|
89
|
+
},
|
|
61
90
|
"devDependencies": {
|
|
91
|
+
"@types/react": "^19.0.0",
|
|
92
|
+
"@types/react-dom": "^19.0.0",
|
|
93
|
+
"react": "^19.0.0",
|
|
94
|
+
"react-dom": "^19.0.0",
|
|
62
95
|
"tsx": "^4.21.0",
|
|
63
96
|
"typescript": "^5.4.0"
|
|
64
97
|
},
|
|
65
98
|
"publishConfig": {
|
|
66
99
|
"access": "public"
|
|
67
|
-
},
|
|
68
|
-
"scripts": {
|
|
69
|
-
"build": "tsc -p tsconfig.json",
|
|
70
|
-
"dev": "tsc -p tsconfig.json --watch",
|
|
71
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
72
|
-
"generate:schemas": "node scripts/generate-schemas.mjs",
|
|
73
|
-
"test": "node --test --import=tsx 'src/**/*.test.ts'"
|
|
74
100
|
}
|
|
75
|
-
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// <Canvas> — the reusable free-form pan/zoom/grid-snap surface extracted from
|
|
2
|
+
// the shell home page. Composes usePanZoom + useDragSnap and renders the
|
|
3
|
+
// stage + items; the consumer supplies item content via `renderItem` and owns
|
|
4
|
+
// `layout` / `editMode` / `selectedId` (all controlled props).
|
|
5
|
+
//
|
|
6
|
+
// Item DOM: Canvas does NOT wrap items in an extra positioned div. It clones
|
|
7
|
+
// the element `renderItem` returns and injects `data-id`, the canvas-space
|
|
8
|
+
// left/top/width geometry, and the `is-selected` class onto it. So the
|
|
9
|
+
// consumer's own card element stays the positioned box — DOM shape matches the
|
|
10
|
+
// pre-extraction home exactly. The cloned element must carry its base class
|
|
11
|
+
// (e.g. `home-widget` / `home-greeting`) and `position: absolute` (the bundled
|
|
12
|
+
// canvas.css supplies the latter for the home classes).
|
|
13
|
+
//
|
|
14
|
+
// CSS: canvas.css is imported as a side effect here, so any bundler following
|
|
15
|
+
// the import graph (Vite in a pkg, the shell's build) inlines it. Its
|
|
16
|
+
// var(--*) tokens resolve against the host document — inside a Vite/iframe pkg
|
|
17
|
+
// the consumer must import @ikenga/tokens at entry (Round 8 / G21).
|
|
18
|
+
|
|
19
|
+
import {
|
|
20
|
+
cloneElement,
|
|
21
|
+
forwardRef,
|
|
22
|
+
isValidElement,
|
|
23
|
+
useImperativeHandle,
|
|
24
|
+
type CSSProperties,
|
|
25
|
+
type ReactElement,
|
|
26
|
+
} from 'react';
|
|
27
|
+
import './canvas.css';
|
|
28
|
+
import type { CanvasHandle, CanvasProps, ItemId, ItemRenderState } from './types.js';
|
|
29
|
+
import { usePanZoom } from './use-pan-zoom.js';
|
|
30
|
+
import { useDragSnap } from './use-drag-snap.js';
|
|
31
|
+
|
|
32
|
+
// Hit-test class roots Canvas owns. Anything matching these inside the canvas
|
|
33
|
+
// counts as a draggable item; the bar/palette are excluded from gestures.
|
|
34
|
+
const ITEM_SELECTOR = '.home-widget, .home-greeting, [data-canvas-item]';
|
|
35
|
+
const BAR_SELECTOR = '.ikenga-canvas-bar';
|
|
36
|
+
const PALETTE_SELECTOR = '.home-palette';
|
|
37
|
+
|
|
38
|
+
function CanvasInner<T>(props: CanvasProps<T>, ref: React.Ref<CanvasHandle>) {
|
|
39
|
+
const {
|
|
40
|
+
items,
|
|
41
|
+
itemId,
|
|
42
|
+
itemKind,
|
|
43
|
+
layout,
|
|
44
|
+
viewport,
|
|
45
|
+
editMode,
|
|
46
|
+
selectedId = null,
|
|
47
|
+
gridSnap = 12,
|
|
48
|
+
renderItem,
|
|
49
|
+
onLayoutChange,
|
|
50
|
+
onViewportChange,
|
|
51
|
+
onEditModeChange,
|
|
52
|
+
onSelectionChange,
|
|
53
|
+
autoFitOnResize = true,
|
|
54
|
+
className,
|
|
55
|
+
} = props;
|
|
56
|
+
|
|
57
|
+
const { pan, autoFit, canvasRef, stageRef, spaceDown, beginPan, isPanning } = usePanZoom({
|
|
58
|
+
layout,
|
|
59
|
+
editMode,
|
|
60
|
+
autoFitOnResize,
|
|
61
|
+
onViewportChange,
|
|
62
|
+
onEditModeChange,
|
|
63
|
+
onSelectionChange,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const { beginDrag } = useDragSnap({
|
|
67
|
+
layout,
|
|
68
|
+
gridSnap,
|
|
69
|
+
scale: viewport.scale,
|
|
70
|
+
onLayoutChange,
|
|
71
|
+
stageRef,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
useImperativeHandle(ref, () => ({ autoFit }), [autoFit]);
|
|
75
|
+
|
|
76
|
+
function onMouseDown(e: React.MouseEvent<HTMLDivElement>) {
|
|
77
|
+
const target = e.target as HTMLElement;
|
|
78
|
+
if (target.closest(BAR_SELECTOR) || target.closest(PALETTE_SELECTOR)) return;
|
|
79
|
+
const middle = e.button === 1;
|
|
80
|
+
const itemEl = target.closest(ITEM_SELECTOR) as HTMLElement | null;
|
|
81
|
+
|
|
82
|
+
if (editMode && itemEl && !middle && !spaceDown.current) {
|
|
83
|
+
const id = itemEl.getAttribute('data-id') as ItemId | null;
|
|
84
|
+
if (!id) return;
|
|
85
|
+
onSelectionChange?.(id);
|
|
86
|
+
beginDrag(id, e.clientX, e.clientY);
|
|
87
|
+
e.preventDefault();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (middle || spaceDown.current || (!editMode && !itemEl)) {
|
|
91
|
+
beginPan(e.clientX, e.clientY);
|
|
92
|
+
e.preventDefault();
|
|
93
|
+
}
|
|
94
|
+
if (editMode && !itemEl) onSelectionChange?.(null);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function onDoubleClick(e: React.MouseEvent<HTMLDivElement>) {
|
|
98
|
+
const t = e.target as HTMLElement;
|
|
99
|
+
if (t.closest(ITEM_SELECTOR) || t.closest(BAR_SELECTOR) || t.closest(PALETTE_SELECTOR)) return;
|
|
100
|
+
autoFit(true);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
const transform = `translate(${pan.x}px, ${pan.y}px) scale(${pan.scale})`;
|
|
104
|
+
|
|
105
|
+
return (
|
|
106
|
+
<div
|
|
107
|
+
ref={canvasRef}
|
|
108
|
+
className={className ? `ikenga-canvas ${className}` : 'ikenga-canvas'}
|
|
109
|
+
data-mode-edit={editMode ? 'true' : 'false'}
|
|
110
|
+
onMouseDown={onMouseDown}
|
|
111
|
+
onDoubleClick={onDoubleClick}
|
|
112
|
+
>
|
|
113
|
+
<div className="ikenga-canvas-grain" />
|
|
114
|
+
|
|
115
|
+
<div ref={stageRef} className="ikenga-canvas-stage" style={{ transform }}>
|
|
116
|
+
{items.map((item) => {
|
|
117
|
+
const id = itemId(item);
|
|
118
|
+
const placement = layout[id];
|
|
119
|
+
if (!placement) return null;
|
|
120
|
+
const isSelected = selectedId === id;
|
|
121
|
+
const state: ItemRenderState = {
|
|
122
|
+
id,
|
|
123
|
+
kind: itemKind(item),
|
|
124
|
+
placement,
|
|
125
|
+
isSelected,
|
|
126
|
+
isEditMode: editMode,
|
|
127
|
+
};
|
|
128
|
+
const node = renderItem(item, state);
|
|
129
|
+
if (!isValidElement(node)) return node;
|
|
130
|
+
const el = node as ReactElement<{ style?: CSSProperties; className?: string }>;
|
|
131
|
+
// Inject geometry under the consumer's own style so renderItem can
|
|
132
|
+
// still override (e.g. minHeight vs height for the naked greeting).
|
|
133
|
+
const injected: CSSProperties = {
|
|
134
|
+
left: placement.x,
|
|
135
|
+
top: placement.y,
|
|
136
|
+
width: placement.w,
|
|
137
|
+
...el.props.style,
|
|
138
|
+
};
|
|
139
|
+
// Append the selection class without clobbering the consumer's.
|
|
140
|
+
const baseClass = el.props.className ?? '';
|
|
141
|
+
const className = isSelected ? `${baseClass} is-selected`.trim() : baseClass;
|
|
142
|
+
return cloneElement(el, {
|
|
143
|
+
key: id,
|
|
144
|
+
'data-id': id,
|
|
145
|
+
style: injected,
|
|
146
|
+
className,
|
|
147
|
+
} as Partial<typeof el.props> & { key: string; 'data-id': string });
|
|
148
|
+
})}
|
|
149
|
+
</div>
|
|
150
|
+
|
|
151
|
+
{props.children}
|
|
152
|
+
</div>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// forwardRef can't preserve the <T> generic through its typing, so we cast the
|
|
157
|
+
// wrapped component back to a generic-aware signature. Callers get full
|
|
158
|
+
// inference on CanvasProps<T>.
|
|
159
|
+
export const Canvas = forwardRef(CanvasInner) as <T>(
|
|
160
|
+
props: CanvasProps<T> & { ref?: React.Ref<CanvasHandle> }
|
|
161
|
+
) => ReactElement;
|