regular-layout 0.1.0 → 0.2.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 (42) 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 +2 -2
  8. package/dist/{common → layout}/calculate_intersect.d.ts +7 -9
  9. package/dist/{common → layout}/constants.d.ts +15 -1
  10. package/dist/{common → layout}/flatten.d.ts +1 -1
  11. package/dist/{common → layout}/generate_grid.d.ts +3 -3
  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 +1 -1
  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 +23 -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 +209 -0
  24. package/src/{common → layout}/calculate_intersect.ts +59 -101
  25. package/src/{common → layout}/constants.ts +18 -1
  26. package/src/{common → layout}/flatten.ts +1 -1
  27. package/src/{common → layout}/generate_grid.ts +76 -106
  28. package/src/{common → layout}/generate_overlay.ts +24 -12
  29. package/src/{common → layout}/insert_child.ts +105 -51
  30. package/src/{common → layout}/redistribute_panel_sizes.ts +1 -1
  31. package/src/{common → layout}/remove_child.ts +2 -2
  32. package/src/{common/layout_config.ts → layout/types.ts} +6 -19
  33. package/src/regular-layout-frame.ts +34 -71
  34. package/src/regular-layout-tab.ts +103 -0
  35. package/src/regular-layout.ts +190 -141
  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 +129 -0
  41. package/dist/common/generate_overlay.d.ts +0 -2
  42. package/src/common/calculate_edge.ts +0 -104
@@ -9,24 +9,25 @@
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 { GRID_DIVIDER_SIZE } from "./constants.ts";
13
+ import type { LayoutPath, LayoutDivider, Layout, ViewWindow } from "./types.ts";
14
+
15
+ const VIEW_WINDOW = {
16
+ row_start: 0,
17
+ row_end: 1,
18
+ col_start: 0,
19
+ col_end: 1,
20
+ };
18
21
 
19
22
  /**
20
23
  * Determines which panel or divider is located at a given position in the
21
24
  * layout.
22
25
  *
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
26
+ * @param column - Horizontal position as a fraction (0-1) of the container width
27
+ * @param row - Vertical position as a fraction (0-1) of the container height
27
28
  * @param layout - The layout tree to search
28
29
  * @param check_dividers - Whether `LayoutDivider` intersection should be
29
- * checked, which oyu may not want for e.g. `drop` actions.
30
+ * checked, which you may not want for e.g. `drop` actions.
30
31
  * @returns The panel path if over a panel, a divider if over a resizable
31
32
  * boundary, or null if outside all panels
32
33
  */
@@ -34,44 +35,37 @@ export function calculate_intersection(
34
35
  column: number,
35
36
  row: number,
36
37
  layout: Layout,
37
- check_dividers: false,
38
- ): LayoutPath;
38
+ check_dividers?: null,
39
+ ): LayoutPath | null;
39
40
 
40
41
  export function calculate_intersection(
41
42
  column: number,
42
43
  row: number,
43
44
  layout: Layout,
44
- check_dividers: true,
45
+ check_dividers?: DOMRect,
45
46
  ): LayoutPath | null | LayoutDivider;
46
47
 
47
48
  export function calculate_intersection(
48
49
  column: number,
49
50
  row: number,
50
51
  layout: Layout,
51
- check_dividers?: boolean,
52
+ check_dividers?: DOMRect | null,
52
53
  ): LayoutPath | null | LayoutDivider;
53
54
 
54
55
  export function calculate_intersection(
55
56
  column: number,
56
57
  row: number,
57
58
  layout: Layout,
58
- check_dividers: boolean = true,
59
+ check_dividers: DOMRect | null = null,
59
60
  ): LayoutPath | null | LayoutDivider {
60
61
  return calculate_intersection_recursive(column, row, layout, check_dividers);
61
62
  }
62
63
 
