regular-layout 0.1.0 → 0.2.1

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 (44) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +6 -6
  3. package/dist/extensions.d.ts +5 -4
  4. package/dist/index.d.ts +3 -3
  5. package/dist/index.js +15 -10
  6. package/dist/index.js.map +4 -4
  7. package/dist/{common → layout}/calculate_edge.d.ts +3 -2
  8. package/dist/{common → layout}/calculate_intersect.d.ts +13 -9
  9. package/dist/layout/constants.d.ts +81 -0
  10. package/dist/{common → layout}/flatten.d.ts +1 -1
  11. package/dist/{common → layout}/generate_grid.d.ts +5 -4
  12. package/dist/layout/generate_overlay.d.ts +2 -0
  13. package/dist/{common → layout}/insert_child.d.ts +3 -2
  14. package/dist/{common → layout}/redistribute_panel_sizes.d.ts +2 -2
  15. package/dist/{common → layout}/remove_child.d.ts +1 -1
  16. package/dist/{common/layout_config.d.ts → layout/types.d.ts} +6 -10
  17. package/dist/regular-layout-frame.d.ts +1 -4
  18. package/dist/regular-layout-tab.d.ts +26 -0
  19. package/dist/regular-layout.d.ts +37 -18
  20. package/package.json +9 -7
  21. package/src/extensions.ts +10 -4
  22. package/src/index.ts +3 -7
  23. package/src/layout/calculate_edge.ts +217 -0
  24. package/src/{common → layout}/calculate_intersect.ts +61 -101
  25. package/src/layout/constants.ts +119 -0
  26. package/src/{common → layout}/flatten.ts +1 -1
  27. package/src/{common → layout}/generate_grid.ts +120 -106
  28. package/src/{common → layout}/generate_overlay.ts +26 -12
  29. package/src/{common → layout}/insert_child.ts +105 -51
  30. package/src/{common → layout}/redistribute_panel_sizes.ts +11 -4
  31. package/src/{common → layout}/remove_child.ts +2 -2
  32. package/src/{common/layout_config.ts → layout/types.ts} +7 -19
  33. package/src/regular-layout-frame.ts +40 -74
  34. package/src/regular-layout-tab.ts +103 -0
  35. package/src/regular-layout.ts +260 -148
  36. package/themes/chicago.css +89 -0
  37. package/themes/fluxbox.css +110 -0
  38. package/themes/gibson.css +264 -0
  39. package/themes/hotdog.css +88 -0
  40. package/themes/lorax.css +130 -0
  41. package/dist/common/constants.d.ts +0 -29
  42. package/dist/common/generate_overlay.d.ts +0 -2
  43. package/src/common/calculate_edge.ts +0 -104
  44. package/src/common/constants.ts +0 -46
