regular-layout 0.2.1 → 0.3.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.
@@ -2,7 +2,7 @@ import { type Physics } from "./constants";
2
2
  import type { Layout, LayoutPath } from "./types";
3
3
  /**
4
4
  * Calculates an insertion point (which may involve splitting a single
5
- * `"child-panel"` into a new `"split-panel"`), based on the cursor position.
5
+ * `"tab-layout"` into a new `"split-layout"`), based on the cursor position.
6
6
  * *
7
7
  * @param col - The cursor column.
8
8
  * @param row - The cursor row.
@@ -10,7 +10,7 @@ import type { Layout, LayoutPath } from "./types";
10
10
  * @param slot - The slot identifier where the insert should occur
11
11
  * @param drop_target - The `LayoutPath` (from `calculateIntersect`) of the
12
12
  * panel to either insert next to, or split by.
13
- * @returns A new `LayoutPath` reflecting the updated (maybe) `"split-panel"`,
13
+ * @returns A new `LayoutPath` reflecting the updated (maybe) `"split-layout"`,
14
14
  * which is enough to draw the overlay.
15
15
  */
16
16
  export declare function calculate_edge(col: number, row: number, panel: Layout, slot: string, drop_target: LayoutPath, box?: DOMRect, physics?: Physics): LayoutPath;
@@ -0,0 +1,12 @@
1
+ import type { Layout } from "./types.ts";
2
+ /**
3
+ * Calculates the index path for a panel with the given name.
4
+ *
5
+ * Traverses the layout tree to find the named panel and returns the
6
+ * index path describing its position in the tree.
7
+ *
8
+ * @param name - The name of the panel to find.
9
+ * @param layout - The layout tree to search.
10
+ * @returns The panel's index path if found, `null` otherwise.
11
+ */
12
+ export declare function calculate_path(name: string, layout: Layout): number[] | null;
@@ -14,11 +14,11 @@ import type { Layout } from "./types.ts";
14
14
  * @example
15
15
  * ```typescript
16
16
  * const layout = {
17
- * type: "split-panel",
17
+ * type: "split-layout",
18
18
  * orientation: "horizontal",
19
19
  * children: [
20
- * { type: "child-panel", child: "sidebar" },
21
- * { type: "child-panel", child: "main" }
20
+ * { type: "tab-layout", tabs: "sidebar" },
21
+ * { type: "tab-layout", tabs: "main" }
22
22
  * ],
23
23
  * sizes: [0.25, 0.75]
24
24
  * };
@@ -1,2 +1,2 @@
1
1
  import type { LayoutPath } from "./types";
2
- export declare function updateOverlaySheet(slot: string, box: DOMRect, style: CSSStyleDeclaration, drag_target: LayoutPath<undefined> | null, physics?: import("./constants").Physics): string;
2
+ export declare function updateOverlaySheet(slot: string, box: DOMRect, style: CSSStyleDeclaration, drag_target: LayoutPath | null, physics?: import("./constants").Physics): string;
@@ -1,4 +1,4 @@
1
- import type { Layout } from "./types.ts";
1
+ import type { Layout, LayoutPathTraversal } from "./types.ts";
2
2
  /**
3
3
  * Inserts a new child panel into the layout tree at a specified location.
4
4
  * Creates a split panel if necessary and redistributes sizes equally among all
@@ -13,4 +13,4 @@ import type { Layout } from "./types.ts";
13
13
  * @param is_edge - If true, create the split at the parent level.
14
14
  * @returns A new layout tree with the child inserted (original is not mutated).
15
15
  */
16
- export declare function insert_child(panel: Layout, child: string, path: number[], orientation?: "horizontal" | "vertical"): Layout;
16
+ export declare function insert_child(panel: Layout, child: string, path: LayoutPathTraversal, orientation?: "horizontal" | "vertical"): Layout;
@@ -1,4 +1,4 @@
1
- import type { Layout } from "./types.ts";
1
+ import type { Layout, LayoutPathTraversal } from "./types.ts";
2
2
  /**
3
3
  * Adjusts panel sizes during a drag operation on a divider.
4
4
  *
@@ -16,4 +16,4 @@ import type { Layout } from "./types.ts";
16
16
  * @returns A new layout tree with updated sizes (original is not mutated).
17
17
  * ```
18
18
  */
