regular-layout 0.2.0 → 0.2.2
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/dist/index.js +6 -6
- package/dist/index.js.map +3 -3
- package/dist/layout/calculate_edge.d.ts +2 -1
- package/dist/layout/calculate_intersect.d.ts +8 -2
- package/dist/layout/constants.d.ts +76 -38
- package/dist/layout/generate_grid.d.ts +4 -3
- package/dist/layout/generate_overlay.d.ts +1 -1
- package/dist/layout/redistribute_panel_sizes.d.ts +1 -1
- package/dist/layout/types.d.ts +3 -7
- package/dist/regular-layout-frame.d.ts +10 -3
- package/dist/regular-layout.d.ts +63 -12
- package/package.json +4 -2
- package/src/layout/calculate_edge.ts +26 -16
- package/src/layout/calculate_intersect.ts +11 -9
- package/src/layout/constants.ts +94 -38
- package/src/layout/generate_grid.ts +71 -27
- package/src/layout/generate_overlay.ts +5 -3
- package/src/layout/insert_child.ts +5 -5
- package/src/layout/redistribute_panel_sizes.ts +20 -9
- package/src/layout/remove_child.ts +7 -7
- package/src/layout/types.ts +3 -7
- package/src/regular-layout-frame.ts +53 -65
- package/src/regular-layout-tab.ts +5 -5
- package/src/regular-layout.ts +206 -114
- package/themes/lorax.css +2 -1
package/src/regular-layout.ts
CHANGED
|
@@ -34,11 +34,21 @@ import { updateOverlaySheet } from "./layout/generate_overlay.ts";
|
|
|
34
34
|
import { calculate_edge } from "./layout/calculate_edge.ts";
|
|
35
35
|
import { flatten } from "./layout/flatten.ts";
|
|
36
36
|
import {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
DEFAULT_PHYSICS,
|
|
38
|
+
type PhysicsUpdate,
|
|
39
|
+
type Physics,
|
|
40
40
|
} from "./layout/constants.ts";
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* An interface which models the fields of `PointerEvent` that
|
|
44
|
+
* `<regular-layour>` actually uses, making it easier to sub out with an
|
|
45
|
+
* JavaScript object lieral when you don't have a `PointerEvent` handy.
|
|
46
|
+
*/
|
|
47
|
+
export interface PointerEventCoordinates {
|
|
48
|
+
clientX: number;
|
|
49
|
+
clientY: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
42
52
|
/**
|
|
43
53
|
* A Web Component that provides a resizable panel layout system.
|
|
44
54
|
* Panels are arranged using CSS Grid and can be resized by dragging dividers.
|
|
@@ -71,6 +81,22 @@ import {
|
|
|
71
81
|
* layout.restore(state);
|
|
72
82
|
* ```
|
|
73
83
|
*
|
|
84
|
+
* @remarks
|
|
85
|
+
*
|
|
86
|
+
* Why does this implementation use a `<slot>` at all? We must use
|
|
87
|
+
* `<slot>` and the Shadow DOM to scope the grid CSS rules to each
|
|
88
|
+
* instance of `<regular-layout>` (without e.g. giving them unique
|
|
89
|
+
* `"id"` and injecting into `document,head`), and we can only select
|
|
90
|
+
* `::slotted` light DOM children from `adoptedStyleSheets` on the
|
|
91
|
+
* `ShadowRoot`.
|
|
92
|
+
*
|
|
93
|
+
* Why does this implementation use a single `<slot>` and the child
|
|
94
|
+
* `"name"` attribute, as opposed to a named `<slot name="my_slot">`
|
|
95
|
+
* and the built-in `"slot"` child attribute? Children with a `"slot"`
|
|
96
|
+
* attribute don't fallback to the un-named `<slot>`, so using the
|
|
97
|
+
* latter implementation would require synchronizing the light DOM
|
|
98
|
+
* and shadow DOM slots/slotted children continuously.
|
|
99
|
+
*
|
|
74
100
|
*/
|
|
75
101
|
export class RegularLayout extends HTMLElement {
|
|
76
102
|
private _shadowRoot: ShadowRoot;
|
|
@@ -80,21 +106,12 @@ export class RegularLayout extends HTMLElement {
|
|
|
80
106
|
private _drag_target?: [LayoutDivider, number, number];
|
|
81
107
|
private _cursor_override: boolean;
|
|
82
108
|
private _dimensions?: { box: DOMRect; style: CSSStyleDeclaration };
|
|
109
|
+
private _physics: Physics;
|
|
83
110
|
|
|
84
111
|
constructor() {
|
|
85
112
|
super();
|
|
113
|
+
this._physics = DEFAULT_PHYSICS;
|
|
86
114
|
this._panel = structuredClone(EMPTY_PANEL);
|
|
87
|
-
|
|
88
|
-
// Why does this implementation use a `<slot>` at all? We must use
|
|
89
|
-
// `<slot>` and the Shadow DOM to scope the grid CSS rules to each
|
|
90
|
-
// instance of `<regular-layout>` (without e.g. giving them unique
|
|
91
|
-
// `"id"` and injecting into `document,head`), and we can only select
|
|
92
|
-
// `::slotted` light DOM children from `adoptedStyleSheets` on the
|
|
93
|
-
// `ShadowRoot`.
|
|
94
|
-
|
|
95
|
-
// In addition, this model uses a single un-named `<slot>` to host all
|
|
96
|
-
// light-DOM children, and the child's `"name"` attribute to identify
|
|
97
|
-
// its position in the `Layout`. Alternatively, using named
|
|
98
115
|
this._shadowRoot = this.attachShadow({ mode: "open" });
|
|
99
116
|
this._shadowRoot.innerHTML = `<slot></slot>`;
|
|
100
117
|
this._stylesheet = new CSSStyleSheet();
|
|
@@ -107,12 +124,14 @@ export class RegularLayout extends HTMLElement {
|
|
|
107
124
|
}
|
|
108
125
|
|
|
109
126
|
connectedCallback() {
|
|
127
|
+
this.addEventListener("dblclick", this.onDblClick);
|
|
110
128
|
this.addEventListener("pointerdown", this.onPointerDown);
|
|
111
129
|
this.addEventListener("pointerup", this.onPointerUp);
|
|
112
130
|
this.addEventListener("pointermove", this.onPointerMove);
|
|
113
131
|
}
|
|
114
132
|
|
|
115
133
|
disconnectedCallback() {
|
|
134
|
+
this.removeEventListener("dblclick", this.onDblClick);
|
|
116
135
|
this.removeEventListener("pointerdown", this.onPointerDown);
|
|
117
136
|
this.removeEventListener("pointerup", this.onPointerUp);
|
|
118
137
|
this.removeEventListener("pointermove", this.onPointerMove);
|
|
@@ -121,36 +140,23 @@ export class RegularLayout extends HTMLElement {
|
|
|
121
140
|
/**
|
|
122
141
|
* Determines which panel is at a given screen coordinate.
|
|
123
142
|
*
|
|
124
|
-
* @param
|
|
125
|
-
*
|
|
143
|
+
* @param coordinates - `PointerEvent`, `MouseEvent`, or just X and Y
|
|
144
|
+
* coordinates in screen pixels.
|
|
126
145
|
* @returns Panel information if a panel is at that position, null otherwise.
|
|
127
146
|
*/
|
|
128
147
|
calculateIntersect = (
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
const [col, row, box] = this.relativeCoordinates(x, y, false);
|
|
134
|
-
const panel = calculate_intersection(
|
|
135
|
-
col,
|
|
136
|
-
row,
|
|
137
|
-
this._panel,
|
|
138
|
-
check_dividers ? box : null,
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
if (panel?.type === "layout-path") {
|
|
142
|
-
return { ...panel, layout: this.save() };
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return null;
|
|
148
|
+
coordinates: PointerEventCoordinates,
|
|
149
|
+
): LayoutPath | null => {
|
|
150
|
+
const [col, row, _] = this.relativeCoordinates(coordinates, false);
|
|
151
|
+
return calculate_intersection(col, row, this._panel);
|
|
146
152
|
};
|
|
147
153
|
|
|
148
154
|
/**
|
|
149
155
|
* Sets the visual overlay state during drag-and-drop operations.
|
|
150
156
|
* Displays a preview of where a panel would be placed at the given coordinates.
|
|
151
157
|
*
|
|
152
|
-
* @param
|
|
153
|
-
*
|
|
158
|
+
* @param event - `PointerEvent`, `MouseEvent`, or just X and Y
|
|
159
|
+
* coordinates in screen pixels.
|
|
154
160
|
* @param dragTarget - A `LayoutPath` (presumably from `calculateIntersect`)
|
|
155
161
|
* which points to the drag element in the current layout.
|
|
156
162
|
* @param className - The CSS class name to use for the overlay panel
|
|
@@ -160,43 +166,60 @@ export class RegularLayout extends HTMLElement {
|
|
|
160
166
|
* "absolute".
|
|
161
167
|
*/
|
|
162
168
|
setOverlayState = (
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
mode: OverlayMode = OVERLAY_DEFAULT,
|
|
169
|
+
event: PointerEventCoordinates,
|
|
170
|
+
{ slot }: LayoutPath,
|
|
171
|
+
className: string = this._physics.OVERLAY_CLASSNAME,
|
|
172
|
+
mode: OverlayMode = this._physics.OVERLAY_DEFAULT,
|
|
168
173
|
) => {
|
|
169
174
|
const panel = remove_child(this._panel, slot);
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
175
|
+
const query = `:scope > [${this._physics.CHILD_ATTRIBUTE_NAME}="${slot}"]`;
|
|
176
|
+
const drag_element = this.querySelector(query);
|
|
177
|
+
if (drag_element) {
|
|
178
|
+
drag_element.classList.add(className);
|
|
179
|
+
}
|
|
173
180
|
|
|
174
|
-
|
|
181
|
+
// TODO: Don't recalculate box (but this currently protects against resize).
|
|
182
|
+
const [col, row, box, style] = this.relativeCoordinates(event, true);
|
|
175
183
|
let drop_target = calculate_intersection(col, row, panel);
|
|
176
184
|
if (drop_target) {
|
|
177
|
-
drop_target = calculate_edge(
|
|
185
|
+
drop_target = calculate_edge(
|
|
186
|
+
col,
|
|
187
|
+
row,
|
|
188
|
+
panel,
|
|
189
|
+
slot,
|
|
190
|
+
drop_target,
|
|
191
|
+
box,
|
|
192
|
+
this._physics,
|
|
193
|
+
);
|
|
178
194
|
}
|
|
179
195
|
|
|
180
196
|
if (mode === "grid" && drop_target) {
|
|
181
197
|
const path: [string, string] = [slot, drop_target?.slot];
|
|
182
|
-
const css = create_css_grid_layout(panel,
|
|
198
|
+
const css = create_css_grid_layout(panel, path, this._physics);
|
|
183
199
|
this._stylesheet.replaceSync(css);
|
|
184
200
|
} else if (mode === "absolute") {
|
|
185
|
-
const grid_css = create_css_grid_layout(panel);
|
|
186
|
-
const overlay_css = updateOverlaySheet(
|
|
201
|
+
const grid_css = create_css_grid_layout(panel, undefined, this._physics);
|
|
202
|
+
const overlay_css = updateOverlaySheet(
|
|
203
|
+
slot,
|
|
204
|
+
box,
|
|
205
|
+
style,
|
|
206
|
+
drop_target,
|
|
207
|
+
this._physics,
|
|
208
|
+
);
|
|
209
|
+
|
|
187
210
|
this._stylesheet.replaceSync([grid_css, overlay_css].join("\n"));
|
|
188
211
|
}
|
|
189
212
|
|
|
190
|
-
const event_name = `${CUSTOM_EVENT_NAME_PREFIX}-before-update`;
|
|
191
|
-
const
|
|
192
|
-
this.dispatchEvent(
|
|
213
|
+
const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-before-update`;
|
|
214
|
+
const custom_event = new CustomEvent<Layout>(event_name, { detail: panel });
|
|
215
|
+
this.dispatchEvent(custom_event);
|
|
193
216
|
};
|
|
194
217
|
|
|
195
218
|
/**
|
|
196
219
|
* Clears the overlay state and commits the panel placement.
|
|
197
220
|
*
|
|
198
|
-
* @param
|
|
199
|
-
*
|
|
221
|
+
* @param event - `PointerEvent`, `MouseEvent`, or just X and Y
|
|
222
|
+
* coordinates in screen pixels.
|
|
200
223
|
* @param dragTarget - A `LayoutPath` (presumably from `calculateIntersect`)
|
|
201
224
|
* which points to the drag element in the current layout.
|
|
202
225
|
* @param className - The CSS class name to use for the overlay panel
|
|
@@ -205,41 +228,53 @@ export class RegularLayout extends HTMLElement {
|
|
|
205
228
|
* passed to `setOverlayState`. Defaults to "absolute".
|
|
206
229
|
*/
|
|
207
230
|
clearOverlayState = (
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
className: string = OVERLAY_CLASSNAME,
|
|
231
|
+
event: PointerEventCoordinates | null,
|
|
232
|
+
{ slot, layout }: LayoutPath,
|
|
233
|
+
className: string = this._physics.OVERLAY_CLASSNAME,
|
|
212
234
|
) => {
|
|
213
235
|
let panel = this._panel;
|
|
214
|
-
panel = remove_child(panel,
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
236
|
+
panel = remove_child(panel, slot);
|
|
237
|
+
const query = `:scope > [${this._physics.CHILD_ATTRIBUTE_NAME}="${slot}"]`;
|
|
238
|
+
const drag_element = this.querySelector(query);
|
|
239
|
+
if (drag_element) {
|
|
240
|
+
drag_element.classList.remove(className);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (event === null) {
|
|
244
|
+
this.restore(layout);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
218
247
|
|
|
219
|
-
const [col, row, box] = this.relativeCoordinates(
|
|
248
|
+
const [col, row, box] = this.relativeCoordinates(event, false);
|
|
220
249
|
let drop_target = calculate_intersection(col, row, panel);
|
|
221
250
|
if (drop_target) {
|
|
222
251
|
drop_target = calculate_edge(
|
|
223
252
|
col,
|
|
224
253
|
row,
|
|
225
254
|
panel,
|
|
226
|
-
|
|
255
|
+
slot,
|
|
227
256
|
drop_target,
|
|
228
257
|
box,
|
|
258
|
+
this._physics,
|
|
229
259
|
);
|
|
230
260
|
}
|
|
231
261
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
262
|
+
if (drop_target) {
|
|
263
|
+
const orientation = drop_target?.is_edge
|
|
264
|
+
? drop_target.orientation
|
|
265
|
+
: undefined;
|
|
266
|
+
|
|
267
|
+
const new_layout = insert_child(
|
|
268
|
+
panel,
|
|
269
|
+
slot,
|
|
270
|
+
drop_target.path,
|
|
271
|
+
orientation,
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
this.restore(new_layout);
|
|
275
|
+
} else {
|
|
276
|
+
this.restore(layout);
|
|
277
|
+
}
|
|
243
278
|
};
|
|
244
279
|
|
|
245
280
|
/**
|
|
@@ -286,9 +321,10 @@ export class RegularLayout extends HTMLElement {
|
|
|
286
321
|
*/
|
|
287
322
|
getPanel = (name: string, layout: Layout = this._panel): TabLayout | null => {
|
|
288
323
|
if (layout.type === "child-panel") {
|
|
289
|
-
if (layout.
|
|
324
|
+
if (layout.tabs.includes(name)) {
|
|
290
325
|
return layout;
|
|
291
326
|
}
|
|
327
|
+
|
|
292
328
|
return null;
|
|
293
329
|
}
|
|
294
330
|
|
|
@@ -323,9 +359,9 @@ export class RegularLayout extends HTMLElement {
|
|
|
323
359
|
*/
|
|
324
360
|
restore = (layout: Layout, _is_flattened: boolean = false) => {
|
|
325
361
|
this._panel = !_is_flattened ? flatten(layout) : layout;
|
|
326
|
-
const css = create_css_grid_layout(this._panel);
|
|
362
|
+
const css = create_css_grid_layout(this._panel, undefined, this._physics);
|
|
327
363
|
this._stylesheet.replaceSync(css);
|
|
328
|
-
const event_name = `${CUSTOM_EVENT_NAME_PREFIX}-update`;
|
|
364
|
+
const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-update`;
|
|
329
365
|
const event = new CustomEvent<Layout>(event_name, { detail: this._panel });
|
|
330
366
|
this.dispatchEvent(event);
|
|
331
367
|
};
|
|
@@ -346,22 +382,42 @@ export class RegularLayout extends HTMLElement {
|
|
|
346
382
|
return structuredClone(this._panel);
|
|
347
383
|
};
|
|
348
384
|
|
|
385
|
+
/**
|
|
386
|
+
* Override this instance's global constants.
|
|
387
|
+
*
|
|
388
|
+
* @param physics
|
|
389
|
+
*/
|
|
390
|
+
restorePhysics(physics: PhysicsUpdate) {
|
|
391
|
+
this._physics = Object.freeze({
|
|
392
|
+
...this._physics,
|
|
393
|
+
...physics,
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Get this instance's constants.
|
|
399
|
+
*
|
|
400
|
+
* @returns The current constants
|
|
401
|
+
*/
|
|
402
|
+
savePhysics(): Physics {
|
|
403
|
+
return this._physics;
|
|
404
|
+
}
|
|
405
|
+
|
|
349
406
|
/**
|
|
350
407
|
* Converts screen coordinates to relative layout coordinates.
|
|
351
408
|
*
|
|
352
409
|
* Transforms absolute pixel positions into normalized coordinates (0-1 range)
|
|
353
410
|
* relative to the layout's bounding box.
|
|
354
411
|
*
|
|
355
|
-
* @param
|
|
356
|
-
*
|
|
412
|
+
* @param coordinates - `PointerEvent`, `MouseEvent`, or just X and Y
|
|
413
|
+
* coordinates in screen pixels.
|
|
357
414
|
* @returns A tuple containing:
|
|
358
415
|
* - col: Normalized X coordinate (0 = left edge, 1 = right edge)
|
|
359
416
|
* - row: Normalized Y coordinate (0 = top edge, 1 = bottom edge)
|
|
360
417
|
* - box: The layout element's bounding rectangle
|
|
361
418
|
*/
|
|
362
419
|
relativeCoordinates = (
|
|
363
|
-
|
|
364
|
-
clientY: number,
|
|
420
|
+
event: PointerEventCoordinates,
|
|
365
421
|
recalculate_bounds: boolean = true,
|
|
366
422
|
): [number, number, DOMRect, CSSStyleDeclaration] => {
|
|
367
423
|
if (recalculate_bounds || !this._dimensions) {
|
|
@@ -374,12 +430,13 @@ export class RegularLayout extends HTMLElement {
|
|
|
374
430
|
const box = this._dimensions.box;
|
|
375
431
|
const style = this._dimensions.style;
|
|
376
432
|
const col =
|
|
377
|
-
(clientX - box.left - parseFloat(style.paddingLeft)) /
|
|
433
|
+
(event.clientX - box.left - parseFloat(style.paddingLeft)) /
|
|
378
434
|
(box.width -
|
|
379
435
|
parseFloat(style.paddingLeft) -
|
|
380
436
|
parseFloat(style.paddingRight));
|
|
437
|
+
|
|
381
438
|
const row =
|
|
382
|
-
(clientY - box.top - parseFloat(style.paddingTop)) /
|
|
439
|
+
(event.clientY - box.top - parseFloat(style.paddingTop)) /
|
|
383
440
|
(box.height -
|
|
384
441
|
parseFloat(style.paddingTop) -
|
|
385
442
|
parseFloat(style.paddingBottom));
|
|
@@ -387,14 +444,49 @@ export class RegularLayout extends HTMLElement {
|
|
|
387
444
|
return [col, row, box, style];
|
|
388
445
|
};
|
|
389
446
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
447
|
+
/**
|
|
448
|
+
* Calculates the Euclidean distance in pixels between the current pointer
|
|
449
|
+
* coordinates and a drag target's position within the layout.
|
|
450
|
+
*
|
|
451
|
+
* @param coordinates - The current pointer event coordinates.
|
|
452
|
+
* @param drag_target - The layout path representing the drag target
|
|
453
|
+
* position.
|
|
454
|
+
* @returns The distance in pixels between the coordinates and the drag
|
|
455
|
+
* target.
|
|
456
|
+
*/
|
|
457
|
+
diffCoordinates = (
|
|
458
|
+
event: PointerEventCoordinates,
|
|
459
|
+
drag_target: LayoutPath,
|
|
460
|
+
): number => {
|
|
461
|
+
const [column, row, box] = this.relativeCoordinates(event, false);
|
|
462
|
+
const dx = (column - drag_target.column) * box.width;
|
|
463
|
+
const dy = (row - drag_target.row) * box.height;
|
|
464
|
+
return Math.sqrt(dx ** 2 + dy ** 2);
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
private onDblClick = (event: MouseEvent) => {
|
|
468
|
+
const [col, row, rect] = this.relativeCoordinates(event, false);
|
|
469
|
+
const divider = calculate_intersection(col, row, this._panel, {
|
|
470
|
+
rect,
|
|
471
|
+
size: this._physics.GRID_DIVIDER_SIZE,
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
if (divider?.type === "horizontal" || divider?.type === "vertical") {
|
|
475
|
+
const panel = redistribute_panel_sizes(
|
|
476
|
+
this._panel,
|
|
477
|
+
divider.path,
|
|
478
|
+
undefined,
|
|
395
479
|
);
|
|
396
480
|
|
|
397
|
-
|
|
481
|
+
this.restore(panel, true);
|
|
482
|
+
}
|
|
483
|
+
};
|
|
484
|
+
|
|
485
|
+
private onPointerDown = (event: PointerEvent) => {
|
|
486
|
+
if (!this._physics.GRID_DIVIDER_CHECK_TARGET || event.target === this) {
|
|
487
|
+
const [col, row, rect] = this.relativeCoordinates(event);
|
|
488
|
+
const size = this._physics.GRID_DIVIDER_SIZE;
|
|
489
|
+
const hit = calculate_intersection(col, row, this._panel, { rect, size });
|
|
398
490
|
if (hit && hit.type !== "layout-path") {
|
|
399
491
|
this._drag_target = [hit, col, row];
|
|
400
492
|
this.setPointerCapture(event.pointerId);
|
|
@@ -405,31 +497,36 @@ export class RegularLayout extends HTMLElement {
|
|
|
405
497
|
|
|
406
498
|
private onPointerMove = (event: PointerEvent) => {
|
|
407
499
|
if (this._drag_target) {
|
|
408
|
-
const [col, row] = this.relativeCoordinates(
|
|
409
|
-
event.clientX,
|
|
410
|
-
event.clientY,
|
|
411
|
-
false,
|
|
412
|
-
);
|
|
413
|
-
|
|
500
|
+
const [col, row] = this.relativeCoordinates(event, false);
|
|
414
501
|
const [{ path, type }, old_col, old_row] = this._drag_target;
|
|
415
502
|
const offset = type === "horizontal" ? old_col - col : old_row - row;
|
|
416
503
|
const panel = redistribute_panel_sizes(this._panel, path, offset);
|
|
417
|
-
this._stylesheet.replaceSync(
|
|
418
|
-
|
|
419
|
-
const [col, row, box] = this.relativeCoordinates(
|
|
420
|
-
event.clientX,
|
|
421
|
-
event.clientY,
|
|
422
|
-
false,
|
|
504
|
+
this._stylesheet.replaceSync(
|
|
505
|
+
create_css_grid_layout(panel, undefined, this._physics),
|
|
423
506
|
);
|
|
507
|
+
}
|
|
424
508
|
|
|
425
|
-
|
|
426
|
-
if (
|
|
427
|
-
this.
|
|
428
|
-
this.
|
|
429
|
-
} else if (divider?.type === "horizontal") {
|
|
430
|
-
this._cursor_stylesheet.replaceSync(":host{cursor:col-resize");
|
|
431
|
-
this._cursor_override = true;
|
|
509
|
+
if (this._physics.GRID_DIVIDER_CHECK_TARGET && event.target !== this) {
|
|
510
|
+
if (this._cursor_override) {
|
|
511
|
+
this._cursor_override = false;
|
|
512
|
+
this._cursor_stylesheet.replaceSync("");
|
|
432
513
|
}
|
|
514
|
+
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
const [col, row, rect] = this.relativeCoordinates(event, false);
|
|
519
|
+
const divider = calculate_intersection(col, row, this._panel, {
|
|
520
|
+
rect,
|
|
521
|
+
size: this._physics.GRID_DIVIDER_SIZE,
|
|
522
|
+
});
|
|
523
|
+
|
|
524
|
+
if (divider?.type === "vertical") {
|
|
525
|
+
this._cursor_stylesheet.replaceSync(":host{cursor:row-resize");
|
|
526
|
+
this._cursor_override = true;
|
|
527
|
+
} else if (divider?.type === "horizontal") {
|
|
528
|
+
this._cursor_stylesheet.replaceSync(":host{cursor:col-resize");
|
|
529
|
+
this._cursor_override = true;
|
|
433
530
|
} else if (this._cursor_override) {
|
|
434
531
|
this._cursor_override = false;
|
|
435
532
|
this._cursor_stylesheet.replaceSync("");
|
|
@@ -439,12 +536,7 @@ export class RegularLayout extends HTMLElement {
|
|
|
439
536
|
private onPointerUp = (event: PointerEvent) => {
|
|
440
537
|
if (this._drag_target) {
|
|
441
538
|
this.releasePointerCapture(event.pointerId);
|
|
442
|
-
const [col, row] = this.relativeCoordinates(
|
|
443
|
-
event.clientX,
|
|
444
|
-
event.clientY,
|
|
445
|
-
false,
|
|
446
|
-
);
|
|
447
|
-
|
|
539
|
+
const [col, row] = this.relativeCoordinates(event, false);
|
|
448
540
|
const [{ path, type }, old_col, old_row] = this._drag_target;
|
|
449
541
|
const offset = type === "horizontal" ? old_col - col : old_row - row;
|
|
450
542
|
const panel = redistribute_panel_sizes(this._panel, path, offset);
|
package/themes/lorax.css
CHANGED
|
@@ -18,7 +18,7 @@ regular-layout.lorax {
|
|
|
18
18
|
regular-layout.lorax regular-layout-frame {
|
|
19
19
|
margin: 3px;
|
|
20
20
|
margin-top: 27px;
|
|
21
|
-
border-radius: 0
|
|
21
|
+
border-radius: 0 6px 6px 6px;
|
|
22
22
|
border: 1px solid #666;
|
|
23
23
|
box-shadow: 0px 6px 6px -4px rgba(150, 150, 180);
|
|
24
24
|
}
|
|
@@ -30,6 +30,7 @@ regular-layout.lorax regular-layout-frame::part(titlebar) {
|
|
|
30
30
|
margin-right: -1px;
|
|
31
31
|
margin-bottom: 0px;
|
|
32
32
|
margin-top: -24px;
|
|
33
|
+
padding-right: 6px;
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
regular-layout.lorax regular-layout-frame::part(tab) {
|