@grafloria/element 0.4.61 → 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grafloria/element",
3
- "version": "0.4.61",
3
+ "version": "0.4.62",
4
4
  "type": "module",
5
5
  "main": "./src/index.js",
6
6
  "types": "./src/index.d.ts",
@@ -2197,6 +2197,11 @@ export function bindDashboardGrid(api, group, options = {}) {
2197
2197
  frame: frameOfGroup(grp),
2198
2198
  stripHeight: layout === 'tabs' ? TAB_STRIP_HEIGHT : 0,
2199
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,
2200
2205
  inner: innerPeer ? boardRef(innerPeer, depth + 1) : null,
2201
2206
  });
2202
2207
  }
@@ -2287,7 +2292,7 @@ export function bindDashboardGrid(api, group, options = {}) {
2287
2292
  containerId: pendingBeside.id,
2288
2293
  side: pendingBeside.side,
2289
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()); })(),
2290
- vacated: 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
2291
2296
  }
2292
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
2293
2298
  maxDepth: nesting,
@@ -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
- vacated: ZoneRect;
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
- if (ry < band)
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 (ry > 1 - band)
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 stripH = stripHeightOf(input.roots, p.containerId);
142
- const stay = bandOf(p.frame0, stripH, x, y, BESIDE_BAND + BESIDE_STAY);
143
- const other = bandOf(p.frame0, stripH, x, y);
144
- const held = stay === p.side || (!(other !== null && other !== p.side) && inRect(p.vacated, x, y, input.gap));
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
- function stripHeightOf(roots, containerId) {
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.stripHeight;
231
+ return c;
218
232
  const deeper = c.inner ? visit(c.inner) : null;
219
- if (deeper !== null)
233
+ if (deeper)
220
234
  return deeper;
221
235
  }
222
236
  return null;
223
237
  };
224
238
  for (const r of roots) {
225
- const h = visit(r);
226
- if (h !== null)
227
- return h;
239
+ const c = visit(r);
240
+ if (c)
241
+ return c;
228
242
  }
229
- return 0;
243
+ return null;
230
244
  }
231
245
  /**
232
246
  * What a pointer means for a TORN-OUT PAGE, in the one order both binders