63
- const VIEW_WINDOW = {
64
- row_start: 0,
65
- row_end: 1,
66
- col_start: 0,
67
- col_end: 1,
68
- };
69
-
70
64
  function calculate_intersection_recursive(
71
65
  column: number,
72
66
  row: number,
73
67
  panel: Layout,
74
- check_dividers: boolean,
68
+ check_dividers: DOMRect | null,
75
69
  parent_orientation: "horizontal" | "vertical" | null = null,
76
70
  view_window: ViewWindow = structuredClone(VIEW_WINDOW),
77
71
  path: number[] = [],
@@ -83,104 +77,68 @@ function calculate_intersection_recursive(
83
77
  // Base case: if this is a child panel, return its name
84
78
  if (panel.type === "child-panel") {
85
79
  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
-
80
+ const col_width = view_window.col_end - view_window.col_start;
81
+ const row_height = view_window.row_end - view_window.row_start;
94
82
  return {
95
83
  type: "layout-path",
96
- box: undefined,
84
+ layout: undefined,
97
85
  slot: panel.child[selected],
98
- panel: structuredClone(panel),
99
- path: path,
100
- view_window: view_window,
86
+ path,
87
+ view_window,
101
88
  is_edge: false,
102
89
  column,
103
90
  row,
104
- column_offset,
105
- row_offset,
91
+ column_offset: (column - view_window.col_start) / col_width,
92
+ row_offset: (row - view_window.row_start) / row_height,
106
93
  orientation: parent_orientation || "horizontal",
107
94
  };
108
95
  }
109
96
 
110
97
  // 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) {
98
+ const is_vertical = panel.orientation === "vertical";
99
+ const position = is_vertical ? row : column;
100
+ const start_key = is_vertical ? "row_start" : "col_start";
101
+ const end_key = is_vertical ? "row_end" : "col_end";
102
+ const rect_dim = is_vertical ? check_dividers?.height : check_dividers?.width;
103
+ let current_pos = view_window[start_key];
104
+ const total_size = view_window[end_key] - view_window[start_key];
105
+ for (let i = 0; i < panel.children.length; i++) {
106
+ const next_pos = current_pos + total_size * panel.sizes[i];
107
+
108
+ // Check if position is on a divider
109
+ if (check_dividers && rect_dim) {
110
+ const divider_threshold = GRID_DIVIDER_SIZE / rect_dim;
111
+ if (Math.abs(position - next_pos) < divider_threshold) {
118
112
  return {
119
113
  path: [...path, i],
120
- type: "vertical",
114
+ type: panel.orientation,
121
115
  view_window: {
122
116
  ...view_window,
123
- row_start: current_row,
124
- row_end: next_row,
117
+ [start_key]: current_pos,
118
+ [end_key]: next_pos,
125
119
  },
126
120
  };
127
121
  }
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
122
  }
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
123
 
182
- current_col = next_col;
124
+ // Check if position falls within this child's bounds
125
+ if (position >= current_pos && position < next_pos) {
126
+ return calculate_intersection_recursive(
127
+ column,
128
+ row,
129
+ panel.children[i],
130
+ check_dividers,
131
+ panel.orientation,
132
+ {
133
+ ...view_window,
134
+ [start_key]: current_pos,
135
+ [end_key]: next_pos,
136
+ },
137
+ [...path, i],
138
+ );
183
139
  }
140
+
141
+ current_pos = next_pos;
184
142
  }
185
143
 
186
144
  // If we get here, the hit was outside all children (possibly in a gap or
@@ -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 { OverlayMode } from "./layout_config";
12
+ import type { OverlayMode } from "./types";
13
+
14
+ /**
15
+ * The prefix to use for `CustomEvent`s generated by `regular-layout`, e.g.
16
+ * `"regular-layout-before-update"`.
17
+ */
18
+ export const CUSTOM_EVENT_NAME_PREFIX = "regular-layout";
13
19
 
14
20
  /**
15
21
  * The minimum number of pixels the mouse must move to be considered a drag.
@@ -32,6 +38,12 @@ export const MINIMUM_REDISTRIBUTION_SIZE_THRESHOLD = 0.15;
32
38
  */
33
39
  export const SPLIT_EDGE_TOLERANCE = 0.25;
34
40
 
41
+ /**
42
+ * Threshold from _container_ edge that is considered a split action on the root
43
+ * node.
44
+ */
45
+ export const SPLIT_ROOT_EDGE_TOLERANCE = 0.01;
46
+
35
47
  /**
36
48
  * Tolerance threshold for considering two grid track positions as identical.
37
49
  *
@@ -44,3 +56,8 @@ export const GRID_TRACK_COLLAPSE_TOLERANCE = 0.001;
44
56
  * The overlay default behavior.
45
57
  */
46
58
  export const OVERLAY_DEFAULT: OverlayMode = "absolute";
59
+
60
+ /**
61
+ * Width of split panel dividers in pixels (for hit-test purposes).
62
+ */
63
+ export const GRID_DIVIDER_SIZE = 6;
@@ -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
@@ -10,8 +10,7 @@
10
10
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
11
11
 
12
12
  import { GRID_TRACK_COLLAPSE_TOLERANCE } from "./constants.ts";
13
- import type { Layout } from "./layout_config.ts";
14
- import { remove_child } from "./remove_child.ts";
13
+ import type { Layout } from "./types.ts";
15
14
 
16
15
  interface GridCell {
17
16
  child: string;
@@ -21,26 +20,23 @@ interface GridCell {
21
20
  rowEnd: number;
22
21
  }
23
22
 
24
- function dedupePositions(positions: number[]): number[] {
25
- if (positions.length === 0) {
26
- return [];
27
- }
28
-
29
- const sorted = positions.sort((a, b) => a - b);
30
- const result = [sorted[0]];
31
- for (let i = 1; i < sorted.length; i++) {
32
- if (
33
- Math.abs(sorted[i] - result[result.length - 1]) >
34
- GRID_TRACK_COLLAPSE_TOLERANCE
35
- ) {
36
- result.push(sorted[i]);
37
- }
23
+ function dedupe_sort(result: number[], pos: number) {
24
+ if (
25
+ result.length === 0 ||
26
+ Math.abs(pos - result[result.length - 1]) > GRID_TRACK_COLLAPSE_TOLERANCE
27
+ ) {
28
+ result.push(pos);
38
29
  }
39
30
 
40
31
  return result;
41
32
  }
42
33
 
43
- function collectTrackPositions(
34
+ function dedupe_positions(positions: number[]): number[] {
35
+ const sorted = positions.sort((a, b) => a - b);
36
+ return sorted.reduce(dedupe_sort, []);
37
+ }
38
+
39
+ function collect_track_positions(
44
40
  panel: Layout,
45
41
  orientation: "horizontal" | "vertical",
46
42
  start: number,
@@ -50,51 +46,44 @@ function collectTrackPositions(
50
46
  return [start, end];
51
47
  }
52
48
 
49
+ const positions: number[] = [start, end];
53
50
  if (panel.orientation === orientation) {
54
- const positions: number[] = [start, end];
55
51
  let current = start;
52
+ const range = end - start;
56
53
  for (let i = 0; i < panel.children.length; i++) {
57
54
  const size = panel.sizes[i];
58
- const childPositions = collectTrackPositions(
59
- panel.children[i],
60
- orientation,
61
- current,
62
- current + size * (end - start),
55
+ const next = current + size * range;
56
+ positions.push(
57
+ ...collect_track_positions(
58
+ panel.children[i],
59
+ orientation,
60
+ current,
61
+ next,
62
+ ),
63
63
  );
64
64
 
65
- positions.push(...childPositions);
66
- current = current + size * (end - start);
65
+ current = next;
67
66
  }
68
-
69
- return dedupePositions(positions);
70
67
  } else {
71
- const allPositions: number[] = [start, end];
72
68
  for (const child of panel.children) {
73
- const childPositions = collectTrackPositions(
74
- child,
75
- orientation,
76
- start,
77
- end,
69
+ positions.push(
70
+ ...collect_track_positions(child, orientation, start, end),
78
71
  );
79
-
80
- allPositions.push(...childPositions);
81
72
  }
82
-
83
- return dedupePositions(allPositions);
84
73
  }
74
+
75
+ return dedupe_positions(positions);
85
76
  }
86
77
 
87
- function findTrackIndex(positions: number[], value: number): number {
88
- for (let i = 0; i < positions.length; i++) {
89
- if (Math.abs(positions[i] - value) < GRID_TRACK_COLLAPSE_TOLERANCE) {
90
- return i;
91
- }
92
- }
78
+ function find_track_index(positions: number[], value: number): number {
79
+ const index = positions.findIndex(
80
+ (pos) => Math.abs(pos - value) < GRID_TRACK_COLLAPSE_TOLERANCE,
81
+ );
93
82
 
94
- throw new Error(`Position ${value} not found in ${positions}`);
83
+ return index === -1 ? 0 : index;
95
84
  }
96
85
 
97
- function buildCells(
86
+ function build_cells(
98
87
  panel: Layout,
99
88
  colPositions: number[],
100
89
  rowPositions: number[],
@@ -108,22 +97,24 @@ function buildCells(
108
97
  return [
109
98
  {
110
99
  child: panel.child[selected],
111
- colStart: findTrackIndex(colPositions, colStart),
112
- colEnd: findTrackIndex(colPositions, colEnd),
113
- rowStart: findTrackIndex(rowPositions, rowStart),
114
- rowEnd: findTrackIndex(rowPositions, rowEnd),
100
+ colStart: find_track_index(colPositions, colStart),
101
+ colEnd: find_track_index(colPositions, colEnd),
102
+ rowStart: find_track_index(rowPositions, rowStart),
103
+ rowEnd: find_track_index(rowPositions, rowEnd),
115
104
  },
116
105
  ];
117
106
  }
118
107
 
119
- const cells: GridCell[] = [];
120
108
  const { children, sizes, orientation } = panel;
121
- if (orientation === "horizontal") {
122
- let current = colStart;
123
- for (let i = 0; i < children.length; i++) {
124
- const next = current + sizes[i] * (colEnd - colStart);
109
+ const isHorizontal = orientation === "horizontal";
110
+ let current = isHorizontal ? colStart : rowStart;
111
+ const range = isHorizontal ? colEnd - colStart : rowEnd - rowStart;
112
+ const cells: GridCell[] = [];
113
+ for (let i = 0; i < children.length; i++) {
114
+ const next = current + sizes[i] * range;
115
+ if (isHorizontal) {
125
116
  cells.push(
126
- ...buildCells(
117
+ ...build_cells(
127
118
  children[i],
128
119
  colPositions,
129
120
  rowPositions,
@@ -133,15 +124,9 @@ function buildCells(
133
124
  rowEnd,
134
125
  ),
135
126
  );
136
-
137
- current = next;
138
- }
139
- } else {
140
- let current = rowStart;
141
- for (let i = 0; i < children.length; i++) {
142
- const next = current + sizes[i] * (rowEnd - rowStart);
127
+ } else {
143
128
  cells.push(
144
- ...buildCells(
129
+ ...build_cells(
145
130
  children[i],
146
131
  colPositions,
147
132
  rowPositions,
@@ -151,19 +136,19 @@ function buildCells(
151
136
  next,
152
137
  ),
153
138
  );
154
-
155
- current = next;
156
139
  }
140
+
141
+ current = next;
157
142
  }
158
143
 
159
144
  return cells;
160
145
  }
161
146
 
162
147
  const host_template = (rowTemplate: string, colTemplate: string) =>
163
- `:host { display: grid; gap: 0px; grid-template-rows: ${rowTemplate}; grid-template-columns: ${colTemplate}; }`;
148
+ `:host ::slotted(*){display:none}:host{display:grid;grid-template-rows:${rowTemplate};grid-template-columns:${colTemplate}}`;
164
149
 
165
150
  const child_template = (slot: string, rowPart: string, colPart: string) =>
166
- `:host ::slotted([slot=${slot}]) { grid-column: ${colPart}; grid-row: ${rowPart}; }`;
151
+ `:host ::slotted([name="${slot}"]){display:flex;grid-column:${colPart};grid-row:${rowPart}}`;
167
152
 
168
153
  /**
169
154
  * Generates CSS Grid styles to render a layout tree.
@@ -191,8 +176,8 @@ const child_template = (slot: string, rowPart: string, colPart: string) =>
191
176
  * const css = create_css_grid_layout(layout);
192
177
  * // Returns CSS like:
193
178
  * // :host { display: grid; grid-template-columns: 25% 75%; ... }
194
- * // :host ::slotted([slot=sidebar]) { grid-column: 1; grid-row: 1; }
195
- * // :host ::slotted([slot=main]) { grid-column: 2; grid-row: 1; }
179
+ * // :host ::slotted([name=sidebar]) { grid-column: 1; grid-row: 1; }
180
+ * // :host ::slotted([name=main]) { grid-column: 2; grid-row: 1; }
196
181
  * ```
197
182
  */
198
183
  export function create_css_grid_layout(
@@ -200,51 +185,36 @@ export function create_css_grid_layout(
200
185
  round: boolean = false,
201
186
  overlay?: [string, string],
202
187
  ): string {
203
- if (overlay) {
204
- layout = remove_child(layout, overlay[0]);
205
- }
206
-
207
188
  if (layout.type === "child-panel") {
208
189
  const selected = layout.selected ?? 0;
209
190
  return `${host_template("100%", "100%")}\n${child_template(layout.child[selected], "1", "1")}`;
210
191
  }
211
192
 
212
- const colPositions = collectTrackPositions(layout, "horizontal", 0, 1);
213
- const colSizes: number[] = [];
214
- for (let i = 0; i < colPositions.length - 1; i++) {
215
- colSizes.push(colPositions[i + 1] - colPositions[i]);
216
- }
217
-
218
- const colTemplate = colSizes
219
- .map((s) => `${round ? Math.round(s * 100) : s * 100}%`)
220
- .join(" ");
221
-
222
- const rowPositions = collectTrackPositions(layout, "vertical", 0, 1);
223
- const rowSizes: number[] = [];
224
- for (let i = 0; i < rowPositions.length - 1; i++) {
225
- rowSizes.push(rowPositions[i + 1] - rowPositions[i]);
226
- }
227
-
228
- const rowTemplate = rowSizes
229
- .map((s) => `${round ? Math.round(s * 100) : s * 100}%`)
230
- .join(" ");
231
-
232
- const cells = buildCells(layout, colPositions, rowPositions, 0, 1, 0, 1);
193
+ const createTemplate = (positions: number[]) => {
194
+ const sizes = positions
195
+ .slice(0, -1)
196
+ .map((pos, i) => positions[i + 1] - pos);
197
+ return sizes
198
+ .map((s) => `${round ? Math.round(s * 100) : s * 100}fr`)
199
+ .join(" ");
200
+ };
201
+
202
+ const colPositions = collect_track_positions(layout, "horizontal", 0, 1);
203
+ const colTemplate = createTemplate(colPositions);
204
+ const rowPositions = collect_track_positions(layout, "vertical", 0, 1);
205
+ const rowTemplate = createTemplate(rowPositions);
206
+ const formatGridLine = (start: number, end: number) =>
207
+ end - start === 1 ? `${start + 1}` : `${start + 1} / ${end + 1}`;
208
+
209
+ const cells = build_cells(layout, colPositions, rowPositions, 0, 1, 0, 1);
233
210
  const css = [host_template(rowTemplate, colTemplate)];
234
211
  for (const cell of cells) {
235
- const colPart =
236
- cell.colEnd - cell.colStart === 1
237
- ? `${cell.colStart + 1}`
238
- : `${cell.colStart + 1} / ${cell.colEnd + 1}`;
239
- const rowPart =
240
- cell.rowEnd - cell.rowStart === 1
241
- ? `${cell.rowStart + 1}`
242
- : `${cell.rowStart + 1} / ${cell.rowEnd + 1}`;
243
-
244
- css.push(`${child_template(cell.child, rowPart, colPart)}`);
212
+ const colPart = formatGridLine(cell.colStart, cell.colEnd);
213
+ const rowPart = formatGridLine(cell.rowStart, cell.rowEnd);
214
+ css.push(child_template(cell.child, rowPart, colPart));
245
215
  if (cell.child === overlay?.[1]) {
246
- css.push(`${child_template(overlay[0], rowPart, colPart)}`);
247
- css.push(`:host ::slotted([slot=${overlay[0]}]) { z-index: 1; }`);
216
+ css.push(child_template(overlay[0], rowPart, colPart));
217
+ css.push(`:host ::slotted([name=${overlay[0]}]){z-index:1}`);
248
218
  }
249
219
  }
250
220
 
@@ -9,20 +9,32 @@
9
9
  // ┃ * [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). * ┃
10
10
  // ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
11
11
 
12
- import type { LayoutPath } from "./layout_config";
12
+ import type { LayoutPath } from "./types";
13
13
 
14
14
  export function updateOverlaySheet(
15
15
  slot: string,
16
- {
17
- view_window: { row_start, row_end, col_start, col_end },
18
- box,
19
- }: LayoutPath<DOMRect>,
16
+ box: DOMRect,
17
+ style: CSSStyleDeclaration,
18
+ drag_target: LayoutPath<undefined> | null,
20
19
  ) {
21
- const margin = 0;
22
- const top = row_start * box.height + margin / 2;
23
- const left = col_start * box.width + margin / 2;
24
- const height = (row_end - row_start) * box.height - margin;
25
- const width = (col_end - col_start) * box.width - margin;
26
- const css = `position:absolute!important;z-index:1;top:${top}px;left:${left}px;height:${height}px;width:${width}px;`;
27
- return `::slotted([slot="${slot}"]){${css}}`;
20
+ if (!drag_target) {
21
+ return `:host ::slotted([name="${slot}"]){display:none;}`;
22
+ }
23
+
24
+ const {
25
+ view_window: { row_start, row_end, col_start, col_end },
26
+ } = drag_target;
27
+
28
+ const box_height =
29
+ box.height - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom);
30
+
31
+ const box_width =
32
+ box.width - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight);
33
+
34
+ const top = row_start * box_height + parseFloat(style.paddingTop);
35
+ const left = col_start * box_width + parseFloat(style.paddingLeft);
36
+ const height = (row_end - row_start) * box_height;
37
+ const width = (col_end - col_start) * box_width;
38
+ const css = `display:flex;position:absolute!important;z-index:1;top:${top}px;left:${left}px;height:${height}px;width:${width}px;`;
39
+ return `::slotted([name="${slot}"]){${css}}`;
28
40
  }