@grafloria/element 0.4.16 → 0.4.18
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
|
@@ -1128,7 +1128,7 @@ export function dashboard(options) {
|
|
|
1128
1128
|
* its metadata, a fresh binder on the same group, selection carried.
|
|
1129
1129
|
*/
|
|
1130
1130
|
function rebindContainerLayout(id, next) {
|
|
1131
|
-
var _a, _b, _c, _d, _e, _f
|
|
1131
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1132
1132
|
const cg = ctx.boardGroups.get(id);
|
|
1133
1133
|
const w = specById.get(id);
|
|
1134
1134
|
const b = binders.get(id);
|
|
@@ -1162,14 +1162,13 @@ export function dashboard(options) {
|
|
|
1162
1162
|
// a child escalation grew to two rows must keep them through a
|
|
1163
1163
|
// split → grid round trip (the visual gate caught it collapsing to one
|
|
1164
1164
|
// inside a two-row slab).
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
(_g = binders.get(id)) === null || _g === void 0 ? void 0 : _g.sync();
|
|
1165
|
+
void ((_b = binders.get((_a = ctx.viewOfWidget.get(id)) !== null && _a !== void 0 ? _a : '')) === null || _b === void 0 ? void 0 : _b.cellOf(id));
|
|
1166
|
+
bindContainer(cg, w, (_c = ctx.viewOfBoard.get(id)) !== null && _c !== void 0 ? _c : ctx.active);
|
|
1167
|
+
(_d = binders.get(id)) === null || _d === void 0 ? void 0 : _d.sync();
|
|
1169
1168
|
if (focused)
|
|
1170
|
-
(
|
|
1169
|
+
(_e = binders.get(id)) === null || _e === void 0 ? void 0 : _e.focusWidget(focused);
|
|
1171
1170
|
else if (selected)
|
|
1172
|
-
(
|
|
1171
|
+
(_f = binders.get(id)) === null || _f === void 0 ? void 0 : _f.selectWidget(selected);
|
|
1173
1172
|
}
|
|
1174
1173
|
(_m = ctx.attachHistory) === null || _m === void 0 ? void 0 : _m.call(ctx);
|
|
1175
1174
|
return;
|
|
@@ -1273,7 +1272,7 @@ export function dashboard(options) {
|
|
|
1273
1272
|
}
|
|
1274
1273
|
/** Bind (or re-bind) a container's inner grid on its group. */
|
|
1275
1274
|
function bindContainer(cg, w, viewId, innerRows) {
|
|
1276
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
1275
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
1277
1276
|
void viewId;
|
|
1278
1277
|
// The LIVE switches ride on the view's binder when it exists (a
|
|
1279
1278
|
// container bound after a setStatic/setRtl/setDragHandle must match).
|
|
@@ -1290,7 +1289,10 @@ export function dashboard(options) {
|
|
|
1290
1289
|
binders.set(w.id, bindDashboardSplit(a, cg, Object.assign(Object.assign({}, inner), (w.tree !== undefined ? { tree: w.tree } : {}))));
|
|
1291
1290
|
return;
|
|
1292
1291
|
}
|
|
1293
|
-
binders.set(w.id, bindDashboardGrid(a, cg, Object.assign(Object.assign({}, inner), { sizing: 'fit', designHeight: 0,
|
|
1292
|
+
binders.set(w.id, bindDashboardGrid(a, cg, Object.assign(Object.assign({}, inner), { sizing: 'fit', designHeight: 0,
|
|
1293
|
+
// The DESIGN: authored, else what the group was mounted with, else
|
|
1294
|
+
// the children's extent — the binder's live bound follows the cells.
|
|
1295
|
+
maxRows: (_l = (_j = innerRows !== null && innerRows !== void 0 ? innerRows : w.maxRows) !== null && _j !== void 0 ? _j : (_k = cg.getMetadata('containerWidget')) === null || _k === void 0 ? void 0 : _k.maxRows) !== null && _l !== void 0 ? _l : rowExtentOf((_m = w.widgets) !== null && _m !== void 0 ? _m : []), float: false, escalate: w.sizing !== 'fit' })));
|
|
1294
1296
|
}
|
|
1295
1297
|
/**
|
|
1296
1298
|
* One reporter for every binder on a view — the view's own and each
|
|
@@ -429,6 +429,13 @@ interface BinderPeer {
|
|
|
429
429
|
group: GroupModel;
|
|
430
430
|
/** True when this board's engine holds `id` as an item (member lookup). */
|
|
431
431
|
hasItem(id: string): boolean;
|
|
432
|
+
/**
|
|
433
|
+
* Drop this board's selection: a press that selects a tile on ONE board of
|
|
434
|
+
* a canvas clears the others, so a section and its parent never show two
|
|
435
|
+
* rings at once (Quantia Groups page: three tiles selected across three
|
|
436
|
+
* boards after three clicks).
|
|
437
|
+
*/
|
|
438
|
+
clearSelection?(): void;
|
|
432
439
|
/** The member's current cell in this board (undefined when absent). */
|
|
433
440
|
memberCell(id: string): CellRect | undefined;
|
|
434
441
|
/**
|
|
@@ -490,6 +497,8 @@ interface AdoptedLeg {
|
|
|
490
497
|
* unregister. A split board adopts nothing and grows no slab: its `adopt`
|
|
491
498
|
* answers null and `resizeMemberBy` answers unchanged.
|
|
492
499
|
*/
|
|
500
|
+
/** Clear the selection on every OTHER board of the canvas — one selection per canvas. */
|
|
501
|
+
export declare function clearOtherSelections(container: HTMLElement, self: BinderPeer | null): void;
|
|
493
502
|
export declare function registerBoardPeer(container: HTMLElement, peer: BinderPeer): () => void;
|
|
494
503
|
export type { BinderPeer };
|
|
495
504
|
export declare function bindDashboardGrid(api: DashboardGridApi, group: GroupModel, options?: DashboardGridOptions): DashboardGridHandle;
|
|
@@ -153,6 +153,13 @@ 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
|
+
/** Clear the selection on every OTHER board of the canvas — one selection per canvas. */
|
|
157
|
+
export function clearOtherSelections(container, self) {
|
|
158
|
+
var _a, _b;
|
|
159
|
+
for (const p of (_a = BOARD_REGISTRY.get(container)) !== null && _a !== void 0 ? _a : [])
|
|
160
|
+
if (p !== self)
|
|
161
|
+
(_b = p.clearSelection) === null || _b === void 0 ? void 0 : _b.call(p);
|
|
162
|
+
}
|
|
156
163
|
export function registerBoardPeer(container, peer) {
|
|
157
164
|
let set = BOARD_REGISTRY.get(container);
|
|
158
165
|
if (!set) {
|
|
@@ -280,8 +287,17 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
280
287
|
const minRowHeight = (_e = options.minRowHeight) !== null && _e !== void 0 ? _e : 28;
|
|
281
288
|
const squeeze = options.squeeze !== false;
|
|
282
289
|
let float = (_f = options.float) !== null && _f !== void 0 ? _f : false;
|
|
283
|
-
/**
|
|
284
|
-
|
|
290
|
+
/**
|
|
291
|
+
* The AUTHORED bound — a nested section's design (row-first push,
|
|
292
|
+
* escalation) — and the LIVE bound the gestures respect. A section that
|
|
293
|
+
* escalation grew holds more rows than its design; the live bound follows
|
|
294
|
+
* the members' extent on every rebuild (reload, undo, refresh), and a shrink
|
|
295
|
+
* never takes the section below `designRows`.
|
|
296
|
+
*/
|
|
297
|
+
const designRows = options.maxRows;
|
|
298
|
+
let maxRows = options.maxRows;
|
|
299
|
+
const extentOf = (items) => items.reduce((m, i) => Math.max(m, i.y + i.h), 0);
|
|
300
|
+
const liveBound = (items) => designRows === undefined ? undefined : Math.max(designRows, extentOf(items));
|
|
285
301
|
/** May a pull past the bound grow the slab in the parent? `false` = the pane is the bound. */
|
|
286
302
|
const escalate = options.escalate !== false;
|
|
287
303
|
const dragOut = (_g = options.dragOut) !== null && _g !== void 0 ? _g : 'cancel';
|
|
@@ -314,6 +330,7 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
314
330
|
* kit's documented boot contract) and turning float off.
|
|
315
331
|
*/
|
|
316
332
|
const engineFrom = (items, pack = false, at = columns) => {
|
|
333
|
+
maxRows = liveBound(items);
|
|
317
334
|
const e = new GridPackEngine(items, { columns: at, float: pack ? float : true, maxRows, capacity });
|
|
318
335
|
e.float = float;
|
|
319
336
|
return e;
|
|
@@ -691,11 +708,15 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
691
708
|
*/
|
|
692
709
|
let selectedId;
|
|
693
710
|
const selectWidget = (id) => {
|
|
711
|
+
if (id !== undefined)
|
|
712
|
+
clearOtherSelections(api.container, selfPeerRef);
|
|
694
713
|
if (id === selectedId)
|
|
695
714
|
return;
|
|
696
715
|
selectedId = id;
|
|
697
716
|
syncA11y();
|
|
698
717
|
};
|
|
718
|
+
/** Set once the peer object exists (below); `selectWidget` runs before that only on boot. */
|
|
719
|
+
let selfPeerRef = null;
|
|
699
720
|
const syncA11y = (only) => {
|
|
700
721
|
var _a, _b;
|
|
701
722
|
if (disposed)
|
|
@@ -1171,6 +1192,10 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1171
1192
|
else {
|
|
1172
1193
|
engine.cancelGesture();
|
|
1173
1194
|
}
|
|
1195
|
+
if (designRows !== undefined) {
|
|
1196
|
+
maxRows = liveBound(engine.getItems());
|
|
1197
|
+
engine.maxRows = maxRows;
|
|
1198
|
+
}
|
|
1174
1199
|
// Restore every pixel to its gesture-start state.
|
|
1175
1200
|
writing = true;
|
|
1176
1201
|
try {
|
|
@@ -1375,23 +1400,24 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1375
1400
|
// the strip's CURRENT slab rows, whatever gesture created them; the
|
|
1376
1401
|
// ledger just accumulates this gesture's net change for the one-batch
|
|
1377
1402
|
// commit and for Escape.
|
|
1378
|
-
// ESCALATION
|
|
1379
|
-
//
|
|
1380
|
-
//
|
|
1381
|
-
// a
|
|
1382
|
-
//
|
|
1383
|
-
//
|
|
1384
|
-
//
|
|
1385
|
-
//
|
|
1386
|
-
//
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1403
|
+
// NESTED ESCALATION — a section is a board one level down, and a pull
|
|
1404
|
+
// inside it can need rows the section does not hold. Two shapes:
|
|
1405
|
+
// · a tile spanning the section's FULL HEIGHT (every tile of a one-row
|
|
1406
|
+
// KPI strip): the section gains a row and every full-height tile grows
|
|
1407
|
+
// with it — a row of tiles pulled taller stays a row (s21) — and gives
|
|
1408
|
+
// it back when pulled up, never below the design;
|
|
1409
|
+
// · a PARTIAL tile (a one-row control in a 14-row panel): it pushes what
|
|
1410
|
+
// is below it; a row the pushed layout needs and the section does not
|
|
1411
|
+
// hold is asked of the board, one per pointer step, and rows the
|
|
1412
|
+
// layout no longer needs go back. The board decides: grow extends, fit
|
|
1413
|
+
// squeezes or refuses. The first version grew the section only for
|
|
1414
|
+
// the full-height case and REFUSED the partial one; before that it
|
|
1415
|
+
// shrank a 14-row panel to 4 (Quantia, Groups page).
|
|
1416
|
+
// The live bound `maxRows` follows the section's rows through all of it.
|
|
1417
|
+
if (designRows !== undefined && maxRows !== undefined && escalate && g.kind === 'resize') {
|
|
1390
1418
|
const parent = parentPeer();
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
const slabRows = (_h = (_g = parent.memberCell(group.id)) === null || _g === void 0 ? void 0 : _g.h) !== null && _h !== void 0 ? _h : 1;
|
|
1394
|
-
const rowPx = visual / Math.max(1, slabRows);
|
|
1419
|
+
const pulled = engine.getItem(g.id);
|
|
1420
|
+
if (parent && pulled) {
|
|
1395
1421
|
const record = (res, d) => {
|
|
1396
1422
|
if (!res.changed || !res.cellBefore || !res.cellAfter || !res.frameBefore || !res.frameAfter)
|
|
1397
1423
|
return;
|
|
@@ -1408,14 +1434,83 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1408
1434
|
g.esc.rowsAdded += d;
|
|
1409
1435
|
g.esc.cellAfter = res.cellAfter;
|
|
1410
1436
|
g.esc.frameAfter = res.frameAfter;
|
|
1411
|
-
project();
|
|
1412
1437
|
};
|
|
1413
|
-
|
|
1414
|
-
|
|
1438
|
+
const setInnerRows = (n) => {
|
|
1439
|
+
maxRows = n;
|
|
1440
|
+
engine.maxRows = n;
|
|
1441
|
+
};
|
|
1442
|
+
const slabRows = (_h = (_g = parent.memberCell(group.id)) === null || _g === void 0 ? void 0 : _g.h) !== null && _h !== void 0 ? _h : maxRows;
|
|
1443
|
+
const inner = maxRows;
|
|
1444
|
+
const rhNow = rowHeightFor(geom(), rows());
|
|
1445
|
+
const rowPx = rhNow + gap;
|
|
1446
|
+
// The SAME rounding the resize path quantises with, or the tile shrinks
|
|
1447
|
+
// through that path first and the section never gets its row back.
|
|
1448
|
+
const wantRows = Math.max(1, Math.round((h + gap) / rowPx));
|
|
1449
|
+
const wantsMore = wantRows > pulled.h;
|
|
1450
|
+
const wantsLess = wantRows < pulled.h;
|
|
1451
|
+
const fullHeight = pulled.y === 0 && pulled.h >= inner;
|
|
1452
|
+
const fullOnes = engine.getItems().filter((i) => i.y === 0 && i.h >= inner).map((i) => i.id);
|
|
1453
|
+
const resizeAll = (ids, rowsTo) => {
|
|
1454
|
+
for (const id of ids) {
|
|
1455
|
+
const it = engine.getItem(id);
|
|
1456
|
+
if (it)
|
|
1457
|
+
engine.resizeCheck(id, it.w, rowsTo);
|
|
1458
|
+
}
|
|
1459
|
+
};
|
|
1460
|
+
let touched = false;
|
|
1461
|
+
if (wantsMore) {
|
|
1462
|
+
if (fullHeight) {
|
|
1463
|
+
const res = parent.resizeMemberBy(group.id, +1);
|
|
1464
|
+
if (res.changed) {
|
|
1465
|
+
record(res, +1);
|
|
1466
|
+
setInnerRows(inner + 1);
|
|
1467
|
+
resizeAll(fullOnes, inner + 1);
|
|
1468
|
+
touched = true;
|
|
1469
|
+
}
|
|
1470
|
+
}
|
|
1471
|
+
else if (!engine.resizeCheck(g.id, pulled.w, pulled.h + 1).changed) {
|
|
1472
|
+
const res = parent.resizeMemberBy(group.id, +1);
|
|
1473
|
+
if (res.changed) {
|
|
1474
|
+
record(res, +1);
|
|
1475
|
+
setInnerRows(inner + 1);
|
|
1476
|
+
engine.resizeCheck(g.id, pulled.w, pulled.h + 1);
|
|
1477
|
+
touched = true;
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
else {
|
|
1481
|
+
touched = true;
|
|
1482
|
+
}
|
|
1415
1483
|
}
|
|
1416
|
-
else if (
|
|
1417
|
-
|
|
1484
|
+
else if (wantsLess) {
|
|
1485
|
+
if (fullHeight) {
|
|
1486
|
+
if (slabRows > designRows && inner > 1) {
|
|
1487
|
+
resizeAll(fullOnes, inner - 1);
|
|
1488
|
+
const res = parent.resizeMemberBy(group.id, -1);
|
|
1489
|
+
if (res.changed) {
|
|
1490
|
+
record(res, -1);
|
|
1491
|
+
setInnerRows(inner - 1);
|
|
1492
|
+
}
|
|
1493
|
+
else {
|
|
1494
|
+
resizeAll(fullOnes, inner);
|
|
1495
|
+
}
|
|
1496
|
+
touched = true;
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
else if (pulled.h > 1) {
|
|
1500
|
+
engine.resizeCheck(g.id, pulled.w, pulled.h - 1);
|
|
1501
|
+
const floor = Math.max(designRows, extentOf(engine.getItems()));
|
|
1502
|
+
if (slabRows > floor) {
|
|
1503
|
+
const res = parent.resizeMemberBy(group.id, -1);
|
|
1504
|
+
if (res.changed) {
|
|
1505
|
+
record(res, -1);
|
|
1506
|
+
setInnerRows(inner - 1);
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
touched = true;
|
|
1510
|
+
}
|
|
1418
1511
|
}
|
|
1512
|
+
if (touched)
|
|
1513
|
+
project();
|
|
1419
1514
|
}
|
|
1420
1515
|
}
|
|
1421
1516
|
// The fluid preview must not outrun what the board can accept: on a
|
|
@@ -1706,6 +1801,12 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1706
1801
|
};
|
|
1707
1802
|
const selfPeer = {
|
|
1708
1803
|
group,
|
|
1804
|
+
clearSelection: () => {
|
|
1805
|
+
if (selectedId === undefined)
|
|
1806
|
+
return;
|
|
1807
|
+
selectedId = undefined;
|
|
1808
|
+
syncA11y();
|
|
1809
|
+
},
|
|
1709
1810
|
hasItem: (id) => !!engine.getItem(id),
|
|
1710
1811
|
memberCell: (id) => {
|
|
1711
1812
|
const it = engine.getItem(id);
|
|
@@ -1742,6 +1843,9 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1742
1843
|
adopt,
|
|
1743
1844
|
};
|
|
1744
1845
|
peersOnCanvas().add(selfPeer);
|
|
1846
|
+
selfPeerRef = selfPeer;
|
|
1847
|
+
// The board's gap, for chrome that must fit BETWEEN tiles (the outside grip tab).
|
|
1848
|
+
api.container.style.setProperty('--axdb-gap', `${gap}px`);
|
|
1745
1849
|
const tool = {
|
|
1746
1850
|
id: `dashboard-grid:${group.id}:${++binderSeq}`,
|
|
1747
1851
|
priority: 2, // point-specific claim — outranks mode-style tools (see ext/tools.ts)
|
|
@@ -1986,7 +2090,7 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1986
2090
|
return;
|
|
1987
2091
|
if (focusedId !== hit.id || selectedId !== hit.id) {
|
|
1988
2092
|
focusedId = hit.id;
|
|
1989
|
-
|
|
2093
|
+
selectWidget(hit.id);
|
|
1990
2094
|
syncA11y();
|
|
1991
2095
|
}
|
|
1992
2096
|
};
|
|
@@ -2338,7 +2442,7 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
2338
2442
|
if (disposed || !((_a = group.members) !== null && _a !== void 0 ? _a : new Set()).has(id) || !diagram.getNode(id))
|
|
2339
2443
|
return false;
|
|
2340
2444
|
focusedId = id;
|
|
2341
|
-
|
|
2445
|
+
selectWidget(id);
|
|
2342
2446
|
syncA11y();
|
|
2343
2447
|
(_c = (_b = hostOf(id)) === null || _b === void 0 ? void 0 : _b.focus) === null || _c === void 0 ? void 0 : _c.call(_b, { preventScroll: true });
|
|
2344
2448
|
return true;
|
|
@@ -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 { dragHandleSelector, gripHostOf, gripOf, normalizeDragHandle, ownsPress, pressOnDragHandle, registerBoardPeer, syncGrip, DRAG_HANDLE_CLASS } from './grid-binder.js';
|
|
28
|
+
import { clearOtherSelections, dragHandleSelector, gripHostOf, gripOf, normalizeDragHandle, ownsPress, pressOnDragHandle, registerBoardPeer, syncGrip, DRAG_HANDLE_CLASS } 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';
|
|
@@ -372,11 +372,14 @@ export function bindDashboardSplit(api, group, options = {}) {
|
|
|
372
372
|
/** The selected widget (see grid-binder): stamped `axdb-selected`, shows the grip. */
|
|
373
373
|
let selectedId;
|
|
374
374
|
const selectWidget = (id) => {
|
|
375
|
+
if (id !== undefined)
|
|
376
|
+
clearOtherSelections(api.container, selfPeerRef);
|
|
375
377
|
if (id === selectedId)
|
|
376
378
|
return;
|
|
377
379
|
selectedId = id;
|
|
378
380
|
syncA11y();
|
|
379
381
|
};
|
|
382
|
+
let selfPeerRef = null;
|
|
380
383
|
// Static boards let content be clicked — see grid-binder's staticGuard.
|
|
381
384
|
const staticGuard = (e) => {
|
|
382
385
|
var _a, _b, _c, _d;
|
|
@@ -823,7 +826,7 @@ export function bindDashboardSplit(api, group, options = {}) {
|
|
|
823
826
|
return;
|
|
824
827
|
if (focusedId !== hit.id || selectedId !== hit.id) {
|
|
825
828
|
focusedId = hit.id;
|
|
826
|
-
|
|
829
|
+
selectWidget(hit.id);
|
|
827
830
|
syncA11y();
|
|
828
831
|
}
|
|
829
832
|
};
|
|
@@ -967,7 +970,26 @@ export function bindDashboardSplit(api, group, options = {}) {
|
|
|
967
970
|
if (layerEl && hostObserver)
|
|
968
971
|
hostObserver.observe(layerEl, { childList: true });
|
|
969
972
|
// -- the handle -------------------------------------------------------------
|
|
970
|
-
|
|
973
|
+
/**
|
|
974
|
+
* The row count the tree's cells are written in. A grid-authored board (or
|
|
975
|
+
* one switched from the grid) carries its members' cells: their extent IS
|
|
976
|
+
* the row count, and switching back must return the same cells — the guess
|
|
977
|
+
* below quantised three 14-row sections on a 758-px fit board to 5 rows
|
|
978
|
+
* (base row height 130), and the grid came back with 14-row inner grids
|
|
979
|
+
* inside 5-row slabs (Quantia, Groups page, Split → Grid). The guess stays
|
|
980
|
+
* for a tree-authored board that never had cells.
|
|
981
|
+
*/
|
|
982
|
+
const rowsAtBind = (() => {
|
|
983
|
+
let max = 0;
|
|
984
|
+
for (const id of members()) {
|
|
985
|
+
const c = persistedCell(id);
|
|
986
|
+
if (!c)
|
|
987
|
+
return undefined;
|
|
988
|
+
max = Math.max(max, c.y + c.h);
|
|
989
|
+
}
|
|
990
|
+
return max > 0 ? max : undefined;
|
|
991
|
+
})();
|
|
992
|
+
const rowsGuess = () => rowsAtBind !== null && rowsAtBind !== void 0 ? rowsAtBind : Math.max(1, Math.round(frame().height / (baseRowHeight + gap)));
|
|
971
993
|
const handle = {
|
|
972
994
|
sync() {
|
|
973
995
|
if (disposed)
|
|
@@ -1021,7 +1043,7 @@ export function bindDashboardSplit(api, group, options = {}) {
|
|
|
1021
1043
|
if (!((_a = group.members) !== null && _a !== void 0 ? _a : new Set()).has(id) || !diagram.getNode(id))
|
|
1022
1044
|
return false;
|
|
1023
1045
|
focusedId = id;
|
|
1024
|
-
|
|
1046
|
+
selectWidget(id);
|
|
1025
1047
|
syncA11y();
|
|
1026
1048
|
(_c = (_b = hostOf(id)) === null || _b === void 0 ? void 0 : _b.focus) === null || _c === void 0 ? void 0 : _c.call(_b, { preventScroll: true });
|
|
1027
1049
|
return true;
|
|
@@ -1168,8 +1190,14 @@ export function bindDashboardSplit(api, group, options = {}) {
|
|
|
1168
1190
|
api.renderNow();
|
|
1169
1191
|
// A split board on a CONTAINER (item 7) sits inside a parent grid: register
|
|
1170
1192
|
// as a peer so the parent's hitTest hands presses on our tiles to us.
|
|
1171
|
-
const
|
|
1193
|
+
const selfPeer = {
|
|
1172
1194
|
group,
|
|
1195
|
+
clearSelection: () => {
|
|
1196
|
+
if (selectedId === undefined)
|
|
1197
|
+
return;
|
|
1198
|
+
selectedId = undefined;
|
|
1199
|
+
syncA11y();
|
|
1200
|
+
},
|
|
1173
1201
|
hasItem: (id) => { var _a; return ((_a = group.members) !== null && _a !== void 0 ? _a : new Set()).has(id); },
|
|
1174
1202
|
memberCell: (id) => handle.cellOf(id),
|
|
1175
1203
|
resizeMemberBy: () => ({ changed: false }),
|
|
@@ -1180,7 +1208,10 @@ export function bindDashboardSplit(api, group, options = {}) {
|
|
|
1180
1208
|
return f.width * f.height;
|
|
1181
1209
|
},
|
|
1182
1210
|
adopt: () => null,
|
|
1183
|
-
}
|
|
1211
|
+
};
|
|
1212
|
+
const unregisterPeer = registerBoardPeer(api.container, selfPeer);
|
|
1213
|
+
selfPeerRef = selfPeer;
|
|
1214
|
+
api.container.style.setProperty('--axdb-gap', `${gap}px`);
|
|
1184
1215
|
const disposeHandle = handle.dispose.bind(handle);
|
|
1185
1216
|
handle.dispose = () => {
|
|
1186
1217
|
unregisterPeer();
|
|
@@ -235,7 +235,10 @@ const CSS = `
|
|
|
235
235
|
.grafloria-node-host > .axdb-grip--inside { top: 2px; }
|
|
236
236
|
}
|
|
237
237
|
/* OUTSIDE: a tab on the card's top edge, its corners in line with the card's. */
|
|
238
|
-
|
|
238
|
+
/* The OUTSIDE tab lives in the gap between tiles: never taller than the gap
|
|
239
|
+
less a pixel (an 11-px tab in a 10-px gap sat on the tile above), never
|
|
240
|
+
shorter than 6 px so the dots still read. */
|
|
241
|
+
.grafloria-node-host > .axdb-grip--outside { top: calc(-1 * clamp(6px, var(--axdb-gap, 11px) - 1px, 11px)); height: clamp(6px, calc(var(--axdb-gap, 11px) - 1px), 11px); border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-bottom: 0; box-shadow: 0 -1px 2px rgba(16, 24, 40, .08); }
|
|
239
242
|
.grafloria-node-host > .axdb-grip--outside.axdb-grip--left { left: 10px; }
|
|
240
243
|
.grafloria-node-host > .axdb-grip--outside.axdb-grip--right { right: 10px; }
|
|
241
244
|
.grafloria-node-host > .axdb-grip--center { left: 50%; transform: translateX(-50%); }
|