@@ -0,0 +1,217 @@
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 { DEFAULT_PHYSICS, type Physics } from "./constants";
13
+ import { insert_child } from "./insert_child";
14
+ import type { Layout, LayoutPath, Orientation, ViewWindow } from "./types";
15
+
16
+ /**
17
+ * Calculates an insertion point (which may involve splitting a single
18
+ * `"child-panel"` into a new `"split-panel"`), based on the cursor position.
19
+ * *
20
+ * @param col - The cursor column.
21
+ * @param row - The cursor row.
22
+ * @param panel - The `Layout` to insert into.
23
+ * @param slot - The slot identifier where the insert should occur
24
+ * @param drop_target - The `LayoutPath` (from `calculateIntersect`) of the
25
+ * panel to either insert next to, or split by.
26
+ * @returns A new `LayoutPath` reflecting the updated (maybe) `"split-panel"`,
27
+ * which is enough to draw the overlay.
28
+ */
29
+ export function calculate_edge(
30
+ col: number,
31
+ row: number,
32
+ panel: Layout,
33
+ slot: string,
34
+ drop_target: LayoutPath,
35
+ box?: DOMRect,
36
+ physics: Physics = DEFAULT_PHYSICS,
37
+ ): LayoutPath {
38
+ // Check root edges first
39
+ if (col < physics.SPLIT_ROOT_EDGE_TOLERANCE) {
40
+ return insert_root_edge(panel, slot, drop_target, [0], true, "horizontal");
41
+ }
42
+
43
+ if (col > 1 - physics.SPLIT_ROOT_EDGE_TOLERANCE) {
44
+ return insert_root_edge(
45
+ panel,
46
+ slot,
47
+ drop_target,
48
+ drop_target.path.length > 0 ? drop_target.path : [1],
49
+ false,
50
+ "horizontal",
51
+ );
52
+ }
53
+
54
+ if (row < physics.SPLIT_ROOT_EDGE_TOLERANCE) {
55
+ return insert_root_edge(panel, slot, drop_target, [0], true, "vertical");
56
+ }
57
+
58
+ if (row > 1 - physics.SPLIT_ROOT_EDGE_TOLERANCE) {
59
+ return insert_root_edge(
60
+ panel,
61
+ slot,
62
+ drop_target,
63
+ drop_target.path.length > 0 ? drop_target.path : [1],
64
+ false,
65
+ "vertical",
66
+ );
67
+ }
68
+
69
+ // Check panel edges
70
+ const is_column_edge =
71
+ drop_target.column_offset < physics.SPLIT_EDGE_TOLERANCE ||
72
+ drop_target.column_offset > 1 - physics.SPLIT_EDGE_TOLERANCE;
73
+
74
+ const is_row_edge =
75
+ drop_target.row_offset < physics.SPLIT_EDGE_TOLERANCE ||
76
+ drop_target.row_offset > 1 - physics.SPLIT_EDGE_TOLERANCE;
77
+
78
+ // If both edges triggered, choose closer axis
79
+ if (is_column_edge && is_row_edge) {
80
+ const col_distance = Math.abs(drop_target.column_offset - 0.5);
81
+ const row_distance = Math.abs(drop_target.row_offset - 0.5);
82
+ const col_scale =
83
+ (box?.width || 1) *
84
+ (drop_target.view_window.col_end - drop_target.view_window.col_start);
85
+
86
+ const row_scale =
87
+ (box?.height || 1) *
88
+ (drop_target.view_window.row_end - drop_target.view_window.row_start);
89
+
90
+ const use_column = col_distance * col_scale > row_distance * row_scale;
91
+
92
+ return insert_axis(
93
+ panel,
94
+ slot,
95
+ drop_target,
96
+ use_column
97
+ ? drop_target.column_offset < physics.SPLIT_EDGE_TOLERANCE
98
+ : drop_target.row_offset < physics.SPLIT_EDGE_TOLERANCE,
99
+ use_column ? "horizontal" : "vertical",
100
+ );
101
+ }
102
+
103
+ if (is_column_edge) {
104
+ return insert_axis(
105
+ panel,
106
+ slot,
107
+ drop_target,
108
+ drop_target.column_offset < physics.SPLIT_EDGE_TOLERANCE,
109
+ "horizontal",
110
+ );
111
+ }
112
+
113
+ if (is_row_edge) {
114
+ return insert_axis(
115
+ panel,
116
+ slot,
117
+ drop_target,
118
+ drop_target.row_offset < physics.SPLIT_EDGE_TOLERANCE,
119
+ "vertical",
120
+ );
121
+ }
122
+
123
+ // Not at an edge - insert as a tab
124
+ return {
125
+ ...drop_target,
126
+ path: [...drop_target.path, 0],
127
+ };
128
+ }
129
+
130
+ function insert_root_edge(
131
+ panel: Layout,
132
+ slot: string,
133
+ drop_target: LayoutPath,
134
+ path: number[],
135
+ is_before: boolean,
136
+ orientation: Orientation,
137
+ ): LayoutPath {
138
+ return insert_axis(
139
+ panel,
140
+ slot,
141
+ { ...drop_target, path, orientation },
142
+ is_before,
143
+ orientation,
144
+ );
145
+ }
146
+
147
+ function insert_axis(
148
+ panel: Layout,
149
+ slot: string,
150
+ drop_target: LayoutPath,
151
+ is_before: boolean,
152
+ axis_orientation: Orientation,
153
+ ): LayoutPath {
154
+ let result_path: number[];
155
+
156
+ if (drop_target.orientation === axis_orientation) {
157
+ // Same orientation - insert into existing split
158
+ if (drop_target.path.length === 0) {
159
+ result_path = [is_before ? 0 : 1];
160
+ } else {
161
+ const last_index = drop_target.path[drop_target.path.length - 1];
162
+ result_path = [
163
+ ...drop_target.path.slice(0, -1),
164
+ is_before ? last_index : last_index + 1,
165
+ ];
166
+ }
167
+ } else {
168
+ // Different orientation - split the child panel
169
+ result_path = [...drop_target.path, is_before ? 0 : 1];
170
+ }
171
+
172
+ const new_panel = insert_child(panel, slot, result_path, axis_orientation);
173
+ const view_window = calculate_view_window(new_panel, result_path);
174
+ return {
175
+ ...drop_target,
176
+ path: result_path,
177
+ slot: drop_target.slot,
178
+ is_edge: true,
179
+ orientation: axis_orientation,
180
+ view_window,
181
+ };
182
+ }
183
+
184
+ function calculate_view_window(panel: Layout, path: number[]): ViewWindow {
185
+ let view_window: ViewWindow = {
186
+ row_start: 0,
187
+ row_end: 1,
188
+ col_start: 0,
189
+ col_end: 1,
190
+ };
191
+
192
+ let current_panel = panel;
193
+ for (const step of path) {
194
+ if (current_panel.type === "child-panel") {
195
+ break;
196
+ }
197
+
198
+ const index = Math.min(step, current_panel.children.length - 1);
199
+ const is_vertical = current_panel.orientation === "vertical";
200
+ const start_key = is_vertical ? "row_start" : "col_start";
201
+ const end_key = is_vertical ? "row_end" : "col_end";
202
+ const total_size = view_window[end_key] - view_window[start_key];
203
+ const offset = current_panel.sizes
204
+ .slice(0, index)
205
+ .reduce((sum, size) => sum + size * total_size, view_window[start_key]);
206
+
207
+ view_window = {
208
+ ...view_window,
209
+ [start_key]: offset,
210
+ [end_key]: offset + total_size * current_panel.sizes[index],
211
+ };
212
+
213
+ current_panel = current_panel.children[index];
214
+ }
215
+
216
+ return view_window;
217
+ }
@@ -9,24 +9,24 @@
9
9
  // ┃ * [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). * ┃
