@xenosystem/blocks 0.16.1 → 0.18.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/dist/edit/index.d.ts +39 -3
- package/dist/edit/index.js +32 -7
- package/package.json +3 -3
package/dist/edit/index.d.ts
CHANGED
|
@@ -6756,12 +6756,28 @@ interface XenoTreeGlyph {
|
|
|
6756
6756
|
* and another names lucide icons. A single `icon: string` field forces every consumer to guess
|
|
6757
6757
|
* which it is holding, and guessing renders `'📄'` as a missing-icon box.
|
|
6758
6758
|
*/
|
|
6759
|
+
/** What a node carries when dragged out of the panel (see `XenoTreeNode.dragOut`). */
|
|
6760
|
+
interface XenoTreeDragOut {
|
|
6761
|
+
kind: string;
|
|
6762
|
+
payload?: unknown;
|
|
6763
|
+
}
|
|
6759
6764
|
type XenoTreeIcon = {
|
|
6760
6765
|
kind: 'lucide';
|
|
6761
6766
|
name: string;
|
|
6762
6767
|
} | {
|
|
6763
6768
|
kind: 'text';
|
|
6764
6769
|
value: string;
|
|
6770
|
+
}
|
|
6771
|
+
/**
|
|
6772
|
+
* A thumbnail the HOST rendered — a data or blob URL — drawn in the row's icon slot by
|
|
6773
|
+
* `chrome/Thumb`. The panel decodes and fetches nothing (the no-pixel-capability rule stands; the
|
|
6774
|
+
* pixels are the host's). Default frame 44×32.
|
|
6775
|
+
*/
|
|
6776
|
+
| {
|
|
6777
|
+
kind: 'image';
|
|
6778
|
+
src: string;
|
|
6779
|
+
width?: number;
|
|
6780
|
+
height?: number;
|
|
6765
6781
|
};
|
|
6766
6782
|
/** What a node permits. Absent ⇒ permitted. */
|
|
6767
6783
|
interface XenoTreeCaps {
|
|
@@ -6842,6 +6858,15 @@ interface XenoTreeNode {
|
|
|
6842
6858
|
columns?: Record<string, string>;
|
|
6843
6859
|
/** Hover actions. */
|
|
6844
6860
|
actions?: XenoTreeAction[];
|
|
6861
|
+
/**
|
|
6862
|
+
* The node may be dragged OUT of the panel and dropped on the host's own surface — a library
|
|
6863
|
+
* component onto a canvas, a clip onto a timeline. `kind` is the host's vocabulary word
|
|
6864
|
+
* (`'component'`, `'clip'`); `payload` is carried back verbatim on the `dragOut` output. The drag
|
|
6865
|
+
* itself is the panel's pointer drag: when it is released outside the panel's rows, the panel
|
|
6866
|
+
* emits `dragOut` with the release point and the host decides what a drop there means. A node
|
|
6867
|
+
* without this is only reorderable inside the tree.
|
|
6868
|
+
*/
|
|
6869
|
+
dragOut?: XenoTreeDragOut;
|
|
6845
6870
|
/**
|
|
6846
6871
|
* A stable identity for the *thing* this node points at — a resolved real path, an inode, a
|
|
6847
6872
|
* document id.
|
|
@@ -6865,7 +6890,9 @@ interface XenoTreeNode {
|
|
|
6865
6890
|
title?: string;
|
|
6866
6891
|
}
|
|
6867
6892
|
/** Which adapter produced this source. Presentation hint + telemetry; never behaviour. */
|
|
6868
|
-
type XenoTreeSourceKind = 'scene-graph' | 'entity' | 'project-entities' | 'document-pages'
|
|
6893
|
+
type XenoTreeSourceKind = 'scene-graph' | 'entity' | 'project-entities' | 'document-pages'
|
|
6894
|
+
/** A library of reusable things — components, assets, presets — usually with `image` icons and `dragOut`. */
|
|
6895
|
+
| 'library' | 'filesystem' | 'derived-outline' | 'org' | 'custom';
|
|
6869
6896
|
/**
|
|
6870
6897
|
* The source-level lifecycle — one incumbent's six-state machine, hoisted.
|
|
6871
6898
|
*
|
|
@@ -7361,14 +7388,19 @@ declare class TreeController {
|
|
|
7361
7388
|
/** Update the hovered drop target. */
|
|
7362
7389
|
dragOver(targetId: string, offsetY: number): DropPosition;
|
|
7363
7390
|
/**
|
|
7364
|
-
* Complete the drag, emitting a `move` intent when the drop is legal
|
|
7391
|
+
* Complete the drag, emitting a `move` intent when the drop is legal — or, when the release was
|
|
7392
|
+
* OUTSIDE the panel (`outside` given) and every dragged node declares `dragOut` of one kind, a
|
|
7393
|
+
* `dragOut` event carrying the release point for the host to hit-test.
|
|
7365
7394
|
*
|
|
7366
7395
|
* A refused drop emits **nothing** — and the refusal that matters most is the descendant one,
|
|
7367
7396
|
* which lives in `@xenosystem/tree-core` because two shipping apps delete a whole subtree without it.
|
|
7368
7397
|
*
|
|
7369
7398
|
* @returns `true` if a move intent was emitted.
|
|
7370
7399
|
*/
|
|
7371
|
-
endDrag(
|
|
7400
|
+
endDrag(outside?: {
|
|
7401
|
+
clientX: number;
|
|
7402
|
+
clientY: number;
|
|
7403
|
+
}): boolean;
|
|
7372
7404
|
/** Abandon the drag. */
|
|
7373
7405
|
cancelDrag(): void;
|
|
7374
7406
|
/** Descendants of a node, through the shared recursive walk. */
|
|
@@ -7496,6 +7528,10 @@ interface IconHalf {
|
|
|
7496
7528
|
iconName: string | null;
|
|
7497
7529
|
/** Literal text (emoji) instead of a glyph. */
|
|
7498
7530
|
iconText: string | null;
|
|
7531
|
+
/** A host-rendered thumbnail (`chrome/Thumb`). */
|
|
7532
|
+
iconSrc: string | null;
|
|
7533
|
+
iconWidth: number;
|
|
7534
|
+
iconHeight: number;
|
|
7499
7535
|
}
|
|
7500
7536
|
interface TreeViewAction extends IconHalf {
|
|
7501
7537
|
key: string;
|
package/dist/edit/index.js
CHANGED
|
@@ -13114,16 +13114,29 @@ var TreeController = class {
|
|
|
13114
13114
|
return result.position;
|
|
13115
13115
|
}
|
|
13116
13116
|
/**
|
|
13117
|
-
* Complete the drag, emitting a `move` intent when the drop is legal
|
|
13117
|
+
* Complete the drag, emitting a `move` intent when the drop is legal — or, when the release was
|
|
13118
|
+
* OUTSIDE the panel (`outside` given) and every dragged node declares `dragOut` of one kind, a
|
|
13119
|
+
* `dragOut` event carrying the release point for the host to hit-test.
|
|
13118
13120
|
*
|
|
13119
13121
|
* A refused drop emits **nothing** — and the refusal that matters most is the descendant one,
|
|
13120
13122
|
* which lives in `@xenosystem/tree-core` because two shipping apps delete a whole subtree without it.
|
|
13121
13123
|
*
|
|
13122
13124
|
* @returns `true` if a move intent was emitted.
|
|
13123
13125
|
*/
|
|
13124
|
-
endDrag() {
|
|
13126
|
+
endDrag(outside) {
|
|
13125
13127
|
const drag = this.drag;
|
|
13126
13128
|
this.drag = null;
|
|
13129
|
+
if (drag && outside) {
|
|
13130
|
+
const nodes = drag.ids.map((id) => this.source?.nodes[id]).filter((n) => !!n);
|
|
13131
|
+
const outs = nodes.map((n) => n.dragOut).filter((d) => !!d);
|
|
13132
|
+
if (nodes.length > 0 && outs.length === nodes.length && outs.every((d) => d.kind === outs[0].kind)) {
|
|
13133
|
+
this.host.emit("dragOut", { ids: nodes.map((n) => n.id), kind: outs[0].kind, payloads: outs.map((d) => d.payload), clientX: outside.clientX, clientY: outside.clientY });
|
|
13134
|
+
this.notify();
|
|
13135
|
+
return true;
|
|
13136
|
+
}
|
|
13137
|
+
this.notify();
|
|
13138
|
+
return false;
|
|
13139
|
+
}
|
|
13127
13140
|
if (!drag || !drag.targetId || !drag.position) {
|
|
13128
13141
|
this.notify();
|
|
13129
13142
|
return false;
|
|
@@ -13248,6 +13261,12 @@ var treeManifest = {
|
|
|
13248
13261
|
schema: WELL_KNOWN_PORT_SCHEMAS8.TREE_OP,
|
|
13249
13262
|
description: "Everything the panel asks for \u2014 select, open, setExpanded, loadChildren, move, rename, create, delete, setProp, action. INTENTS ONLY: the host performs, pins ids, and pushes one undo entry."
|
|
13250
13263
|
},
|
|
13264
|
+
{
|
|
13265
|
+
id: "dragOut",
|
|
13266
|
+
name: "Dragged Out",
|
|
13267
|
+
type: "object",
|
|
13268
|
+
description: "{ ids, kind, payloads, clientX, clientY } \u2014 a pointer drag of nodes that declare `dragOut` was released OUTSIDE the panel. The host hit-tests its own surface at the point and performs the drop (place an instance, insert a clip); the panel places nothing. Nodes without `dragOut` never emit this."
|
|
13269
|
+
},
|
|
13251
13270
|
{
|
|
13252
13271
|
id: "selection",
|
|
13253
13272
|
name: "Selection",
|
|
@@ -13563,12 +13582,13 @@ import {
|
|
|
13563
13582
|
TextButton as TextButton7,
|
|
13564
13583
|
Toolbar as Toolbar7,
|
|
13565
13584
|
ToolbarGroup as ToolbarGroup5,
|
|
13566
|
-
VirtualWindow as VirtualWindow3
|
|
13585
|
+
VirtualWindow as VirtualWindow3,
|
|
13586
|
+
Thumb
|
|
13567
13587
|
} from "@xenosystem/components/chrome";
|
|
13568
13588
|
|
|
13569
13589
|
// src/edit/tree/declaration.ts
|
|
13570
13590
|
import { computeWindow as computeWindow3 } from "@xenosystem/tree-core";
|
|
13571
|
-
var iconHalf = (icon) => icon.kind === "text" ? { iconName: null, iconText: icon.value } : { iconName: icon.name, iconText: null };
|
|
13591
|
+
var iconHalf = (icon) => icon.kind === "text" ? { iconName: null, iconText: icon.value, iconSrc: null, iconWidth: 0, iconHeight: 0 } : icon.kind === "image" ? { iconName: null, iconText: null, iconSrc: icon.src, iconWidth: icon.width ?? 44, iconHeight: icon.height ?? 32 } : { iconName: icon.name, iconText: null, iconSrc: null, iconWidth: 0, iconHeight: 0 };
|
|
13572
13592
|
function treeViewState(c, options = {}) {
|
|
13573
13593
|
const { overscan = 6, showSearch = true, columns, emptyHint } = options;
|
|
13574
13594
|
const state = c.getState();
|
|
@@ -13750,6 +13770,7 @@ var nodeIcon = () => ({
|
|
|
13750
13770
|
component: "fragment",
|
|
13751
13771
|
children: [
|
|
13752
13772
|
{ component: "icons/TreeKind", when: { item: "iconName" }, props: { name: { item: "iconName" } } },
|
|
13773
|
+
{ component: "chrome/Thumb", when: { item: "iconSrc" }, props: { src: { item: "iconSrc" }, width: { item: "iconWidth" }, height: { item: "iconHeight" } } },
|
|
13753
13774
|
{ component: "chrome/Text", when: { item: "iconText" }, props: { role: { value: "caption" } }, children: [text10({ item: "iconText" })] }
|
|
13754
13775
|
]
|
|
13755
13776
|
});
|
|
@@ -13872,8 +13893,9 @@ function TreePanelView({ controller, ...options }) {
|
|
|
13872
13893
|
useSyncExternalStore10(controller.subscribe, controller.getState, controller.getState);
|
|
13873
13894
|
const view = treeViewState(controller, options);
|
|
13874
13895
|
const ui10 = (intent) => applyTreeUi(controller, intent, options);
|
|
13875
|
-
const icon = (name, textValue) => /* @__PURE__ */ jsxs11(Fragment9, { children: [
|
|
13896
|
+
const icon = (name, textValue, src = null, w = 0, h = 0) => /* @__PURE__ */ jsxs11(Fragment9, { children: [
|
|
13876
13897
|
name ? /* @__PURE__ */ jsx12(TreeIcon, { name }) : null,
|
|
13898
|
+
src ? /* @__PURE__ */ jsx12(Thumb, { src, width: w, height: h }) : null,
|
|
13877
13899
|
textValue ? /* @__PURE__ */ jsx12(Text9, { role: "caption", children: textValue }) : null
|
|
13878
13900
|
] });
|
|
13879
13901
|
const row2 = (r) => /* @__PURE__ */ jsx12(
|
|
@@ -13888,7 +13910,7 @@ function TreePanelView({ controller, ...options }) {
|
|
|
13888
13910
|
expanded: r.expanded,
|
|
13889
13911
|
dropHint: r.dropHint,
|
|
13890
13912
|
title: r.dropTitle,
|
|
13891
|
-
icon: icon(r.iconName, r.iconText),
|
|
13913
|
+
icon: icon(r.iconName, r.iconText, r.iconSrc, r.iconWidth, r.iconHeight),
|
|
13892
13914
|
label: /* @__PURE__ */ jsxs11(Fragment9, { children: [
|
|
13893
13915
|
r.renaming ? /* @__PURE__ */ jsx12(Input5, { autoFocus: true, value: r.draft, label: "Name", onChange: (value) => ui10({ kind: "renameDraft", value }), onBlur: () => ui10({ kind: "commitRename" }), onKeyDown: (e) => ui10({ kind: "renameKey", key: e.key }) }) : null,
|
|
13894
13916
|
!r.renaming ? r.label : null
|
|
@@ -13990,7 +14012,10 @@ function TreeScroller({ controller, children }) {
|
|
|
13990
14012
|
e.currentTarget.releasePointerCapture(e.pointerId);
|
|
13991
14013
|
} catch {
|
|
13992
14014
|
}
|
|
13993
|
-
if (press?.dragging)
|
|
14015
|
+
if (!press?.dragging) return;
|
|
14016
|
+
const r = scrollRef.current?.getBoundingClientRect();
|
|
14017
|
+
const inside = !!r && e.clientX >= r.left && e.clientX <= r.right && e.clientY >= r.top && e.clientY <= r.bottom;
|
|
14018
|
+
controller.endDrag(inside ? void 0 : { clientX: e.clientX, clientY: e.clientY });
|
|
13994
14019
|
},
|
|
13995
14020
|
[controller]
|
|
13996
14021
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenosystem/blocks",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "XENO Blocks — rung 3 of the front ladder: components composed into a contract-bearing unit (manifest: ports, intents, commands, agent surface), rendered by @xenosystem/workbench. ONE package, one subpath per family (/auth, /edit, /data, /time, /ops, /trust, /agent), one named export per block — XENO PACKAGE NAMING - STANDARD.md.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"peerDependencies": {
|
|
65
65
|
"@duckdb/duckdb-wasm": ">=1.28.0",
|
|
66
66
|
"@xenosystem/block-sdk": ">=0.3.4 <1",
|
|
67
|
-
"@xenosystem/components": ">=0.
|
|
67
|
+
"@xenosystem/components": ">=0.34.0 <1",
|
|
68
68
|
"@xenosystem/data-core": "^0.1.0",
|
|
69
69
|
"@xenosystem/elements": ">=0.0.1",
|
|
70
70
|
"@xenosystem/elements-react": ">=0.0.1",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"@types/react": "^19.0.0",
|
|
82
82
|
"@types/react-dom": "^19.0.0",
|
|
83
83
|
"@xenosystem/block-sdk": "^0.3.4",
|
|
84
|
-
"@xenosystem/components": "^0.
|
|
84
|
+
"@xenosystem/components": "^0.34.0",
|
|
85
85
|
"@xenosystem/data-core": "^0.1.0",
|
|
86
86
|
"@xenosystem/elements": "0.0.1",
|
|
87
87
|
"@xenosystem/elements-react": "0.0.1",
|