@lupinum/vue-board 0.1.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/LICENSE +21 -0
- package/README.md +61 -0
- package/dist/components/BoardBoxSelect.d.vue.ts +16 -0
- package/dist/components/BoardGrid.d.vue.ts +3 -0
- package/dist/components/BoardNode.d.vue.ts +35 -0
- package/dist/components/BoardNodeHandle.d.vue.ts +8 -0
- package/dist/components/BoardRoot.d.vue.ts +139 -0
- package/dist/components/BoardSelectionToolbar.d.vue.ts +3 -0
- package/dist/components/BoardSnapGuides.d.vue.ts +3 -0
- package/dist/components/BoardViewport.d.vue.ts +13 -0
- package/dist/composables/runBoardCommand.d.ts +3 -0
- package/dist/composables/useKeyboardShortcuts.d.ts +20 -0
- package/dist/composables/useLodCulling.d.ts +20 -0
- package/dist/composables/usePointerInteraction.d.ts +24 -0
- package/dist/composables/useResolvedGrid.d.ts +14 -0
- package/dist/composables/useViewportSize.d.ts +19 -0
- package/dist/context.d.ts +18 -0
- package/dist/eventTargets.d.ts +4 -0
- package/dist/grid.d.ts +22 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.js +1180 -0
- package/dist/minimap.d.ts +82 -0
- package/dist/minimap.js +192 -0
- package/dist/nodeColors.d.ts +10 -0
- package/dist/useBoardEngine-GWeHBmOy.js +128 -0
- package/dist/useBoardEngine.d.ts +52 -0
- package/package.json +56 -0
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type ComputedRef, type MaybeRefOrGetter, type PropType, type SlotsType, type VNode } from 'vue';
|
|
2
|
+
import { type Bounds, type BoardEngine, type BoardNode, type Point } from '@lupinum/board-core';
|
|
3
|
+
/** Sizing options for the minimap composable and component. */
|
|
4
|
+
export interface MinimapOptions {
|
|
5
|
+
width?: MaybeRefOrGetter<number>;
|
|
6
|
+
height?: MaybeRefOrGetter<number>;
|
|
7
|
+
padding?: MaybeRefOrGetter<number>;
|
|
8
|
+
}
|
|
9
|
+
export interface MinimapSlotProps {
|
|
10
|
+
nodes: Array<{
|
|
11
|
+
node: BoardNode;
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
}>;
|
|
17
|
+
viewport: {
|
|
18
|
+
x: number;
|
|
19
|
+
y: number;
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Project board content and the active viewport into minimap coordinates.
|
|
26
|
+
*
|
|
27
|
+
* Returns derived node rectangles, the current viewport rectangle, and a
|
|
28
|
+
* helper that pans the main board camera from minimap pointer input.
|
|
29
|
+
*/
|
|
30
|
+
export declare function useBoardMinimap(engine: BoardEngine, options?: MinimapOptions): {
|
|
31
|
+
bounds: ComputedRef<Bounds>;
|
|
32
|
+
viewportRect: ComputedRef<{
|
|
33
|
+
x: number;
|
|
34
|
+
y: number;
|
|
35
|
+
width: number;
|
|
36
|
+
height: number;
|
|
37
|
+
}>;
|
|
38
|
+
minimapNodes: ComputedRef<Array<{
|
|
39
|
+
node: BoardNode;
|
|
40
|
+
x: number;
|
|
41
|
+
y: number;
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
}>>;
|
|
45
|
+
panToMinimapPoint: (point: Point) => Promise<void>;
|
|
46
|
+
};
|
|
47
|
+
/** Render a clickable, draggable minimap for the current board engine. */
|
|
48
|
+
export declare const BoardMinimap: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
49
|
+
engine: {
|
|
50
|
+
type: PropType<BoardEngine | null>;
|
|
51
|
+
default: null;
|
|
52
|
+
};
|
|
53
|
+
width: {
|
|
54
|
+
type: NumberConstructor;
|
|
55
|
+
default: number;
|
|
56
|
+
};
|
|
57
|
+
height: {
|
|
58
|
+
type: NumberConstructor;
|
|
59
|
+
default: number;
|
|
60
|
+
};
|
|
61
|
+
}>, () => VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
62
|
+
[key: string]: any;
|
|
63
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
64
|
+
engine: {
|
|
65
|
+
type: PropType<BoardEngine | null>;
|
|
66
|
+
default: null;
|
|
67
|
+
};
|
|
68
|
+
width: {
|
|
69
|
+
type: NumberConstructor;
|
|
70
|
+
default: number;
|
|
71
|
+
};
|
|
72
|
+
height: {
|
|
73
|
+
type: NumberConstructor;
|
|
74
|
+
default: number;
|
|
75
|
+
};
|
|
76
|
+
}>> & Readonly<{}>, {
|
|
77
|
+
engine: BoardEngine<import("@lupinum/board-core").BoardPluginApis, {}> | null;
|
|
78
|
+
width: number;
|
|
79
|
+
height: number;
|
|
80
|
+
}, SlotsType<{
|
|
81
|
+
default?: (props: MinimapSlotProps) => VNode[];
|
|
82
|
+
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
package/dist/minimap.js
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { defineComponent as P, onScopeDispose as Y, h as g, shallowRef as M, getCurrentInstance as k, onMounted as B, computed as c, toValue as X } from "vue";
|
|
2
|
+
import { getVisibleBounds as C } from "@lupinum/board-core";
|
|
3
|
+
import { b as R } from "./useBoardEngine-GWeHBmOy.js";
|
|
4
|
+
function L(a, v = {}) {
|
|
5
|
+
const d = M(a.$camera.get()), r = M(a.$nodes.get()), u = M(a.getViewportSize()), m = [];
|
|
6
|
+
function w() {
|
|
7
|
+
m.push(
|
|
8
|
+
a.$camera.subscribe((e) => {
|
|
9
|
+
d.value = e;
|
|
10
|
+
}),
|
|
11
|
+
a.$nodes.subscribe((e) => {
|
|
12
|
+
r.value = e;
|
|
13
|
+
}),
|
|
14
|
+
a.on("viewport:change", (e) => {
|
|
15
|
+
u.value = e;
|
|
16
|
+
})
|
|
17
|
+
), d.value = a.$camera.get(), r.value = a.$nodes.get(), u.value = a.getViewportSize();
|
|
18
|
+
}
|
|
19
|
+
k() ? B(w) : w(), Y(() => {
|
|
20
|
+
for (const e of m)
|
|
21
|
+
e();
|
|
22
|
+
});
|
|
23
|
+
const x = c(() => X(v.width ?? 200)), y = c(() => X(v.height ?? 140)), t = c(() => X(v.padding ?? 24)), o = c(() => {
|
|
24
|
+
let e = !1, l = 1 / 0, n = 1 / 0, f = -1 / 0, b = -1 / 0;
|
|
25
|
+
for (const p of r.value.values())
|
|
26
|
+
e = !0, l = Math.min(l, p.x), n = Math.min(n, p.y), f = Math.max(f, p.x + p.width), b = Math.max(b, p.y + p.height);
|
|
27
|
+
return e ? {
|
|
28
|
+
minX: l - t.value,
|
|
29
|
+
minY: n - t.value,
|
|
30
|
+
maxX: f + t.value,
|
|
31
|
+
maxY: b + t.value
|
|
32
|
+
} : { minX: -500, minY: -500, maxX: 500, maxY: 500 };
|
|
33
|
+
}), i = c(() => {
|
|
34
|
+
const e = o.value;
|
|
35
|
+
return Math.min(
|
|
36
|
+
x.value / Math.max(1, e.maxX - e.minX),
|
|
37
|
+
y.value / Math.max(1, e.maxY - e.minY)
|
|
38
|
+
);
|
|
39
|
+
}), s = c(() => {
|
|
40
|
+
const e = o.value, l = (e.maxX - e.minX) * i.value, n = (e.maxY - e.minY) * i.value;
|
|
41
|
+
return {
|
|
42
|
+
x: (x.value - l) / 2,
|
|
43
|
+
y: (y.value - n) / 2
|
|
44
|
+
};
|
|
45
|
+
}), h = c(() => {
|
|
46
|
+
const e = o.value, l = s.value;
|
|
47
|
+
return Array.from(r.value.values()).map((n) => ({
|
|
48
|
+
node: n,
|
|
49
|
+
x: (n.x - e.minX) * i.value + l.x,
|
|
50
|
+
y: (n.y - e.minY) * i.value + l.y,
|
|
51
|
+
width: Math.max(2, n.width * i.value),
|
|
52
|
+
height: Math.max(2, n.height * i.value)
|
|
53
|
+
}));
|
|
54
|
+
}), $ = c(() => {
|
|
55
|
+
const e = o.value, l = s.value, n = C(
|
|
56
|
+
u.value.x,
|
|
57
|
+
u.value.y,
|
|
58
|
+
d.value
|
|
59
|
+
);
|
|
60
|
+
return {
|
|
61
|
+
x: (n.minX - e.minX) * i.value + l.x,
|
|
62
|
+
y: (n.minY - e.minY) * i.value + l.y,
|
|
63
|
+
width: Math.max(6, (n.maxX - n.minX) * i.value),
|
|
64
|
+
height: Math.max(6, (n.maxY - n.minY) * i.value)
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
async function I(e) {
|
|
68
|
+
const l = d.value, n = s.value, f = {
|
|
69
|
+
x: o.value.minX + (e.x - n.x) / i.value - u.value.x / (2 * l.z),
|
|
70
|
+
y: o.value.minY + (e.y - n.y) / i.value - u.value.y / (2 * l.z)
|
|
71
|
+
};
|
|
72
|
+
await a.panTo(f, !1);
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
bounds: o,
|
|
76
|
+
viewportRect: $,
|
|
77
|
+
minimapNodes: h,
|
|
78
|
+
panToMinimapPoint: I
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const T = P({
|
|
82
|
+
name: "BoardMinimap",
|
|
83
|
+
slots: Object,
|
|
84
|
+
props: {
|
|
85
|
+
engine: {
|
|
86
|
+
type: Object,
|
|
87
|
+
default: null
|
|
88
|
+
},
|
|
89
|
+
width: {
|
|
90
|
+
type: Number,
|
|
91
|
+
default: 200
|
|
92
|
+
},
|
|
93
|
+
height: {
|
|
94
|
+
type: Number,
|
|
95
|
+
default: 140
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
setup(a, { slots: v }) {
|
|
99
|
+
const d = a.engine ?? R().engine, r = L(d, {
|
|
100
|
+
width: () => a.width,
|
|
101
|
+
height: () => a.height
|
|
102
|
+
});
|
|
103
|
+
let u = null, m = () => {
|
|
104
|
+
};
|
|
105
|
+
Y(() => {
|
|
106
|
+
m();
|
|
107
|
+
});
|
|
108
|
+
function w(t, o) {
|
|
109
|
+
const i = t.getBoundingClientRect();
|
|
110
|
+
return {
|
|
111
|
+
x: o.clientX - i.left,
|
|
112
|
+
y: o.clientY - i.top
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function x(t) {
|
|
116
|
+
t.stopPropagation();
|
|
117
|
+
const o = t.currentTarget;
|
|
118
|
+
o.setPointerCapture?.(t.pointerId), u = t.pointerId, r.panToMinimapPoint(w(o, t));
|
|
119
|
+
const i = (h) => {
|
|
120
|
+
h.pointerId === u && r.panToMinimapPoint(w(o, h));
|
|
121
|
+
}, s = (h) => {
|
|
122
|
+
h.pointerId === u && (o.releasePointerCapture?.(h.pointerId), u = null, m());
|
|
123
|
+
};
|
|
124
|
+
m(), window.addEventListener("pointermove", i), window.addEventListener("pointerup", s), window.addEventListener("pointercancel", s), m = () => {
|
|
125
|
+
window.removeEventListener("pointermove", i), window.removeEventListener("pointerup", s), window.removeEventListener("pointercancel", s);
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function y(t) {
|
|
129
|
+
const o = t.shiftKey ? 100 : 24, i = t.key === "ArrowLeft" ? { x: -o, y: 0 } : t.key === "ArrowRight" ? { x: o, y: 0 } : t.key === "ArrowUp" ? { x: 0, y: -o } : t.key === "ArrowDown" ? { x: 0, y: o } : null;
|
|
130
|
+
i && (t.preventDefault(), t.stopPropagation(), d.panBy(i.x, i.y));
|
|
131
|
+
}
|
|
132
|
+
return () => g(
|
|
133
|
+
"div",
|
|
134
|
+
{
|
|
135
|
+
class: "board-minimap",
|
|
136
|
+
"data-board-interactive": "true",
|
|
137
|
+
tabindex: 0,
|
|
138
|
+
role: "region",
|
|
139
|
+
"aria-label": "Board minimap. Use arrow keys to pan.",
|
|
140
|
+
style: {
|
|
141
|
+
position: "relative",
|
|
142
|
+
width: `${a.width}px`,
|
|
143
|
+
height: `${a.height}px`,
|
|
144
|
+
overflow: "hidden"
|
|
145
|
+
},
|
|
146
|
+
onPointerdown: x,
|
|
147
|
+
onKeydown: y
|
|
148
|
+
},
|
|
149
|
+
[
|
|
150
|
+
v.default ? v.default({
|
|
151
|
+
nodes: r.minimapNodes.value,
|
|
152
|
+
viewport: r.viewportRect.value
|
|
153
|
+
}) : [
|
|
154
|
+
g(
|
|
155
|
+
"svg",
|
|
156
|
+
{
|
|
157
|
+
width: a.width,
|
|
158
|
+
height: a.height,
|
|
159
|
+
viewBox: `0 0 ${a.width} ${a.height}`,
|
|
160
|
+
style: { display: "block" },
|
|
161
|
+
"aria-hidden": "true"
|
|
162
|
+
},
|
|
163
|
+
[
|
|
164
|
+
g("path", {
|
|
165
|
+
d: r.minimapNodes.value.map(
|
|
166
|
+
(t) => `M${t.x},${t.y}h${t.width}v${t.height}h-${t.width}Z`
|
|
167
|
+
).join(""),
|
|
168
|
+
fill: "currentColor",
|
|
169
|
+
opacity: 0.22,
|
|
170
|
+
stroke: "currentColor",
|
|
171
|
+
"stroke-width": 0.75
|
|
172
|
+
}),
|
|
173
|
+
g("rect", {
|
|
174
|
+
x: r.viewportRect.value.x,
|
|
175
|
+
y: r.viewportRect.value.y,
|
|
176
|
+
width: r.viewportRect.value.width,
|
|
177
|
+
height: r.viewportRect.value.height,
|
|
178
|
+
fill: "none",
|
|
179
|
+
stroke: "currentColor",
|
|
180
|
+
"stroke-width": 1
|
|
181
|
+
})
|
|
182
|
+
]
|
|
183
|
+
)
|
|
184
|
+
]
|
|
185
|
+
]
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
export {
|
|
190
|
+
T as BoardMinimap,
|
|
191
|
+
L as useBoardMinimap
|
|
192
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { BOARD_COLOR_PRESETS, colorForPreset, type BoardColorPreset, type CanvasColor } from '@lupinum/board-core';
|
|
2
|
+
export { BOARD_COLOR_PRESETS, colorForPreset };
|
|
3
|
+
export type { BoardColorPreset };
|
|
4
|
+
/**
|
|
5
|
+
* Emits CSS custom properties for a node's color preset. The primary color
|
|
6
|
+
* resolves through `--board-preset-${preset}` so theme.css can swap light/dark
|
|
7
|
+
* values without touching node inline styles. The hex from board-core is the
|
|
8
|
+
* SSR fallback for consumers that haven't loaded theme.css yet.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveNodeColorStyle(color: CanvasColor | undefined): Record<string, string>;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { inject as $, computed as n, toValue as b } from "vue";
|
|
2
|
+
import { getBoundsFromPoints as y, getVisibleBounds as x } from "@lupinum/board-core";
|
|
3
|
+
import { getBoardInteractionAdapter as B } from "@lupinum/board-core/internal";
|
|
4
|
+
const h = /* @__PURE__ */ Symbol("board-engine");
|
|
5
|
+
function d() {
|
|
6
|
+
const e = $(h);
|
|
7
|
+
if (!e)
|
|
8
|
+
throw new Error("Board composables must be used under <BoardRoot>.");
|
|
9
|
+
return e;
|
|
10
|
+
}
|
|
11
|
+
function w() {
|
|
12
|
+
const { $camera: e } = d();
|
|
13
|
+
return n(() => e.value);
|
|
14
|
+
}
|
|
15
|
+
function E() {
|
|
16
|
+
const { $nodes: e } = d();
|
|
17
|
+
return n(() => e.value);
|
|
18
|
+
}
|
|
19
|
+
function I() {
|
|
20
|
+
const { $selection: e } = d();
|
|
21
|
+
return n(() => [...e.value]);
|
|
22
|
+
}
|
|
23
|
+
function N() {
|
|
24
|
+
const { $interaction: e } = d();
|
|
25
|
+
return n(() => e.value);
|
|
26
|
+
}
|
|
27
|
+
function X() {
|
|
28
|
+
const { $camera: e, viewportSize: t } = d();
|
|
29
|
+
return n(
|
|
30
|
+
() => x(t.value.x, t.value.y, e.value)
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
function Y(e = 200) {
|
|
34
|
+
const { $nodes: t, viewportSize: i, $camera: u } = d();
|
|
35
|
+
return n(() => {
|
|
36
|
+
const c = i.value.x > 0 && i.value.y > 0 ? x(
|
|
37
|
+
i.value.x,
|
|
38
|
+
i.value.y,
|
|
39
|
+
u.value
|
|
40
|
+
) : null;
|
|
41
|
+
return Array.from(t.value.values()).filter((r) => r.visible ? c ? r.x + r.width > c.minX - e && r.x < c.maxX + e && r.y + r.height > c.minY - e && r.y < c.maxY + e : !0 : !1);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function k() {
|
|
45
|
+
const { $camera: e, resolvedGrid: t } = d();
|
|
46
|
+
function i(u, l) {
|
|
47
|
+
return (u % l + l) % l;
|
|
48
|
+
}
|
|
49
|
+
return n(() => {
|
|
50
|
+
const u = e.value.z, l = t.value.size, c = t.value.size * t.value.majorEvery, r = l * u, o = c * u, a = e.value.x * u, m = e.value.y * u, v = r < 6 ? 0 : r < 12 ? t.value.minorOpacity * 0.57 : t.value.minorOpacity, p = o < 8 ? t.value.majorOpacity * 0.44 : t.value.majorOpacity;
|
|
51
|
+
return {
|
|
52
|
+
"--grid-minor-size": `${r}px`,
|
|
53
|
+
"--grid-major-size": `${o}px`,
|
|
54
|
+
"--grid-minor-x": `${i(a, r)}px`,
|
|
55
|
+
"--grid-minor-y": `${i(m, r)}px`,
|
|
56
|
+
"--grid-major-x": `${i(a, o)}px`,
|
|
57
|
+
"--grid-major-y": `${i(m, o)}px`,
|
|
58
|
+
"--grid-minor-color": `rgba(var(--board-grid-minor-rgb, 148 163 184) / ${v})`,
|
|
59
|
+
"--grid-major-color": `rgba(var(--board-grid-major-rgb, 71 85 105) / ${p})`,
|
|
60
|
+
"--grid-mask-image": t.value.fadeEdges ? "radial-gradient(circle at center, black 68%, transparent 100%)" : "none"
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
function A(e) {
|
|
65
|
+
const { engine: t, $nodes: i, $selection: u, $interaction: l, toLocalPoint: c } = d(), r = B(t), o = n(() => b(e)), a = n(() => {
|
|
66
|
+
const s = i.value.get(o.value);
|
|
67
|
+
if (!s)
|
|
68
|
+
throw new Error(
|
|
69
|
+
`Node "${o.value}" is not present in the current snapshot.`
|
|
70
|
+
);
|
|
71
|
+
return s;
|
|
72
|
+
}), m = n(() => u.value.has(o.value)), v = n(
|
|
73
|
+
() => l.value.mode === "editing-text" && l.value.nodeId === o.value
|
|
74
|
+
), p = n(() => a.value.locked), f = n(() => ({
|
|
75
|
+
left: `${a.value.x}px`,
|
|
76
|
+
top: `${a.value.y}px`,
|
|
77
|
+
width: `${a.value.width}px`,
|
|
78
|
+
height: `${a.value.height}px`,
|
|
79
|
+
zIndex: String(a.value.zIndex)
|
|
80
|
+
}));
|
|
81
|
+
return {
|
|
82
|
+
node: a,
|
|
83
|
+
selected: m,
|
|
84
|
+
editing: v,
|
|
85
|
+
locked: p,
|
|
86
|
+
style: f,
|
|
87
|
+
beginEdit: () => {
|
|
88
|
+
a.value.type === "text" && t.beginTextEdit(o.value);
|
|
89
|
+
},
|
|
90
|
+
commitText: (s) => {
|
|
91
|
+
a.value.type === "text" && t.commitTextEdit(o.value, s);
|
|
92
|
+
},
|
|
93
|
+
startDrag: (s) => r.beginNodeDrag(
|
|
94
|
+
o.value,
|
|
95
|
+
s.pointerId,
|
|
96
|
+
c(s.clientX, s.clientY)
|
|
97
|
+
),
|
|
98
|
+
startResize: (s, g) => r.beginResize(
|
|
99
|
+
o.value,
|
|
100
|
+
s,
|
|
101
|
+
g.pointerId,
|
|
102
|
+
c(g.clientX, g.clientY)
|
|
103
|
+
)
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
function O() {
|
|
107
|
+
const { $interaction: e } = d();
|
|
108
|
+
return n(() => {
|
|
109
|
+
const t = e.value;
|
|
110
|
+
return t.mode !== "box-select" ? null : y(
|
|
111
|
+
t.startScreenPoint,
|
|
112
|
+
t.currentScreenPoint
|
|
113
|
+
);
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
export {
|
|
117
|
+
N as a,
|
|
118
|
+
d as b,
|
|
119
|
+
k as c,
|
|
120
|
+
w as d,
|
|
121
|
+
h as e,
|
|
122
|
+
A as f,
|
|
123
|
+
E as g,
|
|
124
|
+
I as h,
|
|
125
|
+
X as i,
|
|
126
|
+
Y as j,
|
|
127
|
+
O as u
|
|
128
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { type MaybeRefOrGetter } from 'vue';
|
|
2
|
+
import { type BoardNode, type NodeId, type ResizeHandle } from '@lupinum/board-core';
|
|
3
|
+
/** Access the board context provided by `BoardRoot`. */
|
|
4
|
+
export declare function useBoardEngine(): import("./context.js").BoardEngineContext;
|
|
5
|
+
/** Reactive camera state for the current board. */
|
|
6
|
+
export declare function useBoardCamera(): import("vue").ComputedRef<import("@lupinum/board-core").Camera>;
|
|
7
|
+
/** Reactive node map for the current board. */
|
|
8
|
+
export declare function useBoardNodes(): import("vue").ComputedRef<ReadonlyMap<NodeId, BoardNode>>;
|
|
9
|
+
/** Reactive selection ids as an ordered array. */
|
|
10
|
+
export declare function useBoardSelection(): import("vue").ComputedRef<readonly NodeId[]>;
|
|
11
|
+
/** Reactive interaction state for the current board gesture. */
|
|
12
|
+
export declare function useBoardInteraction(): import("vue").ComputedRef<import("@lupinum/board-core").InteractionState>;
|
|
13
|
+
/** Compute the currently visible world bounds from camera and viewport size. */
|
|
14
|
+
export declare function useBoardVisibleBounds(): import("vue").ComputedRef<import("@lupinum/board-core").Bounds>;
|
|
15
|
+
/** Filter visible nodes to the viewport with an optional culling margin. */
|
|
16
|
+
export declare function useBoardVisibleNodes(margin?: number): import("vue").ComputedRef<readonly BoardNode[]>;
|
|
17
|
+
/** CSS custom properties used by `BoardGrid` to render the active grid pattern. */
|
|
18
|
+
export declare function useBoardGridStyle(): import("vue").ComputedRef<{
|
|
19
|
+
'--grid-minor-size': string;
|
|
20
|
+
'--grid-major-size': string;
|
|
21
|
+
'--grid-minor-x': string;
|
|
22
|
+
'--grid-minor-y': string;
|
|
23
|
+
'--grid-major-x': string;
|
|
24
|
+
'--grid-major-y': string;
|
|
25
|
+
'--grid-minor-color': string;
|
|
26
|
+
'--grid-major-color': string;
|
|
27
|
+
'--grid-mask-image': string;
|
|
28
|
+
}>;
|
|
29
|
+
/**
|
|
30
|
+
* Access a single node plus common node-level actions used by renderers.
|
|
31
|
+
*
|
|
32
|
+
* The returned helpers intentionally stay thin over the engine command API.
|
|
33
|
+
*/
|
|
34
|
+
export declare function useBoardNode(id: MaybeRefOrGetter<NodeId>): {
|
|
35
|
+
node: import("vue").ComputedRef<BoardNode>;
|
|
36
|
+
selected: import("vue").ComputedRef<boolean>;
|
|
37
|
+
editing: import("vue").ComputedRef<boolean>;
|
|
38
|
+
locked: import("vue").ComputedRef<boolean>;
|
|
39
|
+
style: import("vue").ComputedRef<{
|
|
40
|
+
left: string;
|
|
41
|
+
top: string;
|
|
42
|
+
width: string;
|
|
43
|
+
height: string;
|
|
44
|
+
zIndex: string;
|
|
45
|
+
}>;
|
|
46
|
+
beginEdit: () => void;
|
|
47
|
+
commitText: (text: string) => void;
|
|
48
|
+
startDrag: (event: PointerEvent) => void;
|
|
49
|
+
startResize: (handle: ResizeHandle, event: PointerEvent) => void;
|
|
50
|
+
};
|
|
51
|
+
/** Screen-space rectangle for the active box-selection gesture, or `null` when idle. */
|
|
52
|
+
export declare function useBoardBoxSelectBounds(): import("vue").ComputedRef<import("@lupinum/board-core").Bounds | null>;
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lupinum/vue-board",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Vue 3 board components and composables built on top of @lupinum/board-core.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Lupinum OG <info@lupinum.com> (https://lupinum.com)",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=20.19.0"
|
|
10
|
+
},
|
|
11
|
+
"main": "dist/index.js",
|
|
12
|
+
"module": "dist/index.js",
|
|
13
|
+
"types": "dist/index.d.ts",
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./minimap": {
|
|
24
|
+
"types": "./dist/minimap.d.ts",
|
|
25
|
+
"import": "./dist/minimap.js",
|
|
26
|
+
"default": "./dist/minimap.js"
|
|
27
|
+
},
|
|
28
|
+
"./style.css": "./dist/index.css"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "git+https://github.com/lupinum-dev/nuxt-board.git",
|
|
33
|
+
"directory": "packages/vue-board"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://nuxt-board.lupinum.com",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/lupinum-dev/nuxt-board/issues"
|
|
38
|
+
},
|
|
39
|
+
"keywords": [
|
|
40
|
+
"board",
|
|
41
|
+
"vue",
|
|
42
|
+
"diagram",
|
|
43
|
+
"whiteboard",
|
|
44
|
+
"nodes"
|
|
45
|
+
],
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"vue": "^3.5.0",
|
|
51
|
+
"@lupinum/board-core": "0.1.0"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"build": "vite build && vue-tsc -p tsconfig.build.json && node ../../scripts/normalize-vue-declarations.mjs dist"
|
|
55
|
+
}
|
|
56
|
+
}
|