10
10
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
11
11
 
12
- import type {
13
- LayoutPath,
14
- LayoutDivider,
15
- Layout,
16
- ViewWindow,
17
- } from "./layout_config.ts";
12
+ import type { LayoutPath, LayoutDivider, Layout, ViewWindow } from "./types.ts";
13
+
14
+ const VIEW_WINDOW = {
15
+ row_start: 0,
16
+ row_end: 1,
17
+ col_start: 0,
18
+ col_end: 1,
19
+ };
18
20
 
19
21
  /**
20
22
  * Determines which panel or divider is located at a given position in the
21
23
  * layout.
22
24
  *
23
- * @param row - Vertical position as a fraction (0-1) of the container
24
- * height
25
- * @param column - Horizontal position as a fraction (0-1) of the
26
- * container width
25
+ * @param column - Horizontal position as a fraction (0-1) of the container width
26
+ * @param row - Vertical position as a fraction (0-1) of the container height
27
27
  * @param layout - The layout tree to search
28
28
  * @param check_dividers - Whether `LayoutDivider` intersection should be
29
- * checked, which oyu may not want for e.g. `drop` actions.
29
+ * checked, which you may not want for e.g. `drop` actions.
30
30
  * @returns The panel path if over a panel, a divider if over a resizable
31
31
  * boundary, or null if outside all panels
32
32
  */
