@grafloria/element 0.4.66 → 0.4.68
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
|
@@ -996,6 +996,8 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
996
996
|
let slabGesture = null;
|
|
997
997
|
/** The gesture as it is NOW, for the same reason. */
|
|
998
998
|
const currentGesture = () => gesture;
|
|
999
|
+
/** Where the hand was at the PREVIOUS move event — the strip is tested along the segment between the two. */
|
|
1000
|
+
let prevWorld = null;
|
|
999
1001
|
/** The PARENT running a resize of OUR section from a press this tool claimed. */
|
|
1000
1002
|
let forwardSlab = null;
|
|
1001
1003
|
const frameOfGroup = (grp) => ({ x: grp.position.x, y: grp.position.y, width: sizeOf(grp).width, height: sizeOf(grp).height });
|
|
@@ -1236,6 +1238,7 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1236
1238
|
};
|
|
1237
1239
|
// -- the gesture machine ----------------------------------------------------
|
|
1238
1240
|
const beginGestureVisuals = (g) => {
|
|
1241
|
+
prevWorld = null;
|
|
1239
1242
|
engine.beginGesture();
|
|
1240
1243
|
const snap = snapshotAll();
|
|
1241
1244
|
g.startCells = snap.cells;
|
|
@@ -1432,6 +1435,7 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
1432
1435
|
nodeOf(g).setPosition(desired.x, desired.y);
|
|
1433
1436
|
ghostStyleFastPath(g, desired);
|
|
1434
1437
|
}
|
|
1438
|
+
prevWorld = g.lastWorld;
|
|
1435
1439
|
g.lastWorld = { x: ev.world.x, y: ev.world.y };
|
|
1436
1440
|
g.lastScreen = { x: ev.screen.x, y: ev.screen.y };
|
|
1437
1441
|
/** The ghost's pixel size on THIS board — a palette chip has spans, not a size. */
|
|
@@ -2194,7 +2198,7 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
2194
2198
|
};
|
|
2195
2199
|
/** What the pointer means for the dragged tile: the resolve over the live tree, with the beside the hand holds. */
|
|
2196
2200
|
const resolveTileZone = (g, ev) => {
|
|
2197
|
-
var _a, _b, _c, _d, _e;
|
|
2201
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2198
2202
|
const roots = zoneRoots();
|
|
2199
2203
|
// THE CONTAINERS THIS GESTURE HAS MOVED, at the frames they rest in. A
|
|
2200
2204
|
// drag's own pushes must never change what the hand means — settled for a
|
|
@@ -2207,7 +2211,45 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
2207
2211
|
if (((_a = options.tabDrop) === null || _a === void 0 ? void 0 : _a.tabIndexAt) && !isStatic && g.kind !== 'palette' && g.subject === 'node') {
|
|
2208
2212
|
// A group never becomes a tab: over a container's strip it is over the
|
|
2209
2213
|
// container's margin — a cell on the parent board, pushing with intent.
|
|
2210
|
-
const
|
|
2214
|
+
const scaleY = clientPerWorld().y || 1;
|
|
2215
|
+
let hit = stripUnder({ x: ev.world.x, y: ev.world.y, roots, held: (_c = (_b = g.strip) === null || _b === void 0 ? void 0 : _b.containerId) !== null && _c !== void 0 ? _c : null, stay: STRIP_STAY / scaleY, restFrames: rests });
|
|
2216
|
+
if (!hit && prevWorld && !g.strip) {
|
|
2217
|
+
// A HAND MOVES FASTER THAN A STRIP IS TALL. (Only for a hand ARRIVING:
|
|
2218
|
+
// one already holding the strip leaves it by the stay, which reaches
|
|
2219
|
+
// down and never up — the band above must stay reachable.) The strip is 30 px and a
|
|
2220
|
+
// hand covers 40 to 80 px between events, so testing only where the
|
|
2221
|
+
// pointer LANDS skips it — the user, coming down from above the panel:
|
|
2222
|
+
// "it's not passing by the tab header, it drops directly to inside or
|
|
2223
|
+
// outside." The segment it travelled is tested too, in steps of half a
|
|
2224
|
+
// strip: crossing the rows and landing within one strip's height of
|
|
2225
|
+
// them means the tabs. Flying far past them does not — a fast drag
|
|
2226
|
+
// into the page must never snag on the header.
|
|
2227
|
+
const dx = ev.world.x - prevWorld.x;
|
|
2228
|
+
const dy = ev.world.y - prevWorld.y;
|
|
2229
|
+
const n = Math.ceil(Math.hypot(dx, dy) / (TAB_STRIP_HEIGHT / 2));
|
|
2230
|
+
let crossed = null;
|
|
2231
|
+
for (let i = 1; i < n && !crossed; i++)
|
|
2232
|
+
crossed = (_e = (_d = stripUnder({ x: prevWorld.x + (dx * i) / n, y: prevWorld.y + (dy * i) / n, roots, held: null, stay: 0, restFrames: rests })) === null || _d === void 0 ? void 0 : _d.containerId) !== null && _e !== void 0 ? _e : null;
|
|
2233
|
+
if (crossed) {
|
|
2234
|
+
const grp = diagram.getGroup(crossed);
|
|
2235
|
+
const f = (_f = rests.get(crossed)) !== null && _f !== void 0 ? _f : (grp ? frameOfGroup(grp) : null);
|
|
2236
|
+
if (f) {
|
|
2237
|
+
const top = f.y;
|
|
2238
|
+
const bottom = f.y + TAB_STRIP_HEIGHT;
|
|
2239
|
+
// A CROSSING is the two events on OPPOSITE sides of the rows — a
|
|
2240
|
+
// hand that swept along the tabs from beside the panel and ended
|
|
2241
|
+
// above it did not cross them, it went past them. And the sides
|
|
2242
|
+
// still take the corners (0.4.47): a hand landing in the outer
|
|
2243
|
+
// fifth meant "after it", whatever it crossed on the way.
|
|
2244
|
+
const through = (prevWorld.y < top && ev.world.y > bottom) || (prevWorld.y > bottom && ev.world.y < top);
|
|
2245
|
+
const away = ev.world.y < top ? top - ev.world.y : ev.world.y > bottom ? ev.world.y - bottom : 0;
|
|
2246
|
+
const rx = (ev.world.x - f.x) / Math.max(1, f.width);
|
|
2247
|
+
const inSideBand = rx < BESIDE_BAND || rx > 1 - BESIDE_BAND;
|
|
2248
|
+
if (through && !inSideBand && ev.world.x >= f.x && ev.world.x <= f.x + f.width && away <= TAB_STRIP_HEIGHT / scaleY)
|
|
2249
|
+
hit = { containerId: crossed };
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2211
2253
|
if (hit) {
|
|
2212
2254
|
// The SLOT is the painted strip's business — its tabs are laid out by
|
|
2213
2255
|
// the browser. A container the gesture shifted sideways is painted
|
|
@@ -2228,7 +2270,7 @@ export function bindDashboardGrid(api, group, options = {}) {
|
|
|
2228
2270
|
strip,
|
|
2229
2271
|
prev: beside
|
|
2230
2272
|
? { 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()) }
|
|
2231
|
-
: ((
|
|
2273
|
+
: ((_h = (_g = g.leg) === null || _g === void 0 ? void 0 : _g.adopted.besideState()) !== null && _h !== void 0 ? _h : null), // a beside another board holds for the ghost, through its leg
|
|
2232
2274
|
maxDepth: nesting,
|
|
2233
2275
|
ghostDepth: g.subject === 'group' ? 1 + levelsInside(g.id) : 0, // a group's widgets sit one board deeper than wherever it lands
|
|
2234
2276
|
restFrames: rests,
|
|
@@ -190,50 +190,6 @@ export interface StripProbe {
|
|
|
190
190
|
export declare function stripUnder(p: StripProbe): {
|
|
191
191
|
containerId: string;
|
|
192
192
|
} | null;
|
|
193
|
-
export interface ContainerProbe {
|
|
194
|
-
x: number;
|
|
195
|
-
y: number;
|
|
196
|
-
roots: ZoneBoard[];
|
|
197
|
-
/** Containers the gesture has displaced, at the frames they rest in. */
|
|
198
|
-
restFrames?: ReadonlyMap<string, ZoneRect>;
|
|
199
|
-
/** The groups inside the dragged tile: never a target, so never lit. */
|
|
200
|
-
ghostSubtree?: ReadonlySet<string>;
|
|
201
|
-
/** The containers the dragged tile's own board sits in: their bands do not apply to it, so they are not lit either. */
|
|
202
|
-
homeChain?: ReadonlySet<string>;
|
|
203
|
-
}
|
|
204
|
-
/** A container's edges, for showing a hand what they mean. */
|
|
205
|
-
export interface ContainerBands {
|
|
206
|
-
containerId: string;
|
|
207
|
-
frame: ZoneRect;
|
|
208
|
-
stripHeight: number;
|
|
209
|
-
band: number;
|
|
210
|
-
bandY?: number;
|
|
211
|
-
topOutside?: number;
|
|
212
|
-
}
|
|
213
|
-
/**
|
|
214
|
-
* The deepest container under a pointer whose EDGES mean something — the one
|
|
215
|
-
* whose bands a drag should be shown while it is held there.
|
|
216
|
-
*
|
|
217
|
-
* `bandOf` decides; this only reports where the decision lives, on the same
|
|
218
|
-
* tree and the same frames, so a painted lane and the zone it stands for can
|
|
219
|
-
* never disagree. Without it the bands are invisible: 0.4.62 made the top and
|
|
220
|
-
* bottom a fixed 30 px, which is a fine target and an impossible guess — to
|
|
221
|
-
* put a widget ABOVE a panel you point just BELOW its header, inside what
|
|
222
|
-
* reads as page content. ("Nothing moves it any more, but how can I drag
|
|
223
|
-
* something on top of the tab group?")
|
|
224
|
-
*/
|
|
225
|
-
export declare function containerUnder(p: ContainerProbe): ContainerBands | null;
|
|
226
|
-
/**
|
|
227
|
-
* Where a container's bands are, in the same world units as its frame. TOP
|
|
228
|
-
* appears twice: hanging above the frame, where a hand looking for "above it"
|
|
229
|
-
* goes, and under the strip, which is the only one a container pressed against
|
|
230
|
-
* the top of its canvas can offer. Both mean the same thing.
|
|
231
|
-
*/
|
|
232
|
-
export declare function bandRects(c: ContainerBands): {
|
|
233
|
-
side: BesideSide;
|
|
234
|
-
name: string;
|
|
235
|
-
rect: ZoneRect;
|
|
236
|
-
}[];
|
|
237
193
|
export declare function resolve(input: ResolveInput): Zone;
|
|
238
194
|
/** A join target as the walk sees it: another tab container, its frame anchored by the binder while the pointer is inside it. */
|
|
239
195
|
export interface TabTarget {
|
|
@@ -125,82 +125,24 @@ export function stripUnder(p) {
|
|
|
125
125
|
visit(r, 0, 0);
|
|
126
126
|
return bestId === null ? null : { containerId: bestId };
|
|
127
127
|
}
|
|
128
|
-
/**
|
|
129
|
-
* The deepest container under a pointer whose EDGES mean something — the one
|
|
130
|
-
* whose bands a drag should be shown while it is held there.
|
|
131
|
-
*
|
|
132
|
-
* `bandOf` decides; this only reports where the decision lives, on the same
|
|
133
|
-
* tree and the same frames, so a painted lane and the zone it stands for can
|
|
134
|
-
* never disagree. Without it the bands are invisible: 0.4.62 made the top and
|
|
135
|
-
* bottom a fixed 30 px, which is a fine target and an impossible guess — to
|
|
136
|
-
* put a widget ABOVE a panel you point just BELOW its header, inside what
|
|
137
|
-
* reads as page content. ("Nothing moves it any more, but how can I drag
|
|
138
|
-
* something on top of the tab group?")
|
|
139
|
-
*/
|
|
140
|
-
export function containerUnder(p) {
|
|
141
|
-
const { x, y } = p;
|
|
142
|
-
let best = null;
|
|
143
|
-
let bestDepth = -1;
|
|
144
|
-
const visit = (b, dx, dy) => {
|
|
145
|
-
var _a, _b, _c, _d;
|
|
146
|
-
for (const c of b.children()) {
|
|
147
|
-
if ((_a = p.ghostSubtree) === null || _a === void 0 ? void 0 : _a.has(c.id))
|
|
148
|
-
continue;
|
|
149
|
-
const rest = (_b = p.restFrames) === null || _b === void 0 ? void 0 : _b.get(c.id);
|
|
150
|
-
const atRest = rest && inRect(rest, x, y) ? rest : null;
|
|
151
|
-
const frame = atRest !== null && atRest !== void 0 ? atRest : c.frame;
|
|
152
|
-
const tx = atRest ? x : x + dx;
|
|
153
|
-
const ty = atRest ? y : y + dy;
|
|
154
|
-
const up = (_c = c.topOutside) !== null && _c !== void 0 ? _c : 0;
|
|
155
|
-
const inOverhang = up > 0 && tx >= frame.x && tx <= frame.x + frame.width && ty < frame.y && ty >= frame.y - up;
|
|
156
|
-
if (!inRect(frame, tx, ty) && !inOverhang)
|
|
157
|
-
continue;
|
|
158
|
-
if (c.band > 0 && !((_d = p.homeChain) === null || _d === void 0 ? void 0 : _d.has(c.id)) && b.depth >= bestDepth) {
|
|
159
|
-
best = Object.assign(Object.assign({ containerId: c.id, frame, stripHeight: c.stripHeight, band: c.band }, (c.bandY === undefined ? {} : { bandY: c.bandY })), (c.topOutside === undefined ? {} : { topOutside: c.topOutside }));
|
|
160
|
-
bestDepth = b.depth;
|
|
161
|
-
}
|
|
162
|
-
if (c.inner)
|
|
163
|
-
visit(c.inner, atRest ? c.frame.x - atRest.x : dx, atRest ? c.frame.y - atRest.y : dy);
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
for (const r of p.roots)
|
|
167
|
-
visit(r, 0, 0);
|
|
168
|
-
return best;
|
|
169
|
-
}
|
|
170
|
-
/**
|
|
171
|
-
* Where a container's bands are, in the same world units as its frame. TOP
|
|
172
|
-
* appears twice: hanging above the frame, where a hand looking for "above it"
|
|
173
|
-
* goes, and under the strip, which is the only one a container pressed against
|
|
174
|
-
* the top of its canvas can offer. Both mean the same thing.
|
|
175
|
-
*/
|
|
176
|
-
export function bandRects(c) {
|
|
177
|
-
var _a;
|
|
178
|
-
const bodyY = c.frame.y + c.stripHeight;
|
|
179
|
-
const bodyH = Math.max(1, c.frame.height - c.stripHeight);
|
|
180
|
-
const w = Math.max(1, c.frame.width);
|
|
181
|
-
const side = w * c.band;
|
|
182
|
-
const depth = c.bandY !== undefined && c.bandY > 0 ? Math.min(c.bandY, bodyH / 2) : c.band * bodyH;
|
|
183
|
-
const up = (_a = c.topOutside) !== null && _a !== void 0 ? _a : 0;
|
|
184
|
-
return [
|
|
185
|
-
{ side: 'left', name: 'left', rect: { x: c.frame.x, y: bodyY, width: side, height: bodyH } },
|
|
186
|
-
{ side: 'right', name: 'right', rect: { x: c.frame.x + w - side, y: bodyY, width: side, height: bodyH } },
|
|
187
|
-
// above the frame: the whole width, since no side band is up there to take the corners
|
|
188
|
-
...(up > 0 ? [{ side: 'top', name: 'top', rect: { x: c.frame.x, y: c.frame.y - up, width: w, height: up } }] : []),
|
|
189
|
-
// and under the strip; the sides take the corners here (bandOf tests rx first)
|
|
190
|
-
{ side: 'top', name: 'top-inside', rect: { x: c.frame.x + side, y: bodyY, width: w - 2 * side, height: depth } },
|
|
191
|
-
{ side: 'bottom', name: 'bottom', rect: { x: c.frame.x + side, y: bodyY + bodyH - depth, width: w - 2 * side, height: depth } },
|
|
192
|
-
];
|
|
193
|
-
}
|
|
194
128
|
/**
|
|
195
129
|
* The band a point is in for a TILE drag: the sides and the bottom as
|
|
196
130
|
* `bandOf` gives them, and "top" ONLY from the band hanging above the frame.
|
|
197
|
-
* The rows under the strip are the page.
|
|
131
|
+
* The rows under the strip are the page. A lane there meant "above" too
|
|
132
|
+
* (0.4.62–0.4.66), so a hand coming down at speed read above, above, page —
|
|
133
|
+
* the answer never changed across the header and the tabs looked skipped.
|
|
134
|
+
* One place means above: above (0.4.67).
|
|
198
135
|
*/
|
|
199
136
|
function tileBand(f, stripHeight, x, y, band, bandY, topOutside, grow = 1) {
|
|
200
137
|
const up = (topOutside !== null && topOutside !== void 0 ? topOutside : 0) * grow;
|
|
201
|
-
if (up > 0 && x >= f.x && x <= f.x + f.width && y < f.y && y >= f.y - up)
|
|
202
|
-
|
|
203
|
-
|
|
138
|
+
if (up > 0 && x >= f.x && x <= f.x + f.width && y < f.y && y >= f.y - up) {
|
|
139
|
+
// the sides take the corners here too (0.4.48's precedence): a widget
|
|
140
|
+
// carried along the top of a panel to its far right means "after it"
|
|
141
|
+
const rx = (x - f.x) / Math.max(1, f.width);
|
|
142
|
+
return rx < band ? 'left' : rx > 1 - band ? 'right' : 'top';
|
|
143
|
+
}
|
|
144
|
+
const side = bandOf(f, stripHeight, x, y, band, bandY === undefined ? undefined : bandY * grow);
|
|
145
|
+
return side === 'top' ? null : side;
|
|
204
146
|
}
|
|
205
147
|
/** The board a container sits on, found by id through the tree. */
|
|
206
148
|
function boardOf(roots, containerId) {
|
|
@@ -239,7 +181,12 @@ export function resolve(input) {
|
|
|
239
181
|
const grow = 1 + BESIDE_STAY / BESIDE_BAND;
|
|
240
182
|
const stay = tileBand(p.frame0, stripH, x, y, BESIDE_BAND + BESIDE_STAY, depth, c0 === null || c0 === void 0 ? void 0 : c0.topOutside, grow);
|
|
241
183
|
const other = tileBand(p.frame0, stripH, x, y, BESIDE_BAND, depth, c0 === null || c0 === void 0 ? void 0 : c0.topOutside);
|
|
242
|
-
|
|
184
|
+
// The cell an "above" took is the container's own rest rows, so "over the
|
|
185
|
+
// vacated cell" would hold the beside 130 px into what is the PAGE — a
|
|
186
|
+
// fast hand then saw no change at all across the header. Inside the body
|
|
187
|
+
// the vacated cell does not count; beside the frame it still does.
|
|
188
|
+
const insideBody = inRect(p.frame0, x, y) && y >= p.frame0.y + stripH;
|
|
189
|
+
const onVacated = !!p.vacated && !insideBody && inRect(p.vacated, x, y, input.gap);
|
|
243
190
|
const held = stay === p.side || (!(other !== null && other !== p.side) && onVacated);
|
|
244
191
|
if (held) {
|
|
245
192
|
const board = boardOf(input.roots, p.containerId);
|
|
@@ -287,8 +234,19 @@ export function resolve(input) {
|
|
|
287
234
|
return { kind: 'beside', board, containerId: c.id, side, kept: false };
|
|
288
235
|
if (opaque(board, c) || !c.inner)
|
|
289
236
|
return { kind: 'plain', board, grace: false };
|
|
290
|
-
|
|
291
|
-
|
|
237
|
+
// The margin — inside the frame, outside the inner board — is the
|
|
238
|
+
// container's own tile, in the way. Except a tab container's 8-px inset
|
|
239
|
+
// UNDER ITS STRIP for a plain widget: a widget can never land on the
|
|
240
|
+
// parent board there, the container being solid to it, so "the parent's"
|
|
241
|
+
// was a refusal flashed for 8 px on the way up out of the page (0.4.68);
|
|
242
|
+
// that inset is the page's. The strip rows stay the tile's (a carried
|
|
243
|
+
// GROUP on the strip pushes the container, 0.4.44), and so does the
|
|
244
|
+
// inset for a group: strip and inset push, the page body nests.
|
|
245
|
+
if (!c.inner.contains(x + ndx0, y + ndy0)) {
|
|
246
|
+
const insetUnderStrip = c.layout === 'tabs' && ty >= frame.y + c.stripHeight && input.ghostSubtree.size === 0;
|
|
247
|
+
if (!insetUnderStrip)
|
|
248
|
+
return { kind: 'plain', board, grace: false };
|
|
249
|
+
}
|
|
292
250
|
return descend(c.inner, ndx0, ndy0);
|
|
293
251
|
}
|
|
294
252
|
const over = overhang(board, dx, dy);
|
|
@@ -311,8 +269,10 @@ export function resolve(input) {
|
|
|
311
269
|
const frame = atRest !== null && atRest !== void 0 ? atRest : c.frame;
|
|
312
270
|
const tx = atRest ? x : x + dx;
|
|
313
271
|
const ty = atRest ? y : y + dy;
|
|
314
|
-
|
|
315
|
-
|
|
272
|
+
// only the band above the frame can answer from out here — and its corners are the sides'
|
|
273
|
+
const side = tileBand(frame, c.stripHeight, tx, ty, c.band, c.bandY, c.topOutside);
|
|
274
|
+
if (side)
|
|
275
|
+
return { kind: 'beside', board, containerId: c.id, side, kept: false };
|
|
316
276
|
const deeper = c.inner ? overhang(c.inner, atRest ? c.frame.x - atRest.x : dx, atRest ? c.frame.y - atRest.y : dy) : null;
|
|
317
277
|
if (deeper)
|
|
318
278
|
return deeper;
|