sliced-areas 1.1.0 → 2.0.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.
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export { SlicedAreasElement, registerSlicedAreasElement } from './sliced-areas';
2
- export type { AreaId, AreaRect, AreaTag, AreasGraph, AreasLayout, GraphArea, GraphEdge, GraphVert, AreaResolver, SlicedAreasOperation, SlicedAreasOperationsConfig, } from './sliced-areas';
2
+ export type { AreaId, AreaAddedDetail, AreaRect, AreaRemovedDetail, AreaTag, AreasGraph, AreasLayout, AreaUpdatedDetail, GraphArea, GraphEdge, GraphVert, AreaResolver, SlicedAreasOperation, SlicedAreasOperationsConfig, } from './sliced-areas';
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { n as registerSlicedAreasElement, t as SlicedAreasElement } from "./sliced-areas-C43gYU0G.js";
1
+ import { n as registerSlicedAreasElement, t as SlicedAreasElement } from "./sliced-areas-BnxGgD6W.js";
2
2
  export { SlicedAreasElement, registerSlicedAreasElement };
@@ -42,7 +42,9 @@ var INTERNAL_ATTR = "data-sliced-areas-internal", AUTO_ATTR = "data-sliced-areas
42
42
  this.graph = null, this.areaTags.clear(), this.storedGraph = null, this.storedTags = null, this.resolvedNodes.clear(), this.render();
43
43
  return;
44
44
  }
45
- this.storedGraph = null, this.storedTags = null, this.graph = this.buildGraphFromLayout(e), this.resolvedNodes.clear(), this.render();
45
+ this.storedGraph = null, this.storedTags = null;
46
+ let t = this.graph, n = new Map(this.areaTags), r = this.buildGraphFromLayout(e);
47
+ this.applyGraphChange(r, "layout", t, n);
46
48
  }