@@ -34,44 +34,37 @@ export function calculate_intersection(
34
34
  column: number,
35
35
  row: number,
36
36
  layout: Layout,
37
- check_dividers: false,
38
- ): LayoutPath;
37
+ check_dividers?: null,
38
+ ): LayoutPath | null;
39
39
 
40
40
  export function calculate_intersection(
41
41
  column: number,
42
42
  row: number,
43
43
  layout: Layout,
44
- check_dividers: true,
44
+ check_dividers?: { rect: DOMRect; size: number },
45
45
  ): LayoutPath | null | LayoutDivider;
46
46
 
47
47
  export function calculate_intersection(
48
48
  column: number,
49
49
  row: number,
50
50
  layout: Layout,
51
- check_dividers?: boolean,
51
+ check_dividers?: { rect: DOMRect; size: number } | null,
52
52
  ): LayoutPath | null | LayoutDivider;
53
53
 
54
54
  export function calculate_intersection(
55
55
  column: number,
56
56
  row: number,
57
57
  layout: Layout,
58
- check_dividers: boolean = true,
58
+ check_dividers: { rect: DOMRect; size: number } | null = null,
59
59
  ): LayoutPath | null | LayoutDivider {
60
60
  return calculate_intersection_recursive(column, row, layout, check_dividers);
61
61
  }
62
62
 
