regular-layout 0.3.0 → 0.4.0

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.
Files changed (47) hide show
  1. package/README.md +110 -22
  2. package/dist/{layout → core}/types.d.ts +6 -0
  3. package/dist/extensions.d.ts +6 -1
  4. package/dist/index.d.ts +2 -1
  5. package/dist/index.js +7 -7
  6. package/dist/index.js.map +4 -4
  7. package/dist/layout/calculate_edge.d.ts +2 -2
  8. package/dist/layout/calculate_intersect.d.ts +1 -1
  9. package/dist/layout/calculate_path.d.ts +1 -1
  10. package/dist/layout/calculate_presize_paths.d.ts +10 -0
  11. package/dist/layout/flatten.d.ts +1 -1
  12. package/dist/layout/generate_grid.d.ts +2 -2
  13. package/dist/layout/generate_overlay.d.ts +18 -2
  14. package/dist/layout/insert_child.d.ts +1 -1
  15. package/dist/layout/redistribute_panel_sizes.d.ts +2 -2
  16. package/dist/layout/remove_child.d.ts +1 -1
  17. package/dist/model/overlay_controller.d.ts +34 -0
  18. package/dist/model/presize_queue.d.ts +17 -0
  19. package/dist/regular-layout-tab.d.ts +1 -1
  20. package/dist/regular-layout.d.ts +37 -9
  21. package/package.json +5 -4
  22. package/src/{layout → core}/constants.ts +2 -2
  23. package/src/{layout → core}/types.ts +7 -0
  24. package/src/extensions.ts +13 -1
  25. package/src/index.ts +3 -1
  26. package/src/layout/calculate_edge.ts +2 -2
  27. package/src/layout/calculate_intersect.ts +5 -2
  28. package/src/layout/calculate_path.ts +1 -1
  29. package/src/layout/calculate_presize_paths.ts +93 -0
  30. package/src/layout/flatten.ts +1 -1
  31. package/src/layout/generate_grid.ts +2 -2
  32. package/src/layout/generate_overlay.ts +48 -16
  33. package/src/layout/insert_child.ts +1 -1
  34. package/src/layout/redistribute_panel_sizes.ts +2 -2
  35. package/src/layout/remove_child.ts +2 -2
  36. package/src/model/overlay_controller.ts +162 -0
  37. package/src/model/presize_queue.ts +79 -0
  38. package/src/regular-layout-frame.ts +2 -2
  39. package/src/regular-layout-tab.ts +1 -1
  40. package/src/regular-layout.ts +166 -131
  41. package/themes/borland.css +103 -0
  42. package/themes/chicago.css +55 -49
  43. package/themes/fluxbox.css +64 -60
  44. package/themes/gibson.css +174 -164
  45. package/themes/hotdog.css +53 -47
  46. package/themes/lorax.css +82 -75
  47. /package/dist/{layout → core}/constants.d.ts +0 -0
@@ -16,7 +16,7 @@
16
16
  * @packageDocumentation
17
17
  */
18
18
 
19
- import { EMPTY_PANEL } from "./layout/types.ts";
19
+ import { EMPTY_PANEL } from "./core/types.ts";
20
20
  import { create_css_grid_layout } from "./layout/generate_grid.ts";
21
21
  import type {
22
22
  LayoutPath,
@@ -26,20 +26,27 @@ import type {
26
26
  OverlayMode,
27
27
  Orientation,
28
28
  LayoutPathTraversal,
29
- } from "./layout/types.ts";
29
+ ViewWindow,
30
+ } from "./core/types.ts";
31
+
30
32
  import { calculate_intersection } from "./layout/calculate_intersect.ts";
31
33
  import { remove_child } from "./layout/remove_child.ts";
32
34
  import { insert_child } from "./layout/insert_child.ts";
33
35
  import { redistribute_panel_sizes } from "./layout/redistribute_panel_sizes.ts";
34
- import { updateOverlaySheet } from "./layout/generate_overlay.ts";
35
- import { calculate_edge } from "./layout/calculate_edge.ts";
36
+ import { viewWindowToLocalRect } from "./layout/generate_overlay.ts";
36
37
  import { flatten } from "./layout/flatten.ts";