19
- export declare function redistribute_panel_sizes(panel: Layout, path: number[], delta: number, physics?: import("./constants.ts").Physics): Layout;
19
+ export declare function redistribute_panel_sizes(panel: Layout, path: LayoutPathTraversal, delta: number | undefined, physics?: import("./constants.ts").Physics): Layout;
@@ -32,7 +32,7 @@ export interface ViewWindow {
32
32
  * opposite `orientation` as its parent.
33
33
  */
34
34
  export interface SplitLayout {
35
- type: "split-panel";
35
+ type: "split-layout";
36
36
  children: Layout[];
37
37
  sizes: number[];
38
38
  orientation: Orientation;
@@ -41,31 +41,31 @@ export interface SplitLayout {
41
41
  * A leaf panel node that contains a single named child element.
42
42
  */
43
43
  export interface TabLayout {
44
- type: "child-panel";
45
- child: string[];
44
+ type: "tab-layout";
45
+ tabs: string[];
46
46
  selected?: number;
47
47
  }
48
+ /**
49
+ * Represents a panel location relative to a `Layout` struct.
50
+ */
51
+ export type LayoutPathTraversal = number[];
48
52
  /**
49
53
  * Represents a draggable divider between two panels in the layout.
50
54
  *
51
55
  * Used for hit detection.
52
56
  */
53
57
  export interface LayoutDivider {
54
- path: number[];
58
+ path: LayoutPathTraversal;
55
59
  view_window: ViewWindow;
56
60
  type: Orientation;
57
61
  }
58
62
  /**
59
63
  * Represents a panel location result from hit detection.
60
- *
61
- * Contains both the panel identifier and its grid position in relative units.
62
- * The generic parameter `T` allows DOM-only properties (e.g. `DOMRect`) to be
63
- * shared in this cross-platform module.
64
64
  */
65
- export interface LayoutPath<T = undefined> {
65
+ export interface LayoutPath {
66
66
  type: "layout-path";
67
67
  slot: string;
68
- path: number[];
68
+ path: LayoutPathTraversal;
69
69
  view_window: ViewWindow;
70
70
  column: number;
71
71
  row: number;
@@ -73,7 +73,7 @@ export interface LayoutPath<T = undefined> {
73
73
  row_offset: number;
74
74
  orientation: Orientation;
75
75
  is_edge: boolean;
76
- layout: T;
76
+ layout: Layout;
77
77
  }
78
78
  /**
79
79
  * An empty `Layout` with no panels.
@@ -28,15 +28,22 @@ export declare class RegularLayoutFrame extends HTMLElement {
28
28
  private _container_sheet;
29
29
  private _layout;
30
30
  private _header;
31
- private _drag_state;
32
- private _drag_moved;
31
+ private _drag;
33
32
  private _tab_to_index_map;
34
- constructor();
33
+ /**
34
+ * Initializes this elements. Override this method and
35
+ * `disconnectedCallback` to modify how this subclass renders the Shadow
36
+ * DOM and registers events.
37
+ */
35
38
  connectedCallback(): void;
39
+ /**
40
+ * Destroys this element.
41
+ */
36
42
  disconnectedCallback(): void;
37
43
  private onPointerDown;
38
44
  private onPointerMove;
39
45
  private onPointerUp;
46
+ private onPointerCancel;
40
47
  private onPointerLost;
41
48
  private drawTabs;
42
49
  }
@@ -1,5 +1,14 @@
1
- import type { LayoutPath, Layout, TabLayout, OverlayMode, Orientation } from "./layout/types.ts";
1
+ import type { LayoutPath, Layout, TabLayout, OverlayMode, Orientation, LayoutPathTraversal } from "./layout/types.ts";
2
2
  import { type PhysicsUpdate, type Physics } from "./layout/constants.ts";
3
+ /**
4
+ * An interface which models the fields of `PointerEvent` that
5
+ * `<regular-layour>` actually uses, making it easier to sub out with an
6
+ * JavaScript object lieral when you don't have a `PointerEvent` handy.
7
+ */
8
+ export interface PointerEventCoordinates {
9
+ clientX: number;
10
+ clientY: number;
11
+ }
3
12
  /**
4
13
  * A Web Component that provides a resizable panel layout system.
5
14
  * Panels are arranged using CSS Grid and can be resized by dragging dividers.
@@ -32,6 +41,22 @@ import { type PhysicsUpdate, type Physics } from "./layout/constants.ts";
32
41
  * layout.restore(state);
33
42
  * ```
34
43
  *
44
+ * @remarks
45
+ *
46
+ * Why does this implementation use a `<slot>` at all? We must use
47
+ * `<slot>` and the Shadow DOM to scope the grid CSS rules to each
48
+ * instance of `<regular-layout>` (without e.g. giving them unique
49
+ * `"id"` and injecting into `document,head`), and we can only select
50
+ * `::slotted` light DOM children from `adoptedStyleSheets` on the
51
+ * `ShadowRoot`.
52
+ *
53
+ * Why does this implementation use a single `<slot>` and the child
54
+ * `"name"` attribute, as opposed to a named `<slot name="my_slot">`
55
+ * and the built-in `"slot"` child attribute? Children with a `"slot"`
56
+ * attribute don't fallback to the un-named `<slot>`, so using the
57
+ * latter implementation would require synchronizing the light DOM
58
+ * and shadow DOM slots/slotted children continuously.
59
+ *
35
60
  */
36
61
  export declare class RegularLayout extends HTMLElement {
37
62
  private _shadowRoot;
@@ -48,17 +73,24 @@ export declare class RegularLayout extends HTMLElement {
48
73
  /**
49
74
  * Determines which panel is at a given screen coordinate.
50
75
  *
51
- * @param column - X coordinate in screen pixels.
52
- * @param row - Y coordinate in screen pixels.
76
+ * @param coordinates - `PointerEvent`, `MouseEvent`, or just X and Y
77
+ * coordinates in screen pixels.
53
78
  * @returns Panel information if a panel is at that position, null otherwise.
54
79
  */
55
- calculateIntersect: (x: number, y: number, check_dividers?: boolean) => LayoutPath<Layout> | null;
80
+ calculateIntersect: (coordinates: PointerEventCoordinates) => LayoutPath | null;
81
+ /**
82
+ * Calculates the index path for a panel with the given name.
83
+ *
84
+ * @param name - The name of the panel to find.
85
+ * @returns The panel's index path if found, `null` otherwise.
86
+ */
87
+ calculatePath: (name: string) => number[] | null;
56
88
  /**
57
89
  * Sets the visual overlay state during drag-and-drop operations.
58
90
  * Displays a preview of where a panel would be placed at the given coordinates.
59
91
  *
60
- * @param x - X coordinate in screen pixels.
61
- * @param y - Y coordinate in screen pixels.
92
+ * @param event - `PointerEvent`, `MouseEvent`, or just X and Y
93
+ * coordinates in screen pixels.
62
94
  * @param dragTarget - A `LayoutPath` (presumably from `calculateIntersect`)
63
95
  * which points to the drag element in the current layout.
64
96
  * @param className - The CSS class name to use for the overlay panel
@@ -67,12 +99,12 @@ export declare class RegularLayout extends HTMLElement {
67
99
  * the target, "absolute" positions the panel absolutely. Defaults to
68
100
  * "absolute".
69
101
  */
70
- setOverlayState: (x: number, y: number, { slot }: LayoutPath<unknown>, className?: string, mode?: OverlayMode) => void;
102
+ setOverlayState: (event: PointerEventCoordinates, { slot }: LayoutPath, className?: string, mode?: OverlayMode) => void;
71
103
  /**
72
104
  * Clears the overlay state and commits the panel placement.
73
105
  *
74
- * @param x - X coordinate in screen pixels.
75
- * @param y - Y coordinate in screen pixels.
106
+ * @param event - `PointerEvent`, `MouseEvent`, or just X and Y
107
+ * coordinates in screen pixels.
76
108
  * @param dragTarget - A `LayoutPath` (presumably from `calculateIntersect`)
77
109
  * which points to the drag element in the current layout.
78
110
  * @param className - The CSS class name to use for the overlay panel
@@ -80,7 +112,7 @@ export declare class RegularLayout extends HTMLElement {
80
112
  * @param mode - Overlay rendering mode that was used, must match the mode
81
113
  * passed to `setOverlayState`. Defaults to "absolute".
82
114
  */
83
- clearOverlayState: (x: number, y: number, drag_target: LayoutPath<Layout>, className?: string) => void;
115
+ clearOverlayState: (event: PointerEventCoordinates | null, { slot, layout }: LayoutPath, className?: string) => void;
84
116
  /**
85
117
  * Inserts a new panel into the layout at a specified path.
86
118
  *
@@ -92,7 +124,7 @@ export declare class RegularLayout extends HTMLElement {
92
124
  * the new `SplitPanel` _if_ there is an option of orientation (e.g. if
93
125
  * the layout had no pre-existing `SplitPanel`)
94
126
  */
95
- insertPanel: (name: string, path?: number[], split?: boolean | Orientation) => void;
127
+ insertPanel: (name: string, path?: LayoutPathTraversal, split?: boolean | Orientation) => void;
96
128
  /**
97
129
  * Removes a panel from the layout by name.
98
130
  *
@@ -155,14 +187,26 @@ export declare class RegularLayout extends HTMLElement {
155
187
  * Transforms absolute pixel positions into normalized coordinates (0-1 range)
156
188
  * relative to the layout's bounding box.
157
189
  *
158
- * @param clientX - X coordinate in screen pixels (client space).
159
- * @param clientY - Y coordinate in screen pixels (client space).
190
+ * @param coordinates - `PointerEvent`, `MouseEvent`, or just X and Y
191
+ * coordinates in screen pixels.
160
192
  * @returns A tuple containing:
161
193
  * - col: Normalized X coordinate (0 = left edge, 1 = right edge)
162
194
  * - row: Normalized Y coordinate (0 = top edge, 1 = bottom edge)
163
195
  * - box: The layout element's bounding rectangle
164
196
  */
165
- relativeCoordinates: (clientX: number, clientY: number, recalculate_bounds?: boolean) => [number, number, DOMRect, CSSStyleDeclaration];
197
+ relativeCoordinates: (event: PointerEventCoordinates, recalculate_bounds?: boolean) => [number, number, DOMRect, CSSStyleDeclaration];
198
+ /**
199
+ * Calculates the Euclidean distance in pixels between the current pointer
200
+ * coordinates and a drag target's position within the layout.
201
+ *
202
+ * @param coordinates - The current pointer event coordinates.
203
+ * @param drag_target - The layout path representing the drag target
204
+ * position.
205
+ * @returns The distance in pixels between the coordinates and the drag
206
+ * target.
207
+ */
208
+ diffCoordinates: (event: PointerEventCoordinates, drag_target: LayoutPath) => number;
209
+ private onDblClick;
166
210
  private onPointerDown;
167
211
  private onPointerMove;
168
212
  private onPointerUp;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "regular-layout",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "A regular CSS `grid` container",
5
5
  "keywords": [],
6
6
  "license": "Apache-2.0",
@@ -10,6 +10,7 @@
10
10
  },
11
11
  "browser": "dist/index.js",
12
12
  "main": "dist/index.js",
13
+ "types": "dist/index.d.ts",
13
14
  "type": "module",
14
15
  "files": [
15
16
  "dist/**/*",
@@ -20,7 +21,8 @@
20
21
  "build": "tsx build.ts",
21
22
  "build:watch": "tsx build.ts --watch",
22
23
  "clean": "rm -rf dist",
23
- "test": "playwright test",
24
+ "test": "playwright test tests/integration tests/unit",
25
+ "test:perf": "playwright test --workers=1 ./benchmarks",
24
26
  "example": "tsx serve.ts",
25
27
  "deploy": "tsx deploy.ts",
26
28
  "lint": "biome lint src tests",
@@ -11,11 +11,17 @@
11
11
 
12
12
  import { DEFAULT_PHYSICS, type Physics } from "./constants";
13
13
  import { insert_child } from "./insert_child";
14
- import type { Layout, LayoutPath, Orientation, ViewWindow } from "./types";
14
+ import type {
15
+ Layout,
16
+ LayoutPath,
17
+ LayoutPathTraversal,
18
+ Orientation,
19
+ ViewWindow,
20
+ } from "./types";
15
21
 
16
22
  /**
17
23
  * Calculates an insertion point (which may involve splitting a single
18
- * `"child-panel"` into a new `"split-panel"`), based on the cursor position.
24
+ * `"tab-layout"` into a new `"split-layout"`), based on the cursor position.
19
25
  * *
20
26
  * @param col - The cursor column.
21
27
  * @param row - The cursor row.
@@ -23,7 +29,7 @@ import type { Layout, LayoutPath, Orientation, ViewWindow } from "./types";
23
29
  * @param slot - The slot identifier where the insert should occur
24
30
  * @param drop_target - The `LayoutPath` (from `calculateIntersect`) of the
25
31
  * panel to either insert next to, or split by.
26
- * @returns A new `LayoutPath` reflecting the updated (maybe) `"split-panel"`,
32
+ * @returns A new `LayoutPath` reflecting the updated (maybe) `"split-layout"`,
27
33
  * which is enough to draw the overlay.
28
34
  */
29
35
  export function calculate_edge(
@@ -87,7 +93,9 @@ export function calculate_edge(
87
93
  (box?.height || 1) *
88
94
  (drop_target.view_window.row_end - drop_target.view_window.row_start);
89
95
 
90
- const use_column = col_distance * col_scale > row_distance * row_scale;
96
+ const use_column =
97
+ col_scale / 2 - col_distance * col_scale <
98
+ row_scale / 2 - row_distance * row_scale;
91
99
 
92
100
  return insert_axis(
93
101
  panel,
@@ -131,7 +139,7 @@ function insert_root_edge(
131
139
  panel: Layout,
132
140
  slot: string,
133
141
  drop_target: LayoutPath,
134
- path: number[],
142
+ path: LayoutPathTraversal,
135
143
  is_before: boolean,
136
144
  orientation: Orientation,
137
145
  ): LayoutPath {
@@ -151,7 +159,7 @@ function insert_axis(
151
159
  is_before: boolean,
152
160
  axis_orientation: Orientation,
153
161
  ): LayoutPath {
154
- let result_path: number[];
162
+ let result_path: LayoutPathTraversal;
155
163
 
156
164
  if (drop_target.orientation === axis_orientation) {
157
165
  // Same orientation - insert into existing split
@@ -181,7 +189,10 @@ function insert_axis(
181
189
  };
182
190
  }
183
191
 
184
- function calculate_view_window(panel: Layout, path: number[]): ViewWindow {
192
+ function calculate_view_window(
193
+ panel: Layout,
194
+ path: LayoutPathTraversal,
195
+ ): ViewWindow {
185
196
  let view_window: ViewWindow = {
186
197
  row_start: 0,
187
198
  row_end: 1,
@@ -191,7 +202,7 @@ function calculate_view_window(panel: Layout, path: number[]): ViewWindow {
191
202
 
192
203
  let current_panel = panel;
193
204
  for (const step of path) {
194
- if (current_panel.type === "child-panel") {
205
+ if (current_panel.type === "tab-layout") {
195
206
  break;
196
207
  }
197
208
 
@@ -9,7 +9,13 @@
9
9
  // ┃ * [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). * ┃
10
10
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
11
11
 
12
- import type { LayoutPath, LayoutDivider, Layout, ViewWindow } from "./types.ts";
12
+ import type {
13
+ LayoutPath,
14
+ LayoutDivider,
15
+ Layout,
16
+ ViewWindow,
17
+ LayoutPathTraversal,
18
+ } from "./types.ts";
13
19
 
14
20
  const VIEW_WINDOW = {
15
21
  row_start: 0,
@@ -67,21 +73,21 @@ function calculate_intersection_recursive(
67
73
  check_dividers: { rect: DOMRect; size: number } | null,
68
74
  parent_orientation: "horizontal" | "vertical" | null = null,
69
75
  view_window: ViewWindow = structuredClone(VIEW_WINDOW),
70
- path: number[] = [],
76
+ path: LayoutPathTraversal = [],
71
77
  ): LayoutPath | null | LayoutDivider {
72
78
  if (column < 0 || row < 0 || column > 1 || row > 1) {
73
79
  return null;
74
80
  }
75
81
 
76
82
  // Base case: if this is a child panel, return its name
77
- if (panel.type === "child-panel") {
83
+ if (panel.type === "tab-layout") {
78
84
  const selected = panel.selected ?? 0;
79
85
  const col_width = view_window.col_end - view_window.col_start;
80
86
  const row_height = view_window.row_end - view_window.row_start;
81
87
  return {
82
88
  type: "layout-path",
83
- layout: undefined,
84
- slot: panel.child[selected],
89
+ layout: panel,
90
+ slot: panel.tabs[selected],
85
91
  path,
86
92
  view_window,
87
93
  is_edge: false,
@@ -0,0 +1,53 @@
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
+ import type { Layout, LayoutPathTraversal } from "./types.ts";
13
+
14
+ /**
15
+ * Calculates the index path for a panel with the given name.
16
+ *
17
+ * Traverses the layout tree to find the named panel and returns the
18
+ * index path describing its position in the tree.
19
+ *
20
+ * @param name - The name of the panel to find.
21
+ * @param layout - The layout tree to search.
22
+ * @returns The panel's index path if found, `null` otherwise.
23
+ */
24
+ export function calculate_path(name: string, layout: Layout): number[] | null {
25
+ return calculate_path_recursive(name, layout, []);
26
+ }
27
+
28
+ function calculate_path_recursive(
29
+ name: string,
30
+ panel: Layout,
31
+ path: LayoutPathTraversal,
32
+ ): number[] | null {
33
+ if (panel.type === "tab-layout") {
34
+ if (!panel.tabs.includes(name)) {
35
+ return null;
36
+ }
37
+
38
+ return path;
39
+ }
40
+
41
+ for (let i = 0; i < panel.children.length; i++) {
42
+ const result = calculate_path_recursive(name, panel.children[i], [
43
+ ...path,
44
+ i,
45
+ ]);
46
+
47
+ if (result) {
48
+ return result;
49
+ }
50
+ }
51
+
52
+ return null;
53
+ }
@@ -23,7 +23,7 @@ import type { Layout } from "./types.ts";
23
23
  * @returns A new flattened layout tree (original is not mutated).
24
24
  */
25
25
  export function flatten(layout: Layout): Layout {
26
- if (layout.type === "child-panel") {
26
+ if (layout.type === "tab-layout") {
27
27
  layout.selected = layout.selected || 0;
28
28
  return layout;
29
29
  }
@@ -36,7 +36,7 @@ export function flatten(layout: Layout): Layout {
36
36
  const flattenedChild = flatten(child);
37
37
 
38
38
  if (
39
- flattenedChild.type === "split-panel" &&
39
+ flattenedChild.type === "split-layout" &&
40
40
  flattenedChild.orientation === layout.orientation
41
41
  ) {
42
42
  for (let j = 0; j < flattenedChild.children.length; j++) {
@@ -54,7 +54,7 @@ export function flatten(layout: Layout): Layout {
54
54
  }
55
55
 
56
56
  return {
57
- type: "split-panel",
57
+ type: "split-layout",
58
58
  orientation: layout.orientation,
59
59
  children: flattenedChildren,
60
60
  sizes: flattenedSizes,
@@ -44,7 +44,7 @@ function collect_track_positions(
44
44
  end: number,
45
45
  physics: Physics,
46
46
  ): number[] {
47
- if (panel.type === "child-panel") {
47
+ if (panel.type === "tab-layout") {
48
48
  return [start, end];
49
49
  }
50
50
 
@@ -100,11 +100,11 @@ function build_cells(
100
100
  rowEnd: number,
101
101
  physics: Physics,
102
102
  ): GridCell[] {
103
- if (panel.type === "child-panel") {
103
+ if (panel.type === "tab-layout") {
104
104
  const selected = panel.selected ?? 0;
105
105
  return [
106
106
  {
107
- child: panel.child[selected],
107
+ child: panel.tabs[selected],
108
108
  colStart: find_track_index(physics, colPositions, colStart),
109
109
  colEnd: find_track_index(physics, colPositions, colEnd),
110
110
  rowStart: find_track_index(physics, rowPositions, rowStart),
@@ -179,11 +179,11 @@ const child_template = (
179
179
  * @example
180
180
  * ```typescript
181
181
  * const layout = {
182
- * type: "split-panel",
182
+ * type: "split-layout",
183
183
  * orientation: "horizontal",
184
184
  * children: [
185
- * { type: "child-panel", child: "sidebar" },
186
- * { type: "child-panel", child: "main" }
185
+ * { type: "tab-layout", tabs: "sidebar" },
186
+ * { type: "tab-layout", tabs: "main" }
187
187
  * ],
188
188
  * sizes: [0.25, 0.75]
189
189
  * };
@@ -200,11 +200,11 @@ export function create_css_grid_layout(
200
200
  overlay?: [string, string],
201
201
  physics: Physics = DEFAULT_PHYSICS,
202
202
  ): string {
203
- if (layout.type === "child-panel") {
203
+ if (layout.type === "tab-layout") {
204
204
  const selected = layout.selected ?? 0;
205
205
  return [
206
206
  host_template("100%", "100%"),
207
- child_template(physics, layout.child[selected], "1", "1"),
207
+ child_template(physics, layout.tabs[selected], "1", "1"),
208
208
  ].join("\n");
209
209
  }
210
210
 
@@ -16,7 +16,7 @@ export function updateOverlaySheet(
16
16
  slot: string,
17
17
  box: DOMRect,
18
18
  style: CSSStyleDeclaration,
19
- drag_target: LayoutPath<undefined> | null,
19
+ drag_target: LayoutPath | null,
20
20
  physics = DEFAULT_PHYSICS,
21
21
  ) {
22
22
  if (!drag_target) {