@grafloria/element 0.4.60 → 0.4.62
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
|
@@ -910,6 +910,52 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
910
910
|
* come back by themselves when the widget leaves (S2).
|
|
911
911
|
*/
|
|
912
912
|
let beside = null;
|
|
913
|
+
/**
|
|
914
|
+
* A VERTICAL BESIDE, HELD BUT NOT APPLIED (0.4.61). A container's top or
|
|
915
|
+
* bottom band pushes it a whole row along its own column — and the zone walk
|
|
916
|
+
* reads the container where it RESTS (0.4.60, which is what stopped the
|
|
917
|
+
* strip flickering), so the moment the push lands, the painted tabs sit a
|
|
918
|
+
* row below the only place that accepts them, and a hand following them down
|
|
919
|
+
* pushes them again. The user met it as "it pushes the entire tab group down
|
|
920
|
+
* and then I cannot go up to the tab header".
|
|
921
|
+
*
|
|
922
|
+
* So a vertical band moves NOTHING while the hand is held: an overlay marks
|
|
923
|
+
* the cell the widget will take and the container gives way on release — the
|
|
924
|
+
* rule a tab's dock and split previews have followed since 0.4.42. The LEFT
|
|
925
|
+
* and RIGHT bands keep their live slide (0.4.48): sideways, a full-width
|
|
926
|
+
* strip never leaves the hand, and the user missed that slide the one time
|
|
927
|
+
* it was frozen.
|
|
928
|
+
*/
|
|
929
|
+
let pendingBeside = null;
|
|
930
|
+
let joinEl = null;
|
|
931
|
+
const showJoin = (r) => {
|
|
932
|
+
const layer = htmlLayer();
|
|
933
|
+
if (!layer)
|
|
934
|
+
return;
|
|
935
|
+
if (!joinEl || joinEl.parentElement !== layer) {
|
|
936
|
+
joinEl === null || joinEl === void 0 ? void 0 : joinEl.remove();
|
|
937
|
+
joinEl = document.createElement('div');
|
|
938
|
+
joinEl.className = 'axdb-join';
|
|
939
|
+
layer.prepend(joinEl);
|
|
940
|
+
}
|
|
941
|
+
joinEl.style.left = `${r.x}px`;
|
|
942
|
+
joinEl.style.top = `${r.y}px`;
|
|
943
|
+
joinEl.style.width = `${r.width}px`;
|
|
944
|
+
joinEl.style.height = `${r.height}px`;
|
|
945
|
+
};
|
|
946
|
+
const endPendingBeside = () => {
|
|
947
|
+
pendingBeside = null;
|
|
948
|
+
joinEl === null || joinEl === void 0 ? void 0 : joinEl.remove();
|
|
949
|
+
joinEl = null;
|
|
950
|
+
};
|
|
951
|
+
/** The cell a vertical beside would take: the container's own, or the row under it. Never the pointer's row — the container is not moving. */
|
|
952
|
+
const pendingCellOf = (containerId, side, spans) => {
|
|
953
|
+
const it = engine.getItem(containerId);
|
|
954
|
+
if (!it)
|
|
955
|
+
return null;
|
|
956
|
+
const x = Math.max(0, Math.min(engine.columns - spans.w, it.x));
|
|
957
|
+
return { x, y: side === 'top' ? it.y : it.y + it.h };
|
|
958
|
+
};
|
|
913
959
|
const endBeside = (restore) => {
|
|
914
960
|
if (!beside)
|
|
915
961
|
return;
|
|
@@ -1292,6 +1338,7 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1292
1338
|
showRefusal(null, 0, 0);
|
|
1293
1339
|
}
|
|
1294
1340
|
}
|
|
1341
|
+
endPendingBeside();
|
|
1295
1342
|
disarmGlideSoon();
|
|
1296
1343
|
releasePointer(g.pointerId);
|
|
1297
1344
|
api.container.style.cursor = '';
|
|
@@ -1335,6 +1382,7 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1335
1382
|
};
|
|
1336
1383
|
const cancelActiveGesture = (notify = true) => {
|
|
1337
1384
|
var _a, _b, _c;
|
|
1385
|
+
endPendingBeside();
|
|
1338
1386
|
if (gesture === null || gesture === void 0 ? void 0 : gesture.strip) {
|
|
1339
1387
|
(_a = options.tabDrop) === null || _a === void 0 ? void 0 : _a.markDrop(null, null);
|
|
1340
1388
|
gesture.strip = null;
|
|
@@ -1483,6 +1531,7 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1483
1531
|
// -- INTO A STRIP: the widget becomes a new tab there, so it leaves
|
|
1484
1532
|
// this board (survivors settle home) and the strip marks the slot.
|
|
1485
1533
|
endBeside(true); // a band's shift gives way to the strip: the container comes back
|
|
1534
|
+
endPendingBeside();
|
|
1486
1535
|
leaveSelf();
|
|
1487
1536
|
setDim(g, false);
|
|
1488
1537
|
if (!g.strip || g.strip.containerId !== z.containerId || g.strip.index !== z.index) {
|
|
@@ -1501,6 +1550,22 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1501
1550
|
// — at the board's edge the container shifts over to make room, live
|
|
1502
1551
|
// and gliding, like any widget gives way (0.4.48). On THIS board the
|
|
1503
1552
|
// engine is driven directly; on another board its leg drives it (4a).
|
|
1553
|
+
if (z.kind === 'beside' && !isStatic && z.board.ref === selfPeer && g.subject === 'node' && (z.side === 'top' || z.side === 'bottom')) {
|
|
1554
|
+
// -- A VERTICAL BAND: marked, not applied. Nothing moves until release.
|
|
1555
|
+
if (beside)
|
|
1556
|
+
endBeside(true);
|
|
1557
|
+
const cell = pendingCellOf(z.containerId, z.side, g.spans);
|
|
1558
|
+
if (cell) {
|
|
1559
|
+
leaveSelf();
|
|
1560
|
+
setDim(g, false);
|
|
1561
|
+
pendingBeside = { id: z.containerId, side: z.side, cell, spans: Object.assign({}, g.spans) };
|
|
1562
|
+
showJoin(cellToRect({ x: cell.x, y: cell.y, w: g.spans.w, h: g.spans.h }, frame(), geom(), rows()));
|
|
1563
|
+
syncPlaceholder();
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
if (pendingBeside)
|
|
1568
|
+
endPendingBeside(); // the hand left the band: the mark goes
|
|
1504
1569
|
if (z.kind === 'beside' && !isStatic && z.board.ref === selfPeer) {
|
|
1505
1570
|
const row = rowOfPoint(ev.world.y);
|
|
1506
1571
|
if (!z.kept || !beside || beside.row !== row)
|
|
@@ -1955,6 +2020,13 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1955
2020
|
(_b = options.onGesture) === null || _b === void 0 ? void 0 : _b.call(options, { type: 'commit', kind: g.kind, nodeId: g.id, changed: true });
|
|
1956
2021
|
return;
|
|
1957
2022
|
}
|
|
2023
|
+
if (pendingBeside) {
|
|
2024
|
+
// -- REALIZED ON RELEASE: the container held still while the hand chose;
|
|
2025
|
+
// now it gives way, and the commit below reads the settled layout.
|
|
2026
|
+
const p = pendingBeside;
|
|
2027
|
+
endPendingBeside();
|
|
2028
|
+
applyBeside(g, { id: p.id, side: p.side }, p.cell.y);
|
|
2029
|
+
}
|
|
1958
2030
|
if (g.leg) {
|
|
1959
2031
|
// -- CROSS-CONTAINER COMMIT: one batch across both boards -----------
|
|
1960
2032
|
const fin = g.leg.adopted.finalize();
|
|
@@ -2125,6 +2197,11 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
2125
2197
|
frame: frameOfGroup(grp),
|
|
2126
2198
|
stripHeight: layout === 'tabs' ? TAB_STRIP_HEIGHT : 0,
|
|
2127
2199
|
band: layout === 'tabs' ? BESIDE_BAND : 0, // a section's whole body is "into" (Quantia's Groups page)
|
|
2200
|
+
// The top and bottom are a FIXED depth — one strip's worth, under
|
|
2201
|
+
// the strip — not a fifth of the body, which grew with the panel
|
|
2202
|
+
// until 216 px of the fluid demo's page meant "above the whole
|
|
2203
|
+
// panel" (0.4.62). The sides keep the fifth.
|
|
2204
|
+
bandY: layout === 'tabs' ? TAB_STRIP_HEIGHT : 0,
|
|
2128
2205
|
inner: innerPeer ? boardRef(innerPeer, depth + 1) : null,
|
|
2129
2206
|
});
|
|
2130
2207
|
}
|
|
@@ -2209,7 +2286,15 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
2209
2286
|
strip,
|
|
2210
2287
|
prev: beside
|
|
2211
2288
|
? { containerId: beside.id, side: beside.side, frame0: beside.frame0, vacated: cellToRect({ x: beside.vacated.x, y: beside.vacated.y, w: g.spans.w, h: g.spans.h }, frame(), geom(), rows()) }
|
|
2212
|
-
:
|
|
2289
|
+
: pendingBeside
|
|
2290
|
+
? // a VERTICAL band the hand holds: the container never moved, so its own frame is the sticky one
|
|
2291
|
+
{
|
|
2292
|
+
containerId: pendingBeside.id,
|
|
2293
|
+
side: pendingBeside.side,
|
|
2294
|
+
frame0: (() => { const grp = diagram.getGroup(pendingBeside.id); return grp ? frameOfGroup(grp) : cellToRect({ x: pendingBeside.cell.x, y: pendingBeside.cell.y, w: pendingBeside.spans.w, h: pendingBeside.spans.h }, frame(), geom(), rows()); })(),
|
|
2295
|
+
// no vacated cell: nothing has moved, so the BAND alone holds the mark
|
|
2296
|
+
}
|
|
2297
|
+
: ((_e = (_d = g.leg) === null || _d === void 0 ? void 0 : _d.adopted.besideState()) !== null && _e !== void 0 ? _e : null), // a beside another board holds for the ghost, through its leg
|
|
2213
2298
|
maxDepth: nesting,
|
|
2214
2299
|
ghostDepth: g.subject === 'group' ? 1 + levelsInside(g.id) : 0, // a group's widgets sit one board deeper than wherever it lands
|
|
2215
2300
|
restFrames: rests,
|
|
@@ -3206,6 +3291,13 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
3206
3291
|
chip === null || chip === void 0 ? void 0 : chip.remove();
|
|
3207
3292
|
return;
|
|
3208
3293
|
}
|
|
3294
|
+
if (commit && pendingBeside) {
|
|
3295
|
+
const p = pendingBeside;
|
|
3296
|
+
endPendingBeside();
|
|
3297
|
+
applyBeside(g, { id: p.id, side: p.side }, p.cell.y);
|
|
3298
|
+
}
|
|
3299
|
+
else
|
|
3300
|
+
endPendingBeside();
|
|
3209
3301
|
if (commit && g.leg) {
|
|
3210
3302
|
// Dropped into another board (a page, a section): its leg closes with
|
|
3211
3303
|
// that board's displaced tiles; this board displaced nothing.
|
|
@@ -57,6 +57,8 @@ export interface ZoneContainer {
|
|
|
57
57
|
stripHeight: number;
|
|
58
58
|
/** The outer fraction of the body that means "beside"; 0 for a container whose whole body is "into" (a section). */
|
|
59
59
|
band: number;
|
|
60
|
+
/** The TOP and BOTTOM depth in world units, when it is a fixed depth rather than `band` of the body. */
|
|
61
|
+
bandY?: number;
|
|
60
62
|
/** The board a descent enters: a tab container's ACTIVE page, a section's own board. Null: nothing to enter. */
|
|
61
63
|
inner: ZoneBoard | null;
|
|
62
64
|
}
|
|
@@ -69,7 +71,14 @@ export interface BesideMemory {
|
|
|
69
71
|
containerId: string;
|
|
70
72
|
side: BesideSide;
|
|
71
73
|
frame0: ZoneRect;
|
|
72
|
-
|
|
74
|
+
/**
|
|
75
|
+
* The cell the widget TOOK, when it took one. A beside that is only MARKED
|
|
76
|
+
* (a vertical band since 0.4.61 — nothing moves until release) has none, and
|
|
77
|
+
* must not borrow one: the cell a mark would take is the container's own, so
|
|
78
|
+
* for a widget the size of its container that rect covers the whole panel
|
|
79
|
+
* and the band would then hold the hand everywhere inside it (lab L105).
|
|
80
|
+
*/
|
|
81
|
+
vacated?: ZoneRect;
|
|
73
82
|
}
|
|
74
83
|
export interface ResolveInput {
|
|
75
84
|
x: number;
|
|
@@ -129,8 +138,16 @@ export declare const BESIDE_STAY = 0.05;
|
|
|
129
138
|
* the middle, or outside. The left and right bands take the corners (VS
|
|
130
139
|
* Code's precedence): a one-row widget carried along the top of a tall panel
|
|
131
140
|
* to its far right means "after it", not "above it".
|
|
141
|
+
*
|
|
142
|
+
* `bandY` is the TOP and BOTTOM depth in world units. A fraction is the wrong
|
|
143
|
+
* unit there: it grows with the container, so the taller and more useful the
|
|
144
|
+
* panel, the more of its page means "above the whole panel" — 216 px of the
|
|
145
|
+
* fluid demo's panel, starting right under its tabs, which is exactly where a
|
|
146
|
+
* hand aiming into the page lands (0.4.62). The SIDES keep the fraction: that
|
|
147
|
+
* is how a widget gets beside a full-height panel, and a tab's split bands
|
|
148
|
+
* are a fifth on all four edges by design.
|
|
132
149
|
*/
|
|
133
|
-
export declare function bandOf(f: ZoneRect, stripHeight: number, x: number, y: number, band?: number): BesideSide | null;
|
|
150
|
+
export declare function bandOf(f: ZoneRect, stripHeight: number, x: number, y: number, band?: number, bandY?: number): BesideSide | null;
|
|
134
151
|
export interface StripProbe {
|
|
135
152
|
x: number;
|
|
136
153
|
y: number;
|
|
@@ -39,8 +39,16 @@ const inRect = (r, x, y, tol = 0) => x >= r.x - tol && x <= r.x + r.width + tol
|
|
|
39
39
|
* the middle, or outside. The left and right bands take the corners (VS
|
|
40
40
|
* Code's precedence): a one-row widget carried along the top of a tall panel
|
|
41
41
|
* to its far right means "after it", not "above it".
|
|
42
|
+
*
|
|
43
|
+
* `bandY` is the TOP and BOTTOM depth in world units. A fraction is the wrong
|
|
44
|
+
* unit there: it grows with the container, so the taller and more useful the
|
|
45
|
+
* panel, the more of its page means "above the whole panel" — 216 px of the
|
|
46
|
+
* fluid demo's panel, starting right under its tabs, which is exactly where a
|
|
47
|
+
* hand aiming into the page lands (0.4.62). The SIDES keep the fraction: that
|
|
48
|
+
* is how a widget gets beside a full-height panel, and a tab's split bands
|
|
49
|
+
* are a fifth on all four edges by design.
|
|
42
50
|
*/
|
|
43
|
-
export function bandOf(f, stripHeight, x, y, band = BESIDE_BAND) {
|
|
51
|
+
export function bandOf(f, stripHeight, x, y, band = BESIDE_BAND, bandY) {
|
|
44
52
|
if (band <= 0 || !inRect(f, x, y))
|
|
45
53
|
return null;
|
|
46
54
|
const bodyY = f.y + stripHeight;
|
|
@@ -53,9 +61,10 @@ export function bandOf(f, stripHeight, x, y, band = BESIDE_BAND) {
|
|
|
53
61
|
return 'left';
|
|
54
62
|
if (rx > 1 - band)
|
|
55
63
|
return 'right';
|
|
56
|
-
|
|
64
|
+
const depth = bandY !== undefined && bandY > 0 ? Math.min(bandY, bodyH / 2) : band * bodyH;
|
|
65
|
+
if (y - bodyY < depth)
|
|
57
66
|
return 'top';
|
|
58
|
-
if (
|
|
67
|
+
if (bodyY + bodyH - y < depth)
|
|
59
68
|
return 'bottom';
|
|
60
69
|
return null;
|
|
61
70
|
}
|
|
@@ -128,6 +137,7 @@ function boardOf(roots, containerId) {
|
|
|
128
137
|
return null;
|
|
129
138
|
}
|
|
130
139
|
export function resolve(input) {
|
|
140
|
+
var _a;
|
|
131
141
|
const { x, y } = input;
|
|
132
142
|
if (input.strip)
|
|
133
143
|
return { kind: 'strip', containerId: input.strip.containerId, index: input.strip.index };
|
|
@@ -138,10 +148,13 @@ export function resolve(input) {
|
|
|
138
148
|
// middle of it is a zone change too (into the page).
|
|
139
149
|
if (input.prev) {
|
|
140
150
|
const p = input.prev;
|
|
141
|
-
const
|
|
142
|
-
const
|
|
143
|
-
const
|
|
144
|
-
const
|
|
151
|
+
const c0 = containerOf(input.roots, p.containerId);
|
|
152
|
+
const stripH = (_a = c0 === null || c0 === void 0 ? void 0 : c0.stripHeight) !== null && _a !== void 0 ? _a : 0;
|
|
153
|
+
const depth = c0 === null || c0 === void 0 ? void 0 : c0.bandY;
|
|
154
|
+
const stay = bandOf(p.frame0, stripH, x, y, BESIDE_BAND + BESIDE_STAY, depth === undefined ? undefined : depth * (1 + BESIDE_STAY / BESIDE_BAND));
|
|
155
|
+
const other = bandOf(p.frame0, stripH, x, y, BESIDE_BAND, depth);
|
|
156
|
+
const onVacated = !!p.vacated && inRect(p.vacated, x, y, input.gap);
|
|
157
|
+
const held = stay === p.side || (!(other !== null && other !== p.side) && onVacated);
|
|
145
158
|
if (held) {
|
|
146
159
|
const board = boardOf(input.roots, p.containerId);
|
|
147
160
|
if (board)
|
|
@@ -183,7 +196,7 @@ export function resolve(input) {
|
|
|
183
196
|
const ndx0 = atRest ? c.frame.x - atRest.x : dx;
|
|
184
197
|
const ndy0 = atRest ? c.frame.y - atRest.y : dy;
|
|
185
198
|
const overNested = !!c.inner && c.inner.children().some((cc) => inRect(cc.frame, x + ndx0, y + ndy0));
|
|
186
|
-
const side = overNested || input.homeChain.has(c.id) ? null : bandOf(frame, c.stripHeight, tx, ty, c.band);
|
|
199
|
+
const side = overNested || input.homeChain.has(c.id) ? null : bandOf(frame, c.stripHeight, tx, ty, c.band, c.bandY);
|
|
187
200
|
if (side)
|
|
188
201
|
return { kind: 'beside', board, containerId: c.id, side, kept: false };
|
|
189
202
|
if (opaque(board, c) || !c.inner)
|
|
@@ -210,23 +223,24 @@ export function resolve(input) {
|
|
|
210
223
|
visit(root);
|
|
211
224
|
return deepest ? { kind: 'plain', board: deepest, grace: true } : { kind: 'off' };
|
|
212
225
|
}
|
|
213
|
-
|
|
226
|
+
/** The container with this id, anywhere in the tree — its strip rows and its band depth. */
|
|
227
|
+
function containerOf(roots, containerId) {
|
|
214
228
|
const visit = (b) => {
|
|
215
229
|
for (const c of b.children()) {
|
|
216
230
|
if (c.id === containerId)
|
|
217
|
-
return c
|
|
231
|
+
return c;
|
|
218
232
|
const deeper = c.inner ? visit(c.inner) : null;
|
|
219
|
-
if (deeper
|
|
233
|
+
if (deeper)
|
|
220
234
|
return deeper;
|
|
221
235
|
}
|
|
222
236
|
return null;
|
|
223
237
|
};
|
|
224
238
|
for (const r of roots) {
|
|
225
|
-
const
|
|
226
|
-
if (
|
|
227
|
-
return
|
|
239
|
+
const c = visit(r);
|
|
240
|
+
if (c)
|
|
241
|
+
return c;
|
|
228
242
|
}
|
|
229
|
-
return
|
|
243
|
+
return null;
|
|
230
244
|
}
|
|
231
245
|
/**
|
|
232
246
|
* What a pointer means for a TORN-OUT PAGE, in the one order both binders
|