37
38
  import { calculate_path } from "./layout/calculate_path.ts";
39
+ import { PresizeQueue } from "./model/presize_queue.ts";
40
+ import {
41
+ OverlayController,
42
+ type OverlayHost,
43
+ } from "./model/overlay_controller.ts";
44
+
38
45
  import {
39
46
  DEFAULT_PHYSICS,
40
47
  type PhysicsUpdate,
41
48
  type Physics,
42
- } from "./layout/constants.ts";
49
+ } from "./core/constants.ts";
43
50
 
44
51
  /**
45
52
  * An interface which models the fields of `PointerEvent` that
@@ -109,6 +116,8 @@ export class RegularLayout extends HTMLElement {
109
116
  private _cursor_override: boolean;
110
117
  private _dimensions?: { box: DOMRect; style: CSSStyleDeclaration };
111
118
  private _physics: Physics;
119
+ private _presizeQueue: PresizeQueue;
120
+ private _overlayController: OverlayController;
112
121
 
113
122
  constructor() {
114
123
  super();
@@ -119,6 +128,9 @@ export class RegularLayout extends HTMLElement {
119
128
  this._stylesheet = new CSSStyleSheet();
120
129
  this._cursor_stylesheet = new CSSStyleSheet();
121
130
  this._cursor_override = false;
131
+ const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-before-resize`;
132
+ this._presizeQueue = new PresizeQueue(this, event_name);
133
+ this._overlayController = new OverlayController(this.create_overlay_host());
122
134
  this._shadowRoot.adoptedStyleSheets = [
123
135
  this._stylesheet,
124
136
  this._cursor_stylesheet,
@@ -177,54 +189,13 @@ export class RegularLayout extends HTMLElement {
177
189
  * the target, "absolute" positions the panel absolutely. Defaults to
178
190
  * "absolute".
179
191
  */