63
- const VIEW_WINDOW = {
64
- row_start: 0,
65
- row_end: 1,
66
- col_start: 0,
67
- col_end: 1,
68
- };
69
-
70
63
  function calculate_intersection_recursive(
71
64
  column: number,
72
65
  row: number,
73
66
  panel: Layout,
74
- check_dividers: boolean,
67
+ check_dividers: { rect: DOMRect; size: number } | null,
75
68
  parent_orientation: "horizontal" | "vertical" | null = null,
76
69
  view_window: ViewWindow = structuredClone(VIEW_WINDOW),
77
70
  path: number[] = [],
@@ -83,104 +76,71 @@ function calculate_intersection_recursive(
83
76
  // Base case: if this is a child panel, return its name
84
77
  if (panel.type === "child-panel") {
85
78
  const selected = panel.selected ?? 0;
86
- const column_offset =
87
- (column - view_window.col_start) /
88
- (view_window.col_end - view_window.col_start);
89
-
90
- const row_offset =
91
- (row - view_window.row_start) /
92
- (view_window.row_end - view_window.row_start);
93
-
79
+ const col_width = view_window.col_end - view_window.col_start;
80
+ const row_height = view_window.row_end - view_window.row_start;
94
81
  return {
95
82
  type: "layout-path",
96
- box: undefined,
83
+ layout: undefined,
97
84
  slot: panel.child[selected],
98
- panel: structuredClone(panel),
99
- path: path,
100
- view_window: view_window,
85
+ path,
86
+ view_window,
101
87
  is_edge: false,
102
88
  column,
103
89
  row,
104
- column_offset,
105
- row_offset,
90
+ column_offset: (column - view_window.col_start) / col_width,
91
+ row_offset: (row - view_window.row_start) / row_height,
106
92
  orientation: parent_orientation || "horizontal",
107
93
  };
108
94
  }
109
95
 
110
96
  // For split panels, determine which child was hit
111
- if (panel.orientation === "vertical") {
112
- // Vertical orientation = rows
113
- let current_row = view_window.row_start;
114
- for (let i = 0; i < panel.children.length; i++) {
115
- const total_size = view_window.row_end - view_window.row_start;
116
- const next_row = total_size * panel.sizes[i] + current_row;
117
- if (check_dividers && Math.abs(row - next_row) < 0.01) {
97
+ const is_vertical = panel.orientation === "vertical";
98
+ const position = is_vertical ? row : column;
99
+ const start_key = is_vertical ? "row_start" : "col_start";
100
+ const end_key = is_vertical ? "row_end" : "col_end";
101
+ const rect_dim = is_vertical
102
+ ? check_dividers?.rect?.height
103
+ : check_dividers?.rect?.width;
104
+
105
+ let current_pos = view_window[start_key];
106
+ const total_size = view_window[end_key] - view_window[start_key];
107
+ for (let i = 0; i < panel.children.length; i++) {
108
+ const next_pos = current_pos + total_size * panel.sizes[i];
109
+
110
+ // Check if position is on a divider
111
+ if (check_dividers && rect_dim) {
112
+ const divider_threshold = check_dividers.size / rect_dim;
113
+ if (Math.abs(position - next_pos) < divider_threshold) {
118
114
  return {
119
115
  path: [...path, i],
120
- type: "vertical",
116
+ type: panel.orientation,
121
117
  view_window: {
122
118
  ...view_window,
123
- row_start: current_row,
124
- row_end: next_row,
119
+ [start_key]: current_pos,
120
+ [end_key]: next_pos,
125
121
  },
126
122
  };
127
123
  }
128
-
129
- if (row >= current_row && row < next_row) {
130
- return calculate_intersection_recursive(
131
- column,
132
- row,
133
- panel.children[i],
134
- check_dividers,
135
- "vertical",
136
- {
137
- ...view_window,
138
- row_start: current_row,
139
- row_end: next_row,
140
- },
141
- [...path, i],
142
- );
143
- }
144
-
145
- current_row = next_row;
146
124
  }
147
- } else {
148
- // Horizontal orientation = columns
149
- let current_col = view_window.col_start;
150
- for (let i = 0; i < panel.children.length; i++) {
151
- const total_size = view_window.col_end - view_window.col_start;
152
- const next_col = current_col + total_size * panel.sizes[i];
153
- if (check_dividers && Math.abs(column - next_col) < 0.01) {
154
- return {
155
- path: [...path, i],
156
- type: "horizontal",
157
- view_window: {
158
- ...view_window,
159
- col_start: current_col,
160
- col_end: next_col,
161
- },
162
- };
163
- }
164
-
165
- // Check if the column falls within this child's bounds.
166
- if (column >= current_col && column < next_col) {
167
- return calculate_intersection_recursive(
168
- column,
169
- row,
170
- panel.children[i],
171
- check_dividers,
172
- "horizontal",
173
- {
174
- ...view_window,
175
- col_start: current_col,
176
- col_end: next_col,
177
- },
178
- [...path, i],
179
- );
180
- }
181
125
 
182
- current_col = next_col;
126
+ // Check if position falls within this child's bounds
127
+ if (position >= current_pos && position < next_pos) {
128
+ return calculate_intersection_recursive(
129
+ column,
130
+ row,
131
+ panel.children[i],
132
+ check_dividers,
133
+ panel.orientation,
134
+ {
135
+ ...view_window,
136
+ [start_key]: current_pos,
137
+ [end_key]: next_pos,
138
+ },
139
+ [...path, i],
140
+ );
183
141
  }
142
+
143
+ current_pos = next_pos;
184
144
  }
185
145
 
186
146
  // If we get here, the hit was outside all children (possibly in a gap or
@@ -0,0 +1,119 @@
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 { OverlayMode } from "./types";
13
+
14
+ /**
15
+ * Instance-specific constants which define the behavior and rendering details
16
+ * of a `<regular-layout>`.
17
+ */
18
+ export interface Physics {
19
+ /**
20
+ * The prefix to use for `CustomEvent`s generated by `regular-layout`, e.g.
21
+ * `"regular-layout-before-update"`.
22
+ */
23
+ CUSTOM_EVENT_NAME_PREFIX: string;
24
+
25
+ /**
26
+ * The attribute name to use for matching child `Element`s to grid
27
+ * positions.
28
+ */
29
+ CHILD_ATTRIBUTE_NAME: string;
30
+
31
+ /**
32
+ * The minimum number of pixels the mouse must move to be considered a drag.
33
+ */
34
+ MIN_DRAG_DISTANCE: number;
35
+
36
+ /**
37
+ * Should floating point pixel calculations be rounded. Useful for testing.
38
+ */
39
+ SHOULD_ROUND: boolean;
40
+
41
+ /**
42
+ * Class name to use for child elements in overlay position (dragging).
43
+ */
44
+ OVERLAY_CLASSNAME: string;
45
+
46
+ /**
47
+ * The percentage of the maximum resize distance that will be clamped.
48
+ */
49
+ MINIMUM_REDISTRIBUTION_SIZE_THRESHOLD: number;
50
+
51
+ /**
52
+ * Threshold from panel edge that is considered a split vs drop action.
53
+ */
54
+ SPLIT_EDGE_TOLERANCE: number;
55
+
56
+ /**
57
+ * Threshold from _container_ edge that is considered a split action on the root
58
+ * node.
59
+ */
60
+ SPLIT_ROOT_EDGE_TOLERANCE: number;
61
+
62
+ /**
63
+ * Tolerance threshold for considering two grid track positions as identical.
64
+ *
65
+ * When collecting and deduplicating track positions, any positions closer than
66
+ * this value are treated as the same position to avoid redundant grid tracks.
67
+ */
68
+ GRID_TRACK_COLLAPSE_TOLERANCE: number;
69
+
70
+ /**
71
+ * The overlay default behavior.
72
+ */
73
+ OVERLAY_DEFAULT: OverlayMode;
74
+
75
+ /**
76
+ * Width of split panel dividers in pixels (for hit-test purposes).
77
+ */
78
+ GRID_DIVIDER_SIZE: number;
79
+
80
+ /**
81
+ * Whether the grid should trigger column resize if the grid itself is not
82
+ * the `event.target`.
83
+ */
84
+ GRID_DIVIDER_CHECK_TARGET: boolean;
85
+ }
86
+
87
+ /**
88
+ * Like `GlobalPhysics`, but suitable for partial definition for incremental
89
+ * updates.
90
+ */
91
+ export interface PhysicsUpdate {
92
+ CUSTOM_EVENT_NAME_PREFIX?: string;
93
+ CHILD_ATTRIBUTE_NAME?: string;
94
+ MIN_DRAG_DISTANCE?: number;
95
+ SHOULD_ROUND?: boolean;
96
+ OVERLAY_CLASSNAME?: string;
97
+ MINIMUM_REDISTRIBUTION_SIZE_THRESHOLD?: number;
98
+ SPLIT_EDGE_TOLERANCE?: number;
99
+ SPLIT_ROOT_EDGE_TOLERANCE?: number;
100
+ GRID_TRACK_COLLAPSE_TOLERANCE?: number;
101
+ OVERLAY_DEFAULT?: OverlayMode;
102
+ GRID_DIVIDER_SIZE?: number;
103
+ GRID_DIVIDER_CHECK_TARGET?: boolean;
104
+ }
105
+
106
+ export const DEFAULT_PHYSICS: Physics = Object.freeze({
107
+ CUSTOM_EVENT_NAME_PREFIX: "regular-layout",
108
+ CHILD_ATTRIBUTE_NAME: "name",
109
+ MIN_DRAG_DISTANCE: 10,
110
+ SHOULD_ROUND: false,
111
+ OVERLAY_CLASSNAME: "overlay",
112
+ MINIMUM_REDISTRIBUTION_SIZE_THRESHOLD: 0.15,
113
+ SPLIT_EDGE_TOLERANCE: 0.25,
114
+ SPLIT_ROOT_EDGE_TOLERANCE: 0.01,
115
+ GRID_TRACK_COLLAPSE_TOLERANCE: 0.001,
116
+ OVERLAY_DEFAULT: "absolute",
117
+ GRID_DIVIDER_SIZE: 6,
118
+ GRID_DIVIDER_CHECK_TARGET: true,
119
+ });
@@ -9,7 +9,7 @@
9
9
  // ┃ * [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). * ┃
10
10
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
11
11
 
12
- import type { Layout } from "./layout_config.ts";
12
+ import type { Layout } from "./types.ts";
13
13
 
14
14
  /**
15
15
  * Flattens the layout tree by merging parent and child split panels that have