@grafloria/element 0.4.20 → 0.4.21
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/package.json
CHANGED
|
@@ -513,14 +513,19 @@ interface AdoptedLeg {
|
|
|
513
513
|
* unregister. A split board adopts nothing and grows no slab: its `adopt`
|
|
514
514
|
* answers null and `resizeMemberBy` answers unchanged.
|
|
515
515
|
*/
|
|
516
|
+
/** The board on the canvas that holds `groupId` as a member — a nested board's parent. */
|
|
517
|
+
export declare function parentPeerOf(container: HTMLElement, groupId: string): BinderPeer | null;
|
|
516
518
|
/** Clear the selection on every OTHER board of the canvas — one selection per canvas. */
|
|
517
519
|
export declare function clearOtherSelections(container: HTMLElement, self: BinderPeer | null): void;
|
|
518
520
|
export declare function registerBoardPeer(container: HTMLElement, peer: BinderPeer): () => void;
|
|
519
521
|
export type { BinderPeer };
|
|
520
|
-
|
|
522
|
+
/** A press this close (CSS px) to a tile's border takes that edge for a resize. */
|
|
523
|
+
export declare const EDGE_GRIP = 7;
|
|
524
|
+
export interface ResizeEdges {
|
|
521
525
|
n: boolean;
|
|
522
526
|
e: boolean;
|
|
523
527
|
s: boolean;
|
|
524
528
|
w: boolean;
|
|
525
529
|
}
|
|
530
|
+
export declare const anyEdge: (E: ResizeEdges) => boolean;
|
|
526
531
|
export declare function bindDashboardGrid(api: DashboardGridApi, group: GroupModel, options?: DashboardGridOptions): DashboardGridHandle;
|
|
@@ -153,6 +153,14 @@ const BOARD_REGISTRY = new WeakMap();
|
|
|
153
153
|
* unregister. A split board adopts nothing and grows no slab: its `adopt`
|
|
154
154
|
* answers null and `resizeMemberBy` answers unchanged.
|
|
155
155
|
*/
|
|
156
|
+
/** The board on the canvas that holds `groupId` as a member — a nested board's parent. */
|
|
157
|
+
export function parentPeerOf(container, groupId) {
|
|
158
|
+
var _a;
|
|
159
|
+
for (const p of (_a = BOARD_REGISTRY.get(container)) !== null && _a !== void 0 ? _a : [])
|
|
160
|
+
if (p.group.id !== groupId && p.hasItem(groupId))
|
|
161
|
+
return p;
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
156
164
|
/** Clear the selection on every OTHER board of the canvas — one selection per canvas. */
|
|
157
165
|
export function clearOtherSelections(container, self) {
|
|
158
166
|
var _a, _b;
|
|
@@ -241,7 +249,7 @@ class SetGroupCellCommand extends Command {
|
|
|
241
249
|
const DRAG_THRESHOLD = 4;
|
|
242
250
|
const GLIDE_OFF_DELAY = 400;
|
|
243
251
|
/** A press this close (CSS px) to a tile's border takes that edge for a resize. */
|
|
244
|
-
const EDGE_GRIP = 7;
|
|
252
|
+
export const EDGE_GRIP = 7;
|
|
245
253
|
const NO_EDGES = { n: false, e: false, s: false, w: false };
|
|
246
254
|
/** Which of a host's edges a client point is within EDGE_GRIP of (none when outside). */
|
|
247
255
|
function edgesNear(host, cx, cy) {
|
|
@@ -255,7 +263,7 @@ function edgesNear(host, cx, cy) {
|
|
|
255
263
|
e: r.right - cx <= EDGE_GRIP,
|
|
256
264
|
};
|
|
257
265
|
}
|
|
258
|
-
const anyEdge = (E) => E.n || E.e || E.s || E.w;
|
|
266
|
+
export const anyEdge = (E) => E.n || E.e || E.s || E.w;
|
|
259
267
|
/** The resize cursor for a set of edges ('' when none). */
|
|
260
268
|
function cursorFor(E) {
|
|
261
269
|
const v = E.n || E.s;
|
|
@@ -2127,7 +2135,7 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
2127
2135
|
id: `dashboard-grid:${group.id}:${++binderSeq}`,
|
|
2128
2136
|
priority: 2, // point-specific claim — outranks mode-style tools (see ext/tools.ts)
|
|
2129
2137
|
hitTest(ev, hit) {
|
|
2130
|
-
var _a, _b;
|
|
2138
|
+
var _a, _b, _c, _d;
|
|
2131
2139
|
if (disposed)
|
|
2132
2140
|
return false;
|
|
2133
2141
|
if (gesture || slabGesture || forwardSlab)
|
|
@@ -2150,6 +2158,17 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
2150
2158
|
}
|
|
2151
2159
|
return insideMemberGroupFrame(ev.world.x, ev.world.y);
|
|
2152
2160
|
}
|
|
2161
|
+
// An EMPTY press inside a NESTED board's frame is that board's: its
|
|
2162
|
+
// dividers, its band, its own section press (which it hands back up).
|
|
2163
|
+
// Ties went to the first registered tool, and a section re-bound by a
|
|
2164
|
+
// layout switch registers AFTER its parent — so the parent took every
|
|
2165
|
+
// divider press in a split section (dead dividers) and, near the
|
|
2166
|
+
// section's edge, turned it into a section resize (the width changed
|
|
2167
|
+
// while a control's height was being dragged — Quantia, Groups page).
|
|
2168
|
+
for (const p of (_c = BOARD_REGISTRY.get(api.container)) !== null && _c !== void 0 ? _c : []) {
|
|
2169
|
+
if (p !== selfPeer && ((_d = group.members) !== null && _d !== void 0 ? _d : new Set()).has(p.group.id) && p.containsWorld(ev.world.x, ev.world.y))
|
|
2170
|
+
return false;
|
|
2171
|
+
}
|
|
2153
2172
|
// Claim (and deaden) empty presses inside a member group's frame so the
|
|
2154
2173
|
// built-in group-drag cannot fight the pack layout for the KPI slab —
|
|
2155
2174
|
// and empty presses on the BOARD itself: its group is a layout
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
import { __awaiter } from "tslib";
|
|
26
26
|
import { Command } from '@grafloria/engine';
|
|
27
27
|
import { LiveRegionController, registerTool } from '@grafloria/renderer';
|
|
28
|
-
import { clearOtherSelections, dragHandleSelector, gripHostOf, gripOf, normalizeDragHandle, ownsPress, pressOnDragHandle, registerBoardPeer, syncGrip, DRAG_HANDLE_CLASS } from './grid-binder.js';
|
|
28
|
+
import { anyEdge, clearOtherSelections, dragHandleSelector, gripHostOf, gripOf, normalizeDragHandle, ownsPress, parentPeerOf, pressOnDragHandle, registerBoardPeer, syncGrip, DRAG_HANDLE_CLASS, EDGE_GRIP } from './grid-binder.js';
|
|
29
29
|
import { cellFromGridItem } from './grid-mapping.js';
|
|
30
30
|
import { addSplitLeaf, cellsFromSplit, cloneSplit, dividersOf, groupRectsOf, insertSplitLeaf, moveSplitDivider, normalizeSplit, pathToLeaf, projectSplit, removeSplitLeaf, splitFromCells, splitLeaves, } from './split-layout.js';
|
|
31
31
|
import { ensureDashboardKitStyles } from './styles.js';
|
|
@@ -99,6 +99,8 @@ export function bindDashboardSplit(api, group, options = {}) {
|
|
|
99
99
|
let designW = (_k = (_j = group.size) === null || _j === void 0 ? void 0 : _j.width) !== null && _k !== void 0 ? _k : 0;
|
|
100
100
|
let disposed = false;
|
|
101
101
|
let gesture = null;
|
|
102
|
+
/** The PARENT running a resize of OUR section from a press this tool claimed. */
|
|
103
|
+
let forwardSlab = null;
|
|
102
104
|
let focusedId;
|
|
103
105
|
const live = liveRegionFor(api.container);
|
|
104
106
|
// -- geometry ---------------------------------------------------------------
|
|
@@ -634,7 +636,7 @@ export function bindDashboardSplit(api, group, options = {}) {
|
|
|
634
636
|
var _a;
|
|
635
637
|
if (disposed)
|
|
636
638
|
return false;
|
|
637
|
-
if (gesture)
|
|
639
|
+
if (gesture || forwardSlab)
|
|
638
640
|
return true;
|
|
639
641
|
if (!ownsPress(api.container, diagram, ev, hit))
|
|
640
642
|
return false;
|
|
@@ -643,7 +645,7 @@ export function bindDashboardSplit(api, group, options = {}) {
|
|
|
643
645
|
return worldInsideBoard(ev.world.x, ev.world.y);
|
|
644
646
|
},
|
|
645
647
|
onPointerDown(ev, hit) {
|
|
646
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
648
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
647
649
|
if (gesture)
|
|
648
650
|
return;
|
|
649
651
|
const target = ((_b = (_a = ev.source) === null || _a === void 0 ? void 0 : _a.target) !== null && _b !== void 0 ? _b : null);
|
|
@@ -678,8 +680,27 @@ export function bindDashboardSplit(api, group, options = {}) {
|
|
|
678
680
|
// sits above the card's box) — see grid-binder.
|
|
679
681
|
const gripId = (_e = (_d = gripHostOf(target)) === null || _d === void 0 ? void 0 : _d.getAttribute('data-node-id')) !== null && _e !== void 0 ? _e : null;
|
|
680
682
|
const onGrip = !!gripId && ((_f = group.members) !== null && _f !== void 0 ? _f : new Set()).has(gripId);
|
|
681
|
-
|
|
682
|
-
|
|
683
|
+
const sectionHandle = (_g = target === null || target === void 0 ? void 0 : target.closest) === null || _g === void 0 ? void 0 : _g.call(target, '.axdb-slab > .axdb-rs');
|
|
684
|
+
if ((!hit.node && !onGrip) || sectionHandle) {
|
|
685
|
+
// OUR OWN empty band or corner handle, and we are a section of a
|
|
686
|
+
// parent board: select the section there; an edge or the handle
|
|
687
|
+
// starts the section resize, which the parent runs while this tool
|
|
688
|
+
// forwards the pointer sequence (the grid binder does the same).
|
|
689
|
+
const parent = parentPeerOf(api.container, group.id);
|
|
690
|
+
if ((parent === null || parent === void 0 ? void 0 : parent.selectMember) && (sectionHandle || worldInsideBoard(ev.world.x, ev.world.y))) {
|
|
691
|
+
const own = ((_h = sectionHandle === null || sectionHandle === void 0 ? void 0 : sectionHandle.parentElement) === null || _h === void 0 ? void 0 : _h.getAttribute('data-slab-id')) === group.id;
|
|
692
|
+
parent.selectMember(group.id);
|
|
693
|
+
if (!isStatic && parent.beginSlabResize) {
|
|
694
|
+
const f = frame();
|
|
695
|
+
const edges = own
|
|
696
|
+
? rtl ? { n: false, e: false, s: true, w: true } : { n: false, e: true, s: true, w: false }
|
|
697
|
+
: { n: ev.world.y - f.y <= EDGE_GRIP, s: f.y + f.height - ev.world.y <= EDGE_GRIP, w: ev.world.x - f.x <= EDGE_GRIP, e: f.x + f.width - ev.world.x <= EDGE_GRIP };
|
|
698
|
+
if (anyEdge(edges) && parent.beginSlabResize(group.id, edges, ev))
|
|
699
|
+
forwardSlab = parent;
|
|
700
|
+
}
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
(_k = (_j = diagram).clearSelection) === null || _k === void 0 ? void 0 : _k.call(_j);
|
|
683
704
|
selectWidget(undefined);
|
|
684
705
|
api.render();
|
|
685
706
|
return;
|
|
@@ -688,9 +709,9 @@ export function bindDashboardSplit(api, group, options = {}) {
|
|
|
688
709
|
if (!node)
|
|
689
710
|
return;
|
|
690
711
|
selectWidget(node.id); // a press selects, whether or not it starts a gesture
|
|
691
|
-
if (((
|
|
712
|
+
if (((_l = node.state) === null || _l === void 0 ? void 0 : _l.locked) === true || isStatic)
|
|
692
713
|
return;
|
|
693
|
-
if (((
|
|
714
|
+
if (((_m = node.getMetadata) === null || _m === void 0 ? void 0 : _m.call(node, 'widgetMovable')) === false)
|
|
694
715
|
return;
|
|
695
716
|
// Drag-handle mode: only the handle (the caption strip, a custom element
|
|
696
717
|
// or the painted grip) lifts a widget out — see pressOnDragHandle.
|
|
@@ -723,12 +744,27 @@ export function bindDashboardSplit(api, group, options = {}) {
|
|
|
723
744
|
};
|
|
724
745
|
},
|
|
725
746
|
onPointerMove(ev) {
|
|
726
|
-
|
|
747
|
+
var _a;
|
|
748
|
+
if (forwardSlab)
|
|
749
|
+
(_a = forwardSlab.slabMove) === null || _a === void 0 ? void 0 : _a.call(forwardSlab, ev);
|
|
750
|
+
else
|
|
751
|
+
onToolMove(ev);
|
|
727
752
|
},
|
|
728
753
|
onPointerUp() {
|
|
729
|
-
|
|
754
|
+
var _a;
|
|
755
|
+
if (forwardSlab) {
|
|
756
|
+
(_a = forwardSlab.slabUp) === null || _a === void 0 ? void 0 : _a.call(forwardSlab);
|
|
757
|
+
forwardSlab = null;
|
|
758
|
+
}
|
|
759
|
+
else
|
|
760
|
+
onToolUp();
|
|
730
761
|
},
|
|
731
762
|
onCancel() {
|
|
763
|
+
var _a;
|
|
764
|
+
if (forwardSlab) {
|
|
765
|
+
(_a = forwardSlab.slabCancel) === null || _a === void 0 ? void 0 : _a.call(forwardSlab);
|
|
766
|
+
forwardSlab = null;
|
|
767
|
+
}
|
|
732
768
|
cancelActiveGesture();
|
|
733
769
|
},
|
|
734
770
|
};
|