180
- setOverlayState = (
192
+ setOverlayState = async (
181
193
  event: PointerEventCoordinates,
182
- { slot }: LayoutPath,
183
- className: string = this._physics.OVERLAY_CLASSNAME,
184
- mode: OverlayMode = this._physics.OVERLAY_DEFAULT,
194
+ target: LayoutPath,
195
+ className?: string,
196
+ mode?: OverlayMode,
185
197
  ) => {
186
- const panel = remove_child(this._panel, slot);
187
- const query = `:scope > [${this._physics.CHILD_ATTRIBUTE_NAME}="${slot}"]`;
188
- const drag_element = this.querySelector(query);
189
- if (drag_element) {
190
- drag_element.classList.add(className);
191
- }
192
-
193
- // TODO: Don't recalculate box (but this currently protects against resize).
194
- const [col, row, box, style] = this.relativeCoordinates(event, true);
195
- let drop_target = calculate_intersection(col, row, panel);
196
- if (drop_target) {
197
- drop_target = calculate_edge(
198
- col,
199
- row,
200
- panel,
201
- slot,
202
- drop_target,
203
- box,
204
- this._physics,
205
- );
206
- }
207
-
208
- if (mode === "grid" && drop_target) {
209
- const path: [string, string] = [slot, drop_target?.slot];
210
- const css = create_css_grid_layout(panel, path, this._physics);
211
- this._stylesheet.replaceSync(css);
212
- } else if (mode === "absolute") {
213
- const grid_css = create_css_grid_layout(panel, undefined, this._physics);
214
- const overlay_css = updateOverlaySheet(
215
- slot,
216
- box,
217
- style,
218
- drop_target,
219
- this._physics,
220
- );
221
-
222
- this._stylesheet.replaceSync([grid_css, overlay_css].join("\n"));
223
- }
224
-
225
- const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-before-update`;
226
- const custom_event = new CustomEvent<Layout>(event_name, { detail: panel });
227
- this.dispatchEvent(custom_event);
198
+ await this._overlayController.set(event, target, className, mode);
228
199
  };
229
200
 
230
201
  /**
@@ -239,54 +210,12 @@ export class RegularLayout extends HTMLElement {
239
210
  * @param mode - Overlay rendering mode that was used, must match the mode
240
211
  * passed to `setOverlayState`. Defaults to "absolute".
241
212
  */
242
- clearOverlayState = (
213
+ clearOverlayState = async (
243
214
  event: PointerEventCoordinates | null,
244
- { slot, layout }: LayoutPath,
245
- className: string = this._physics.OVERLAY_CLASSNAME,
215
+ target: LayoutPath,
216
+ className?: string,
246
217
  ) => {
247
- let panel = this._panel;
248
- panel = remove_child(panel, slot);
249
- const query = `:scope > [${this._physics.CHILD_ATTRIBUTE_NAME}="${slot}"]`;
250
- const drag_element = this.querySelector(query);
251
- if (drag_element) {
252
- drag_element.classList.remove(className);
253
- }
254
-
255
- if (event === null) {
256
- this.restore(layout);
257
- return;
258
- }
259
-
260
- const [col, row, box] = this.relativeCoordinates(event, false);
261
- let drop_target = calculate_intersection(col, row, panel);
262
- if (drop_target) {
263
- drop_target = calculate_edge(
264
- col,
265
- row,
266
- panel,
267
- slot,
268
- drop_target,
269
- box,
270
- this._physics,
271
- );
272
- }
273
-
274
- if (drop_target) {
275
- const orientation = drop_target?.is_edge
276
- ? drop_target.orientation
277
- : undefined;
278
-
279
- const new_layout = insert_child(
280
- panel,
281
- slot,
282
- drop_target.path,
283
- orientation,
284
- );
285
-
286
- this.restore(new_layout);
287
- } else {
288
- this.restore(layout);
289
- }
218
+ await this._overlayController.clear(event, target, className);
290
219
  };
291
220
 
292
221
  /**
@@ -300,7 +229,7 @@ export class RegularLayout extends HTMLElement {
300
229
  * the new `SplitPanel` _if_ there is an option of orientation (e.g. if
301
230
  * the layout had no pre-existing `SplitPanel`)
302
231
  */
303
- insertPanel = (
232
+ insertPanel = async (
304
233
  name: string,
305
234
  path: LayoutPathTraversal = [],
306
235
  split?: boolean | Orientation,
@@ -312,7 +241,7 @@ export class RegularLayout extends HTMLElement {
312
241
  orientation = split;
313
242
  }
314
243
 
315
- this.restore(insert_child(this._panel, name, path, orientation));
244
+ await this.restore(insert_child(this._panel, name, path, orientation));
316
245
  };
317
246
 
318
247
  /**
@@ -320,8 +249,8 @@ export class RegularLayout extends HTMLElement {
320
249
  *
321
250
  * @param name - Name of the panel to remove
322
251
  */
323
- removePanel = (name: string) => {
324
- this.restore(remove_child(this._panel, name));
252
+ removePanel = async (name: string) => {
253
+ await this.restore(remove_child(this._panel, name));
325
254
  };
326
255
 
327
256
  /**
@@ -353,29 +282,61 @@ export class RegularLayout extends HTMLElement {
353
282
  /**
354
283
  * Clears the entire layout, unslotting all panels.
355
284
  */
356
- clear = () => {
357
- this.restore(EMPTY_PANEL);
285
+ clear = async () => {
286
+ await this.restore(EMPTY_PANEL);
287
+ };
288
+
289
+ /**
290
+ * Restores the layout from a saved state synchronously, without
291
+ * dispatching the `regular-layout-before-resize` event.
292
+ *
293
+ * @param layout - The layout tree to restore
294
+ */
295
+ restoreSync = (layout: Layout, _is_flattened: boolean = false) => {
296
+ this._panel = !_is_flattened ? flatten(layout) : layout;
297
+ const css = create_css_grid_layout(this._panel, undefined, this._physics);
298
+ this._stylesheet.replaceSync(css);
299
+ const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-update`;
300
+ const event = new CustomEvent<Layout>(event_name, { detail: this._panel });
301
+ this.dispatchEvent(event);
358
302
  };
359
303
 
360
304
  /**
361
305
  * Restores the layout from a saved state.
362
306
  *
307
+ * Before applying, dispatches a cancelable `regular-layout-before-resize`
308
+ * event. If the event is cancelled via `preventDefault()`, the layout
309
+ * update is suspended until {@link resumeResize} is called.
310
+ *
363
311
  * @param layout - The layout tree to restore
364
312
  *
365
313
  * @example
366
314
  * ```typescript
367
315
  * const layout = document.querySelector('regular-layout');
368
316
  * const savedState = JSON.parse(localStorage.getItem('layout'));
369
- * layout.restore(savedState);
317
+ * await layout.restore(savedState);
370
318
  * ```
371
319
  */
372
- restore = (layout: Layout, _is_flattened: boolean = false) => {
373
- this._panel = !_is_flattened ? flatten(layout) : layout;
374
- const css = create_css_grid_layout(this._panel, undefined, this._physics);
375
- this._stylesheet.replaceSync(css);
376
- const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-update`;
377
- const event = new CustomEvent<Layout>(event_name, { detail: this._panel });
378
- this.dispatchEvent(event);
320
+ restore = async (layout: Layout, _is_flattened: boolean = false) => {
321
+ const panel = !_is_flattened ? flatten(layout) : layout;
322
+ await this._presizeQueue.run(panel, () => {
323
+ this._panel = panel;
324
+ const css = create_css_grid_layout(this._panel, undefined, this._physics);
325
+ this._stylesheet.replaceSync(css);
326
+ const event_name = `${this._physics.CUSTOM_EVENT_NAME_PREFIX}-update`;
327
+ const event = new CustomEvent<Layout>(event_name, {
328
+ detail: this._panel,
329
+ });
330
+ this.dispatchEvent(event);
331
+ });
332
+ };
333
+
334
+ /**
335
+ * Resumes a layout update that was suspended by cancelling the
336
+ * `regular-layout-before-resize` event.
337
+ */
338
+ resumeResize = () => {
339
+ this._presizeQueue.resume();
379
340
  };
380
341
 
381
342
  /**
@@ -441,21 +402,53 @@ export class RegularLayout extends HTMLElement {
441
402
 
442
403
  const box = this._dimensions.box;
443
404
  const style = this._dimensions.style;
444
- const col =
445
- (event.clientX - box.left - parseFloat(style.paddingLeft)) /
446
- (box.width -
447
- parseFloat(style.paddingLeft) -
448
- parseFloat(style.paddingRight));
449
-
450
- const row =
451
- (event.clientY - box.top - parseFloat(style.paddingTop)) /
452
- (box.height -
453
- parseFloat(style.paddingTop) -
454
- parseFloat(style.paddingBottom));
455
-
405
+ const paddingLeft = parseFloat(style.paddingLeft);
406
+ const paddingTop = parseFloat(style.paddingTop);
407
+ const contentWidth =
408
+ box.width - paddingLeft - parseFloat(style.paddingRight);
409
+
410
+ const contentHeight =
411
+ box.height - paddingTop - parseFloat(style.paddingBottom);
412
+
413
+ const localX = event.clientX - box.left - paddingLeft;
414
+ const localY = event.clientY - box.top - paddingTop;
415
+ const col = Math.max(0, Math.min(1, localX / contentWidth));
416
+ const row = Math.max(0, Math.min(1, localY / contentHeight));
456
417
  return [col, row, box, style];
457
418
  };
458
419
 
420
+ /**
421
+ * Converts a {@link ViewWindow} (normalized 0–1 coordinates) to a
422
+ * `DOMRect` in screen pixels, accounting for padding and optionally
423
+ * CSS `gap` and child `margin`.
424
+ *
425
+ * @param window - The view window to convert.
426
+ * @returns A `DOMRect` representing the window in screen coordinates.
427
+ */
428
+ realCoordinates = (window: ViewWindow, child?: HTMLElement): DOMRect => {
429
+ if (!this._dimensions) {
430
+ this._dimensions = {
431
+ box: this.getBoundingClientRect(),
432
+ style: getComputedStyle(this),
433
+ };
434
+ }
435
+
436
+ const box = this._dimensions.box;
437
+ const style = this._dimensions.style;
438
+ let childStyle: CSSStyleDeclaration | undefined;
439
+ if (child) {
440
+ childStyle = getComputedStyle(child);
441
+ }
442
+
443
+ const local = viewWindowToLocalRect(window, box, style, childStyle);
444
+ return new DOMRect(
445
+ box.left + local.x,
446
+ box.top + local.y,
447
+ local.width,
448
+ local.height,
449
+ );
450
+ };
451
+
459
452
  /**
460
453
  * Calculates the Euclidean distance in pixels between the current pointer
461
454
  * coordinates and a drag target's position within the layout.
@@ -476,7 +469,47 @@ export class RegularLayout extends HTMLElement {
476
469
  return Math.sqrt(dx ** 2 + dy ** 2);
477
470
  };
478
471
 
479
- private onDblClick = (event: MouseEvent) => {
472
+ // ▇█████████████████■■■■ȺȺȺȺȺ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ȺȺȺȺȺ■■■■■█████████████████
473
+ // ███████▛▀▀█▃▄▄▅▆▆▆▇▇▇██████████████████████████████▇▇▇▆▆▆▅▅▄▃█▀▀▜███████
474
+ // ████▛▚▅▇███▍ ▗▄▃¯"▜██▘ ▜██▍ ▀█▋ ▐█▀▔▂▄▃ ▔▜█ ▗▃▃▃▄▊ ▄▄▃ ▔▜██▇▅▃▀████
475
+ // ███▋╺██████▍ ▐██▋ █▘ ◨Ƚ "██▍ ▙▁ ▀ ▐▋ █▛▀▀▀▜█ ´▂▂Ŋ█▊ °"▔ ▃██████▍▐███
476
+ // ████▄▝▜████▍ ▝▀▀ ▂▟▘ ▄▄▄▄ "█▍ ██▄ ▐█▃ ▝▀▀ ▐█ ▝▀▀▀▀▊ ██▖ ▝████▛▀▄████
477
+ // ██████▇▆▄▃█▀▀Ⱥ▼■███▇▇████▇▇█▇▇████▇████▇▇▇████▇▇▇▇▇▇▇█▇■◘▀▀▀▀▂▃▄▅▇██████
478
+ // ███████████████▇▇▆▆▆▅▅▅▅▅▅▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▅▅▅▅▅▅▆▆▆▇▇███████████████
479
+ //
480
+ //
481
+ // ┏▅▅▖ ▗▅▅▶ ▅▅▅▅▅▅▅ ▗▅▅▅▅▅▅▖ ▅▅▅▅▅▄▄▂ ▃▅▆▆▆▄▁ ┏▅▅▖ ▅▅▖▅▅▅▅▅▅▅▅▅
482
+ // ┣██▌▗██▛ ██▊▔▔▔▔ ▐██▋▔▔▔` ███▍"▜██▙ ▟██▘▔███▖ ▐██▌ ██▌^▔▔███^▔^
483
+ // ┣██▙██▋ ██▊▂▂▂ ▐██▋▂▂▂ ███▍ ▐██▋ ▐███ ▐██▋ ▐██▌ ██▌ ███▎
484
+ // ┣██████▌ ███▀▀▀ ▐███▀▀▘ ██████▛▀ ▐███ ▐██▋ ▐██▌ ██▌ ███▎
485
+ // ┣██▛ ▜██▖ ██▊ ▐██▋ ███▍ ▝███ ▟██▌ ▐██▌ ██▌ ███▎
486
+ // ┣██▌ ███ ███▆▆▆▆▎▐███▆▆▆▅ ███▍ ▀██▙▅██▛ ▝███▅▆██▘ ███▎
487
+ // ▔▔▔` ´▔▔` ▔▔▔▔▔▔▔ ´▔▔▔▔▔▔▔ ▔▔▔ ▔""▔¯ ▔""^▔ ▔▔▔
488
+
489
+ private create_overlay_host(): OverlayHost {
490
+ const self = this;
491
+ return {
492
+ get panel() {
493
+ return self._panel;
494
+ },
495
+ get physics() {
496
+ return self._physics;
497
+ },
498
+ get stylesheet() {
499
+ return self._stylesheet;
500
+ },
501
+ get presizeQueue() {
502
+ return self._presizeQueue;
503
+ },
504
+ relativeCoordinates: (event, recalculate) =>
505
+ self.relativeCoordinates(event, recalculate),
506
+ restore: (layout, isFlattened) => self.restore(layout, isFlattened),
507
+ querySelector: (selectors) => self.querySelector(selectors),
508
+ dispatchEvent: (event) => self.dispatchEvent(event),
509
+ };
510
+ }
511
+
512
+ private onDblClick = async (event: MouseEvent) => {
480
513
  const [col, row, rect] = this.relativeCoordinates(event, false);
481
514
  const divider = calculate_intersection(col, row, this._panel, {
482
515
  rect,
@@ -490,7 +523,7 @@ export class RegularLayout extends HTMLElement {
490
523
  undefined,
491
524
  );
492
525
 
493
- this.restore(panel, true);
526
+ await this.restore(panel, true);
494
527
  }
495
528
  };
496
529
 
@@ -507,15 +540,17 @@ export class RegularLayout extends HTMLElement {
507
540
  }
508
541
  };
509
542
 
510
- private onPointerMove = (event: PointerEvent) => {
543
+ private onPointerMove = async (event: PointerEvent) => {
511
544
  if (this._drag_target) {
512
545
  const [col, row] = this.relativeCoordinates(event, false);
513
546
  const [{ path, type }, old_col, old_row] = this._drag_target;
514
547
  const offset = type === "horizontal" ? old_col - col : old_row - row;
515
548
  const panel = redistribute_panel_sizes(this._panel, path, offset);
516
- this._stylesheet.replaceSync(
517
- create_css_grid_layout(panel, undefined, this._physics),
518
- );
549
+ await this._presizeQueue.run(panel, () => {
550
+ this._stylesheet.replaceSync(
551
+ create_css_grid_layout(panel, undefined, this._physics),
552
+ );
553
+ });
519
554
  }
520
555
 
521
556
  if (this._physics.GRID_DIVIDER_CHECK_TARGET && event.target !== this) {
@@ -545,14 +580,14 @@ export class RegularLayout extends HTMLElement {
545
580
  }
546
581
  };
547
582
 
548
- private onPointerUp = (event: PointerEvent) => {
583
+ private onPointerUp = async (event: PointerEvent) => {
549
584
  if (this._drag_target) {
550
585
  this.releasePointerCapture(event.pointerId);
551
586
  const [col, row] = this.relativeCoordinates(event, false);
552
587
  const [{ path, type }, old_col, old_row] = this._drag_target;
553
588
  const offset = type === "horizontal" ? old_col - col : old_row - row;
554
589
  const panel = redistribute_panel_sizes(this._panel, path, offset);
555
- this.restore(panel, true);
590
+ await this.restore(panel, true);
556
591
  this._drag_target = undefined;
557
592
  }
558
593
  };
@@ -0,0 +1,103 @@
1
+ /* ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
2
+ * ░░░░░░░░▄▀░█▀▄░█▀▀░█▀▀░█░█░█░░░█▀█░█▀▄░░░░░█░░░█▀█░█░█░█▀█░█░█░▀█▀░▀▄░░░░░░░░
3
+ * ░░░░░░░▀▄░░█▀▄░█▀▀░█░█░█░█░█░░░█▀█░█▀▄░▀▀▀░█░░░█▀█░░█░░█░█░█░█░░█░░░▄▀░░░░░░░
4
+ * ░░░░░░░░░▀░▀░▀░▀▀▀░▀▀▀░▀▀▀░▀▀▀░▀░▀░▀░▀░░░░░▀▀▀░▀░▀░░▀░░▀▀▀░▀▀▀░░▀░░▀░░░░░░░░░
5
+ * ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
6
+ * ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
7
+ * ┃ * Copyright (c) 2026, the Regular Layout Authors. This file is part * ┃
8
+ * ┃ * of the Regular Layout library, distributed under the terms of the * ┃
9
+ * ┃ * [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). * ┃
10
+ * ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
11
+ */
12
+
13
+ regular-layout.borland {
14
+ background-color: #0000aa;
15
+ font-family:
16
+ "ui-monospace", "SFMono-Regular", "SF Mono", "Menlo", "Consolas",
17
+ "Liberation Mono", monospace;
18
+ padding: 16px;
19
+ }
20
+
21
+ /* Frame */
22
+ regular-layout.borland regular-layout-frame {
23
+ position: relative;
24
+ box-sizing: border-box;
25
+ margin: 4px;
26
+ background: #0000aa;
27
+ border: 1px solid #00aaaa;
28
+ box-shadow: 1px 1px 0 #000000;
29
+ }
30
+
31
+ regular-layout.borland regular-layout-frame::part(container) {
32
+ padding: 4px 6px;
33
+ color: #ffff55;
34
+ }
35
+
36
+ regular-layout.borland regular-layout-frame::part(close) {
37
+ background: #00aa00;
38
+ height: 16px;
39
+ align-self: center;
40
+ display: flex;
41
+ align-items: center;
42
+ justify-content: center;
43
+ padding: 0 3px;
44
+ }
45
+
46
+ regular-layout.borland regular-layout-frame::part(close):hover {
47
+ background: #00ff00;
48
+ }
49
+
50
+ regular-layout.borland regular-layout-frame::part(close):before {
51
+ content: "[×]";
52
+ font-size: 10px;
53
+ font-weight: bold;
54
+ color: #000000;
55
+ }
56
+
57
+ regular-layout.borland regular-layout-frame::part(titlebar) {
58
+ display: flex;
59
+ align-items: stretch;
60
+ padding-right: 0;
61
+ height: 22px;
62
+ background: #0000aa;
63
+ }
64
+
65
+ regular-layout.borland regular-layout-frame::part(tab) {
66
+ display: flex;
67
+ flex: 1 1 150px;
68
+ align-items: center;
69
+ padding: 0 3px 0 8px;
70
+ cursor: pointer;
71
+ text-overflow: ellipsis;
72
+ background: #0000aa;
73
+ color: #aaaaaa;
74
+ font-size: 11px;
75
+ font-weight: bold;
76
+ border-right: 1px solid #00aaaa;
77
+ }
78
+
79
+ regular-layout.borland regular-layout-frame::part(active-tab) {
80
+ background: #00aaaa;
81
+ color: #000000;
82
+ }
83
+
84
+ regular-layout.borland:has(.overlay) > * {
85
+ opacity: 0.6;
86
+ }
87
+
88
+ regular-layout.borland:has(.overlay) > .overlay {
89
+ opacity: 1;
90
+ }
91
+
92
+ /* Frame in Overlay Mode */
93
+ regular-layout.borland regular-layout-frame.overlay {
94
+ background: rgba(0, 170, 170, 0.9);
95
+ border: 1px solid #ffff55;
96
+ box-shadow: none;
97
+ margin: 0;
98
+ transition:
99
+ top 0.05s linear,
100
+ height 0.05s linear,
101
+ width 0.05s linear,
102
+ left 0.05s linear;
103
+ }
@@ -11,79 +11,85 @@
11
11
  */
12
12
 
13
13
  regular-layout.chicago {
14
- background-color: #008080;
15
- font-family: "ui-monospace", "SFMono-Regular", "SF Mono", "Menlo", "Consolas", "Liberation Mono", monospace;
16
- padding: 24px;
14
+ background-color: #008080;
15
+ font-family:
16
+ "ui-monospace", "SFMono-Regular", "SF Mono", "Menlo", "Consolas",
17
+ "Liberation Mono", monospace;
18
+ padding: 24px;
17
19
  }
18
20
 
19
21
  /* Frame */
20
22
  regular-layout.chicago regular-layout-frame {
21
- position: relative;
22
- box-sizing: border-box;
23
- margin: 12px;
24
- background: #C0C0C0;
25
- border-width: 2px;
26
- border-color: #FFFFFF #808080 #808080 #FFFFFF;
27
- border-style: solid;
23
+ position: relative;
24
+ box-sizing: border-box;
25
+ margin: 12px;
26
+ background: #c0c0c0;
27
+ border-width: 2px;
28
+ border-color: #ffffff #808080 #808080 #ffffff;
29
+ border-style: solid;
30
+ }
31
+
32
+ regular-layout.chicago regular-layout-frame::part(container) {
33
+ padding: 6px;
28
34
  }
29
35
 
30
36
  regular-layout.chicago regular-layout-frame::part(close) {
31
- border-width: 1px;
32
- border-color: #FFFFFF #808080 #808080 #FFFFFF;
33
- border-style: solid;
34
- height: 16px;
35
- background: #C0C0C0;
36
- align-self: center;
37
- display: flex;
38
- align-items: center;
39
- padding: 0px 4px;
37
+ border-width: 1px;
38
+ border-color: #ffffff #808080 #808080 #ffffff;
39
+ border-style: solid;
40
+ height: 16px;
41
+ background: #c0c0c0;
42
+ align-self: center;
43
+ display: flex;
44
+ align-items: center;
45
+ padding: 0px 4px;
40
46
  }
41
47
 
42
48
  regular-layout.chicago regular-layout-frame::part(close):before {
43
- content: "X";
44
- font-size: 10px;
45
- font-weight: bold;
49
+ content: "X";
50
+ font-size: 10px;
51
+ font-weight: bold;
46
52
  }
47
53
 
48
54
  regular-layout.chicago regular-layout-frame::part(titlebar) {
49
- display: flex;
50
- align-items: stretch;
51
- padding-right: 0px;
55
+ display: flex;
56
+ align-items: stretch;
57
+ padding-right: 0px;
52
58
  }
53
59
 
54
60
  regular-layout.chicago regular-layout-frame::part(tab) {
55
- display: flex;
56
- flex: 1 1 150px;
57
- align-items: center;
58
- padding: 0 3px 0 8px;
59
- cursor: pointer;
60
- text-overflow: ellipsis;
61
- background: #808080;
62
- color: #FFF;
63
- font-family: "Tahoma", "Arial", sans-serif;
64
- font-weight: bold;
65
- font-size: 11px;
61
+ display: flex;
62
+ flex: 1 1 150px;
63
+ align-items: center;
64
+ padding: 0 3px 0 8px;
65
+ cursor: pointer;
66
+ text-overflow: ellipsis;
67
+ background: #808080;
68
+ color: #fff;
69
+ font-family: "Tahoma", "Arial", sans-serif;
70
+ font-weight: bold;
71
+ font-size: 11px;
66
72
  }
67
73
 
68
74
  regular-layout.chicago regular-layout-frame::part(active-tab) {
69
- background: #000080;
70
- opacity: 1;
75
+ background: #000080;
76
+ opacity: 1;
71
77
  }
72
78
 
73
- regular-layout.chicago:has(.overlay)>* {
74
- opacity: 0.8;
79
+ regular-layout.chicago:has(.overlay) > * {
80
+ opacity: 0.8;
75
81
  }
76
82
 
77
- regular-layout.chicago:has(.overlay)>.overlay {
78
- opacity: 1;
83
+ regular-layout.chicago:has(.overlay) > .overlay {
84
+ opacity: 1;
79
85
  }
80
86
 
81
87
  /* Frame in Overlay Mode */
82
88
  regular-layout.chicago regular-layout-frame.overlay {
83
- margin: 0;
84
- transition:
85
- top 0.1s ease-in-out,
86
- height 0.1s ease-in-out,
87
- width 0.1s ease-in-out,
88
- left 0.1s ease-in-out;
89
- }
89
+ margin: 0;
90
+ transition:
91
+ top 0.1s ease-in-out,
92
+ height 0.1s ease-in-out,
93
+ width 0.1s ease-in-out,
94
+ left 0.1s ease-in-out;
95
+ }