47
49
  get operations() {
48
50
  return this.operationsConfig;
@@ -62,48 +64,65 @@ var INTERNAL_ATTR = "data-sliced-areas-internal", AUTO_ATTR = "data-sliced-areas
62
64
  split(e, t = "right", r = 0, i = 0) {
63
65
  if (!this.isOperationEnabled("split") || !this.graph) return;
64
66
  let a = this.nextAreaId(), o = Number.isFinite(r) && Number.isFinite(i) && this.rootEl ? this.splitAreaAtPointer(this.graph, e, t, r, i, a) : this.splitAreaByZone(this.graph, e, t, DEFAULT_RATIO, a);
65
- o && (this.ensureAreaNode(a, e, !0), this.graph = this.normalizeGraph(o), this.emitLayoutChange(), this.render());
67
+ if (!o) return;
68
+ this.ensureAreaNode(a, e, !0);
69
+ let s = this.normalizeGraph(o);
70
+ this.applyGraphChange(s, "split");
66
71
  }
67
72
  join(e, t) {
68
73
  if (!this.isOperationEnabled("join") || !this.graph || !this.canJoin(e, t)) return;
69
- let n = this.joinAreas(this.graph, e, t);
70
- n && (this.graph = this.normalizeGraph(n), this.pruneAreaTags(this.graph), this.emitLayoutChange(), this.render());
74
+ let n = this.graph, r = new Map(this.areaTags), i = this.joinAreas(this.graph, e, t);
75
+ if (!i) return;
76
+ let a = this.normalizeGraph(i);
77
+ this.applyGraphChange(a, "join", n, r), this.pruneAreaTags(a);
71
78
  }
72
79
  replace(e, t) {
73
80
  if (!this.isOperationEnabled("replace") || !this.graph) return;
74
- let n = this.replaceArea(this.graph, e, t);
75
- n && (this.graph = this.normalizeGraph(n), this.removeAreaNode(t), this.pruneAreaTags(this.graph), this.emitLayoutChange(), this.render());
81
+ let n = this.graph, r = new Map(this.areaTags), i = this.replaceArea(this.graph, e, t);
82
+ if (!i) return;
83
+ this.removeAreaNode(t);
84
+ let a = this.normalizeGraph(i);
85
+ this.applyGraphChange(a, "replace", n, r), this.pruneAreaTags(a);
76
86
  }
77
87
  swap(e, t) {
78
88
  if (!this.isOperationEnabled("swap") || !this.graph) return;
79
89
  let n = this.swapAreaIds(this.graph, e, t);
80
- n && (this.graph = n, this.emitLayoutChange(), this.render());
90
+ n && this.applyGraphChange(n, "swap");
81
91
  }
82
92
  move(e, t, n, r) {
83
93
  if (!this.isOperationEnabled("move") || !this.graph) return;
84
94
  let i = this.moveArea(this.graph, e, t, n, r);
85
- i && (this.graph = this.normalizeGraph(i), this.emitLayoutChange(), this.render());
95
+ if (!i) return;
96
+ let a = this.normalizeGraph(i);
97
+ this.applyGraphChange(a, "move");
86
98
  }
87
99
  close(e) {
88
100
  if (!this.graph || !this.graph.areas[e] || Object.keys(this.graph.areas).length <= 1) return;
89
- let t = {
101
+ let t = this.graph, n = new Map(this.areaTags), r = {
90
102
  verts: { ...this.graph.verts },
91
103
  edges: { ...this.graph.edges },
92
104
  areas: { ...this.graph.areas }
93
105
  };
94
- delete t.areas[e], this.graph = this.normalizeGraph(t), this.removeAreaNode(e), this.pruneAreaTags(this.graph), this.emitLayoutChange(), this.render();
106
+ delete r.areas[e], this.removeAreaNode(e);
107
+ let i = this.normalizeGraph(r);
108
+ this.applyGraphChange(i, "close", t, n), this.pruneAreaTags(i);
95
109
  }
96
110
  retag(e, t) {
97
- this.graph && this.graph.areas[e] && this.areaTags.get(e) !== t && (this.areaTags.set(e, t), this.resolvedNodes.delete(e), this.detachAreaNode(e), this.emitLayoutChange(), this.render());
111
+ if (!this.graph || !this.graph.areas[e] || this.areaTags.get(e) === t) return;
112
+ let n = this.graph, r = new Map(this.areaTags);
113
+ this.areaTags.set(e, t), this.resolvedNodes.delete(e), this.detachAreaNode(e), this.applyGraphChange(this.graph, "retag", n, r);
98
114
  }
99
115
  maximize(e) {
100
116
  if (!this.isOperationEnabled("maximize") || !this.graph || this.storedGraph || !this.graph.areas[e]) return;
101
- this.storedGraph = this.graph, this.storedTags = new Map(this.areaTags), this.graph = this.createBaseGraph(e), this.areaTags = /* @__PURE__ */ new Map();
102
- let t = this.storedTags.get(e);
103
- t && this.areaTags.set(e, t), this.emitLayoutChange(), this.render();
117
+ let t = this.graph, n = new Map(this.areaTags);
118
+ this.storedGraph = this.graph, this.storedTags = new Map(this.areaTags);
119
+ let r = this.createBaseGraph(e), i = /* @__PURE__ */ new Map(), a = this.storedTags.get(e);
120
+ a && i.set(e, a), this.areaTags = i, this.applyGraphChange(r, "maximize", t, n);
104
121
  }
105
122
  restore() {
106
- this.isOperationEnabled("restore") && this.storedGraph && (this.graph = this.storedGraph, this.storedTags && (this.areaTags = new Map(this.storedTags)), this.storedGraph = null, this.storedTags = null, this.emitLayoutChange(), this.render());
123
+ if (!this.isOperationEnabled("restore") || !this.storedGraph) return;
124
+ let e = this.graph, t = new Map(this.areaTags), n = this.storedGraph, r = this.storedTags ? new Map(this.storedTags) : /* @__PURE__ */ new Map();
125
+ this.storedGraph = null, this.storedTags = null, this.areaTags = r, this.applyGraphChange(n, "restore", e, t);
107
126
  }
108
127
  ensureRoot() {
109
128
  if (this.rootEl) return;
@@ -126,6 +145,65 @@ var INTERNAL_ATTR = "data-sliced-areas-internal", AUTO_ATTR = "data-sliced-areas
126
145
  emitCornerClick(e) {
127
146
  e.corner === "top-left" && this.dispatchEvent(new CustomEvent("sliced-areas:cornerclick", { detail: e }));
128
147
  }
148
+ calculateLayoutDiff(e, t, n, r) {
149
+ let a = [], o = [], s = [], c = new Set(e ? Object.keys(e.areas) : []), l = new Set(Object.keys(n.areas));
150
+ for (let o of l) {
151
+ if (!c.has(o)) {
152
+ a.push(o);
153
+ continue;
154
+ }
155
+ let l = e.areas[o], u = n.areas[o];
156
+ if (!l || !u) continue;
157
+ let d = this.getAreaRect(e, l), f = this.getAreaRect(n, u), p = t.get(o), m = r.get(o);
158
+ (Math.abs(d.left - f.left) > EPS || Math.abs(d.top - f.top) > EPS || Math.abs(d.right - f.right) > EPS || Math.abs(d.bottom - f.bottom) > EPS || p !== m) && s.push(o);
159
+ }
160
+ for (let e of c) l.has(e) || o.push(e);
161
+ return {
162
+ added: a,
163
+ removed: o,
164
+ updated: s
165
+ };
166
+ }
167
+ applyGraphChange(e, t, n = this.graph, r = new Map(this.areaTags)) {
168
+ if (this.graph = e, n) {
169
+ let i = this.calculateLayoutDiff(n, r, e, this.areaTags);
170
+ for (let e of i.removed) this.resolvedNodes.delete(e);
171
+ for (let e of i.updated) r.get(e) !== this.areaTags.get(e) && this.resolvedNodes.delete(e);
172
+ this.render(), this.emitLayoutChange(), t !== "maximize" && t !== "restore" && this.emitGranularEvents(i, n, r);
173
+ } else this.render();
174
+ }
175
+ emitGranularEvents(e, t, n) {
176
+ if (this.graph) {
177
+ for (let t of e.added) {
178
+ let e = this.graph.areas[t];
179
+ e && this.dispatchEvent(new CustomEvent("sliced-areas:area-added", { detail: {
180
+ areaId: t,
181
+ tag: this.areaTags.get(t) ?? t,
182
+ rect: this.formatRect(this.getAreaRect(this.graph, e))
183
+ } }));
184
+ }
185
+ for (let t of e.removed) this.dispatchEvent(new CustomEvent("sliced-areas:area-removed", { detail: {
186
+ areaId: t,
187
+ tag: n.get(t) ?? t
188
+ } }));
189
+ for (let n of e.updated) {
190
+ let e = this.graph.areas[n];
191
+ if (!e) continue;
192
+ let r = t.areas[n] ? this.getAreaRect(t, t.areas[n]) : {
193
+ left: 0,
194
+ top: 1,
195
+ right: 1,
196
+ bottom: 0
197
+ };
198
+ this.dispatchEvent(new CustomEvent("sliced-areas:area-updated", { detail: {
199
+ areaId: n,
200
+ tag: this.areaTags.get(n) ?? n,
201
+ oldRect: this.formatRect(r),
202
+ newRect: this.formatRect(this.getAreaRect(this.graph, e))
203
+ } }));
204
+ }
205
+ }
206
+ }
129
207
  syncOperations() {
130
208
  let e = new Set(ALL_OPERATIONS), t = /* @__PURE__ */ new Set(), n = (this.operationsConfig.enable ?? []).filter((t) => e.has(t));
131
209
  if (n.length > 0) for (let e of n) t.add(e);
@@ -140,26 +218,61 @@ var INTERNAL_ATTR = "data-sliced-areas-internal", AUTO_ATTR = "data-sliced-areas
140
218
  hasAreaDragOperations() {
141
219
  return this.isOperationEnabled("split") || this.isOperationEnabled("join") || this.isOperationEnabled("move") || this.isOperationEnabled("replace") || this.isOperationEnabled("swap");
142
220
  }
221
+ reconcileAreaWrappers(t) {
222
+ if (!this.rootEl || !this.graph) return;
223
+ let n = this.rootEl.getBoundingClientRect(), r = Math.max(n.width, 1), i = Math.max(n.height, 1), a = DEFAULT_SPLITTER_SIZE / 2, o = /* @__PURE__ */ new Map(), c = this.rootEl.querySelectorAll(".sliced-areas-area");
224
+ for (let e of c) {
225
+ let t = (e.querySelector(".sliced-areas-overlay")?.querySelector(".sliced-areas-corner"))?.getAttribute("data-area-id");
226
+ t && o.set(t, e);
227
+ }
228
+ for (let n of Object.values(this.graph.areas)) {
229
+ let s = this.getAreaRect(this.graph, n), c = s.left * r + a, l = (1 - s.top) * i + a, u = (s.right - s.left) * r - a * 2, d = (s.top - s.bottom) * i - a * 2, f = o.get(n.id);
230
+ if (f) {
231
+ f.style.left = `${c}px`, f.style.top = `${l}px`, f.style.width = `${Math.max(u, 0)}px`, f.style.height = `${Math.max(d, 0)}px`;
232
+ let r = Array.from(f.children).find((t) => !t.hasAttribute(INTERNAL_ATTR)), i = t.get(n.id);
233
+ i && r !== i && (r && r.remove(), f.appendChild(i)), o.delete(n.id);
234
+ continue;
235
+ }
236
+ let p = document.createElement("div");
237
+ p.classList.add("sliced-areas-area"), p.setAttribute(INTERNAL_ATTR, "true"), p.style.left = `${c}px`, p.style.top = `${l}px`, p.style.width = `${Math.max(u, 0)}px`, p.style.height = `${Math.max(d, 0)}px`;
238
+ let m = document.createElement("div");
239
+ m.classList.add("sliced-areas-overlay"), m.setAttribute(INTERNAL_ATTR, "true"), p.appendChild(m);
240
+ for (let t of [
241
+ "top-left",
242
+ "top-right",
243
+ "bottom-left",
244
+ "bottom-right"
245
+ ]) {
246
+ let r = document.createElement("div");
247
+ r.classList.add("sliced-areas-corner"), r.classList.add(`is-${t}`), r.setAttribute(INTERNAL_ATTR, "true"), r.dataset.areaId = n.id, r.dataset.corner = t, m.appendChild(r);
248
+ }
249
+ let h = t.get(n.id);
250
+ if (h) p.appendChild(h);
251
+ else throw Error(`Missing area content for ${n.id}`);
252
+ this.rootEl.appendChild(p);
253
+ }
254
+ for (let [e, t] of o) t.remove();
255
+ }
143
256
  render() {
144
257
  if (!this.rootEl || !this.graph) return;
145
- let n = this.collectAreaNodes();
258
+ let e = this.collectAreaNodes();
146
259
  this.ensureStash(), this.stashEl && (this.stashEl.innerHTML = "");
147
- let r = Object.values(this.graph.areas).filter((e) => !n.has(e.id));
148
- if (r.length > 0 && this.areaResolver) {
149
- for (let e of r) {
150
- let r = this.resolvedNodes.get(e.id);
151
- if (r) {
152
- n.set(e.id, r);
260
+ let n = Object.values(this.graph.areas).filter((t) => !e.has(t.id));
261
+ if (n.length > 0 && this.areaResolver) {
262
+ for (let r of n) {
263
+ let n = this.resolvedNodes.get(r.id);
264
+ if (n) {
265
+ e.set(r.id, n);
153
266
  continue;
154
267
  }
155
- let i = this.areaTags.get(e.id) ?? e.id, a = this.areaResolver(i);
156
- a && (this.assertFreshResolvedNode(e.id, i, a), a.dataset.areaId = e.id, a.setAttribute(AUTO_ATTR, "true"), this.resolvedNodes.set(e.id, a), n.set(e.id, a));
268
+ let i = this.areaTags.get(r.id) ?? r.id, a = this.areaResolver(i);
269
+ a && (this.assertFreshResolvedNode(r.id, i, a), a.dataset.areaId = r.id, a.setAttribute(AUTO_ATTR, "true"), this.resolvedNodes.set(r.id, a), e.set(r.id, a));
157
270
  }
158
- r = Object.values(this.graph.areas).filter((e) => !n.has(e.id));
271
+ n = Object.values(this.graph.areas).filter((t) => !e.has(t.id));
159
272
  }
160
- if (r.length > 0) {
273
+ if (n.length > 0) {
161
274
  let e = {
162
- missing: r.map((e) => e.id),
275
+ missing: n.map((e) => e.id),
163
276
  areas: Object.values(this.graph.areas).map((e) => ({
164
277
  id: e.id,
165
278
  rect: this.formatRect(this.getAreaRect(this.graph, e))
@@ -167,31 +280,13 @@ var INTERNAL_ATTR = "data-sliced-areas-internal", AUTO_ATTR = "data-sliced-areas
167
280
  };
168
281
  throw Error(`Missing area content detected: ${JSON.stringify(e)}`);
169
282
  }
170
- let i = this.rootEl.getBoundingClientRect(), a = Math.max(i.width, 1), o = Math.max(i.height, 1), c = DEFAULT_SPLITTER_SIZE / 2;
171
- this.rootEl.innerHTML = "";
172
- for (let t of Object.values(this.graph.areas)) {
173
- let r = this.getAreaRect(this.graph, t), i = document.createElement("div");
174
- i.classList.add("sliced-areas-area"), i.setAttribute(INTERNAL_ATTR, "true");
175
- let s = r.left * a + c, l = (1 - r.top) * o + c, u = (r.right - r.left) * a - c * 2, d = (r.top - r.bottom) * o - c * 2;
176
- i.style.left = `${s}px`, i.style.top = `${l}px`, i.style.width = `${Math.max(u, 0)}px`, i.style.height = `${Math.max(d, 0)}px`;
177
- let f = document.createElement("div");
178
- f.classList.add("sliced-areas-overlay"), f.setAttribute(INTERNAL_ATTR, "true"), i.appendChild(f);
179
- for (let n of [
180
- "top-left",
181
- "top-right",
182
- "bottom-left",
183
- "bottom-right"
184
- ]) {
185
- let r = document.createElement("div");
186
- r.classList.add("sliced-areas-corner"), r.classList.add(`is-${n}`), r.setAttribute(INTERNAL_ATTR, "true"), r.dataset.areaId = t.id, r.dataset.corner = n, f.appendChild(r);
187
- }
188
- let p = n.get(t.id);
189
- if (p) i.appendChild(p);
190
- else throw Error(`Missing area content for ${t.id}`);
191
- this.rootEl.appendChild(i);
283
+ if (this.reconcileAreaWrappers(e), this.stashEl) for (let [t, n] of e.entries()) this.graph.areas[t] || this.stashEl.appendChild(n);
284
+ let r = this.rootEl.querySelectorAll(".sliced-areas-handle");
285
+ for (let e of r) e.remove();
286
+ if (this.isOperationEnabled("resize")) {
287
+ let e = this.rootEl.getBoundingClientRect(), t = Math.max(e.width, 1), n = Math.max(e.height, 1);
288
+ for (let e of this.buildResizeHandles(this.graph, t, n)) this.rootEl.appendChild(e);
192
289
  }
193
- if (this.stashEl) for (let [e, t] of n.entries()) this.graph.areas[e] || this.stashEl.appendChild(t);
194
- if (this.isOperationEnabled("resize")) for (let e of this.buildResizeHandles(this.graph, a, o)) this.rootEl.appendChild(e);
195
290
  }
196
291
  collectAreaNodes() {
197
292
  let n = /* @__PURE__ */ new Map(), r = Array.from(this.querySelectorAll("[data-area-id]"));
@@ -241,21 +336,42 @@ var INTERNAL_ATTR = "data-sliced-areas-internal", AUTO_ATTR = "data-sliced-areas
241
336
  }
242
337
  this.areaTags.set(e, t);
243
338
  }
244
- buildGraphFromLayout(e) {
245
- this.areaTags.clear();
246
- let t = [];
247
- for (let n of e.areas) {
248
- let e = this.nextAreaId();
249
- t.push({
339
+ assignAreaIds(e) {
340
+ let t = /* @__PURE__ */ new Set(), n = [];
341
+ for (let r of e.areas) {
342
+ let e;
343
+ if (r.id) {
344
+ if (t.has(r.id)) throw Error(`Duplicate area ID: ${r.id}`);
345
+ e = r.id;
346
+ let n = /^area-(\d+)$/.exec(e);
347
+ if (n) {
348
+ /* v8 ignore next */
349
+ let e = Number.parseInt(n[1] ?? "0", 10);
350
+ /* v8 ignore next */
351
+ e >= this.areaCounter && (this.areaCounter = e);
352
+ }
353
+ } else e = this.nextAreaId();
354
+ t.add(e), n.push({
250
355
  id: e,
251
- rect: n.rect
252
- }), this.areaTags.set(e, n.tag);
356
+ tag: r.tag,
357
+ rect: r.rect
358
+ });
253
359
  }
254
- let n = this.buildGraphFromRects(t);
255
- return this.normalizeGraph(n);
360
+ return n;
361
+ }
362
+ buildGraphFromLayout(e) {
363
+ this.areaTags.clear();
364
+ let t = this.assignAreaIds(e), n = [];
365
+ for (let e of t) n.push({
366
+ id: e.id,
367
+ rect: e.rect
368
+ }), this.areaTags.set(e.id, e.tag);
369
+ let r = this.buildGraphFromRects(n);
370
+ return this.normalizeGraph(r);
256
371
  }
257
372
  serializeLayout(e) {
258
373
  return { areas: Object.values(e.areas).map((t) => ({
374
+ id: t.id,
259
375
  tag: this.areaTags.get(t.id) ?? t.id,
260
376
  rect: this.formatRect(this.getAreaRect(e, t))
261
377
  })) };
@@ -726,7 +842,7 @@ var INTERNAL_ATTR = "data-sliced-areas-internal", AUTO_ATTR = "data-sliced-areas
726
842
  }
727
843
  if (!this.rootEl || !this.graph || !this.dragState) return;
728
844
  let t = this.rootEl.getBoundingClientRect(), n = Math.max(t.width, 1), r = Math.max(t.height, 1), i = e.clientX - this.dragState.originX, a = e.clientY - this.dragState.originY, o = this.dragState.axis === "vertical" ? i / n : -a / r, s = Math.max(this.dragState.min, Math.min(this.dragState.max, this.dragState.coord + o)), c = this.moveEdge(this.graph, this.dragState.axis, this.dragState.coord, s, this.dragState.start, this.dragState.end);
729
- c && (this.graph = c, this.dragState.coord = s, this.dragState.originX = e.clientX, this.dragState.originY = e.clientY, this.render());
845
+ c && (this.applyGraphChange(c, "resize"), this.dragState.coord = s, this.dragState.originX = e.clientX, this.dragState.originY = e.clientY);
730
846
  };
731
847
  onPointerUp = (e) => {
732
848
  if (this.areaDragState) {
@@ -739,7 +855,10 @@ var INTERNAL_ATTR = "data-sliced-areas-internal", AUTO_ATTR = "data-sliced-areas
739
855
  }), this.finishAreaDrag();
740
856
  return;
741
857
  }
742
- this.dragState && (this.dragState = null, this.detachDragListeners(), this.detachKeyListener(), this.dragSnapshot = null, this.graph &&= this.normalizeGraph(this.graph), this.emitLayoutChange());
858
+ if (this.dragState && (this.dragState = null, this.detachDragListeners(), this.detachKeyListener(), this.dragSnapshot = null, this.graph)) {
859
+ let e = this.normalizeGraph(this.graph);
860
+ e !== this.graph && (this.graph = e, this.render());
861
+ }
743
862
  };
744
863
  onKeyDown = (e) => {
745
864
  if (e.key === "Control") {
@@ -1789,4 +1908,4 @@ const registerSlicedAreasElement = () => {
1789
1908
  registerSlicedAreasElement();
1790
1909
  export { registerSlicedAreasElement as n, SlicedAreasElement as t };
1791
1910
 
1792
- //# sourceMappingURL=sliced-areas-C43gYU0G.js.map
1911
+ //# sourceMappingURL=sliced-areas-BnxGgD6W.js.map