@grafloria/element 0.4.45 → 0.4.46

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafloria/element",
3
- "version": "0.4.45",
3
+ "version": "0.4.46",
4
4
  "type": "module",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
@@ -1264,27 +1264,31 @@ export function bindDashboardGrid(api, group, options = {}) {
1264
1264
  const TAB_FRAME_GRIP = 3;
1265
1265
  const edgeGripFor = (grp) => (isTabsGroup(grp) ? TAB_FRAME_GRIP : EDGE_GRIP);
1266
1266
  const BESIDE_BAND = 0.2;
1267
+ /** The outer band of a container FRAME the point is in — null in the strip, in the middle, or outside. */
1268
+ const bandOf = (f, wx, wy) => {
1269
+ if (wx < f.x || wx > f.x + f.width || wy < f.y || wy > f.y + f.height)
1270
+ return null;
1271
+ const bodyY = f.y + TAB_STRIP_HEIGHT;
1272
+ const bodyH = Math.max(1, f.height - TAB_STRIP_HEIGHT);
1273
+ const rx = (wx - f.x) / Math.max(1, f.width);
1274
+ const ry = (wy - bodyY) / bodyH;
1275
+ if (ry < 0)
1276
+ return null; // the strip: a new tab, the strip's own business
1277
+ if (rx >= BESIDE_BAND && rx <= 1 - BESIDE_BAND && ry >= BESIDE_BAND && ry <= 1 - BESIDE_BAND)
1278
+ return null; // the middle: into the page
1279
+ const d = [['left', rx], ['right', 1 - rx], ['top', ry], ['bottom', 1 - ry]];
1280
+ d.sort((a, b) => a[1] - b[1]);
1281
+ return d[0][0];
1282
+ };
1267
1283
  const besideZoneAt = (wx, wy) => {
1268
1284
  var _a;
1269
1285
  for (const id of (_a = group.members) !== null && _a !== void 0 ? _a : []) {
1270
1286
  const grp = diagram.getGroup(id);
1271
1287
  if (!grp || diagram.getNode(id) || !isTabsGroup(grp))
1272
1288
  continue;
1273
- const p = grp.position;
1274
- const sz = sizeOf(grp);
1275
- if (wx < p.x || wx > p.x + sz.width || wy < p.y || wy > p.y + sz.height)
1276
- continue;
1277
- const bodyY = p.y + TAB_STRIP_HEIGHT;
1278
- const bodyH = Math.max(1, sz.height - TAB_STRIP_HEIGHT);
1279
- const rx = (wx - p.x) / Math.max(1, sz.width);
1280
- const ry = (wy - bodyY) / bodyH;
1281
- if (ry < 0)
1282
- return null; // the strip: a new tab, the strip's own business
1283
- if (rx >= BESIDE_BAND && rx <= 1 - BESIDE_BAND && ry >= BESIDE_BAND && ry <= 1 - BESIDE_BAND)
1284
- return null; // the middle: into the page
1285
- const d = [['left', rx], ['right', 1 - rx], ['top', ry], ['bottom', 1 - ry]];
1286
- d.sort((a, b) => a[1] - b[1]);
1287
- return { id, side: d[0][0] };
1289
+ const side = bandOf(frameOfGroup(grp), wx, wy);
1290
+ if (side)
1291
+ return { id, side };
1288
1292
  }
1289
1293
  return null;
1290
1294
  };
@@ -1296,8 +1300,17 @@ export function bindDashboardGrid(api, group, options = {}) {
1296
1300
  const it = engine.getItem(beside.id);
1297
1301
  if (it && restore && (it.x !== beside.from.x || it.y !== beside.from.y))
1298
1302
  engine.moveCheck(beside.id, beside.from.x, beside.from.y, { gate: false });
1303
+ if (restore) {
1304
+ // The sections the shift pushed come back with it.
1305
+ for (const [oid, c] of beside.others) {
1306
+ const o = engine.getItem(oid);
1307
+ if (o && (o.x !== c.x || o.y !== c.y))
1308
+ engine.moveCheck(oid, c.x, c.y, { gate: false });
1309
+ }
1310
+ }
1299
1311
  if (it)
1300
1312
  it.locked = true;
1313
+ relockOthersForSlab();
1301
1314
  beside = null;
1302
1315
  };
1303
1316
  const applyBeside = (g, z) => {
@@ -1316,8 +1329,8 @@ export function bindDashboardGrid(api, group, options = {}) {
1316
1329
  (_a = hostOf(g.id)) === null || _a === void 0 ? void 0 : _a.classList.remove('axdb-out');
1317
1330
  engine.add({ id: g.id, x: 0, y: engine.rows(), w, h });
1318
1331
  }
1319
- if (beside && beside.id !== z.id)
1320
- endBeside(true);
1332
+ if (beside && (beside.id !== z.id || beside.side !== z.side))
1333
+ endBeside(true); // another container, or another side of it: start over from the rest layout
1321
1334
  const from = beside ? beside.from : { x: tc.x, y: tc.y };
1322
1335
  let cell;
1323
1336
  let shiftTo = null;
@@ -1344,12 +1357,23 @@ export function bindDashboardGrid(api, group, options = {}) {
1344
1357
  }
1345
1358
  if (shiftTo && shiftTo.x < 0)
1346
1359
  shiftTo = null; // no room even shifted: the widget goes where it can
1347
- if (!beside)
1348
- beside = { id: z.id, from, vacated: cell };
1360
+ if (!beside) {
1361
+ // The other sections give way to the shift the way they give way to a
1362
+ // moved group (0.4.44): on the demo the Operations section spans the
1363
+ // row under the panel and a locked tile refused the shift outright.
1364
+ // Their cells are kept so they come back if the pointer leaves.
1365
+ const others = new Map();
1366
+ for (const o of engine.getItems())
1367
+ if (o.id !== z.id && o.id !== g.id && isGroupMember(o.id))
1368
+ others.set(o.id, { x: o.x, y: o.y });
1369
+ const grp0 = diagram.getGroup(z.id);
1370
+ beside = { id: z.id, side: z.side, from, frame0: grp0 ? frameOfGroup(grp0) : cellToRect({ x: from.x, y: from.y, w: tc.w, h: tc.h }, frame(), geom(), rows()), vacated: cell, others };
1371
+ unlockOthersForSlab(z.id);
1372
+ }
1349
1373
  tc.locked = false; // for the gesture: it shifts, or the ghost pushes it
1350
- // The ghost steps off the board while the container shifts: on a bounded
1351
- // board a chart as wide as the panel had its own cell as the panel's
1352
- // target, could not be pushed down, and the shift was refused (lab L94).
1374
+ // The ghost steps off the board while the container shifts: the engine
1375
+ // will not push the dragged tile, so a chart as wide as the panel had its
1376
+ // own cell as the panel's target and the shift was refused (lab L94).
1353
1377
  // Then it takes the cell the shift vacated.
1354
1378
  if (shiftTo && (tc.x !== shiftTo.x || tc.y !== shiftTo.y)) {
1355
1379
  if (engine.getItem(g.id))
@@ -2082,8 +2106,18 @@ export function bindDashboardGrid(api, group, options = {}) {
2082
2106
  // is what "beside" leaves under the pointer once the container has
2083
2107
  // shifted away (the ghost's wanted cell carries the grab offset and
2084
2108
  // read as "elsewhere" a move later, and the shift undid itself).
2109
+ // "Still here" is the pointer in the SAME band of the container's
2110
+ // ORIGINAL frame (it asked for beside from there, and the container
2111
+ // is what moved) or over the cell the widget took: a one-row
2112
+ // widget's cell is not where a hand hovering the band sits, and
2113
+ // testing only that undid the shift on the next move, which pushed
2114
+ // the widget to the bottom as the panel came back (live walk N).
2115
+ // "Anywhere inside the original frame" is too much: a hand crossing
2116
+ // the bottom band on its way to the middle never reached the page
2117
+ // (lab L73) — the middle of the original frame is a zone change.
2085
2118
  const r = cellToRect({ x: beside.vacated.x, y: beside.vacated.y, w: g.spans.w, h: g.spans.h }, frame(), geom(), rows());
2086
- const over = ev.world.x >= r.x - gap && ev.world.x <= r.x + r.width + gap && ev.world.y >= r.y - gap && ev.world.y <= r.y + r.height + gap;
2119
+ const inR = (q) => ev.world.x >= q.x - gap && ev.world.x <= q.x + q.width + gap && ev.world.y >= q.y - gap && ev.world.y <= q.y + q.height + gap;
2120
+ const over = bandOf(beside.frame0, ev.world.x, ev.world.y) === beside.side || inR(r);
2087
2121
  if (!over)
2088
2122
  endBeside(true);
2089
2123
  else {