@oicl/openbridge-webcomponents 2.0.0-next.170 → 2.0.0-next.171

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 (54) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +870 -441
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +1333 -392
  4. package/dist/ar/poi/poi-aton.d.ts +1 -0
  5. package/dist/ar/poi/poi-aton.d.ts.map +1 -1
  6. package/dist/ar/poi/poi-aton.js +1 -0
  7. package/dist/ar/poi/poi-aton.js.map +1 -1
  8. package/dist/ar/poi/poi-base.d.ts +39 -5
  9. package/dist/ar/poi/poi-base.d.ts.map +1 -1
  10. package/dist/ar/poi/poi-base.js +108 -37
  11. package/dist/ar/poi/poi-base.js.map +1 -1
  12. package/dist/ar/poi/poi-data.d.ts +1 -0
  13. package/dist/ar/poi/poi-data.d.ts.map +1 -1
  14. package/dist/ar/poi/poi-data.js +1 -0
  15. package/dist/ar/poi/poi-data.js.map +1 -1
  16. package/dist/ar/poi/poi-vessel.d.ts +1 -0
  17. package/dist/ar/poi/poi-vessel.d.ts.map +1 -1
  18. package/dist/ar/poi/poi-vessel.js +1 -0
  19. package/dist/ar/poi/poi-vessel.js.map +1 -1
  20. package/dist/ar/poi/poi.d.ts +4 -12
  21. package/dist/ar/poi/poi.d.ts.map +1 -1
  22. package/dist/ar/poi/poi.js +6 -72
  23. package/dist/ar/poi/poi.js.map +1 -1
  24. package/dist/ar/poi-button/poi-button.d.ts +6 -2
  25. package/dist/ar/poi-button/poi-button.d.ts.map +1 -1
  26. package/dist/ar/poi-button/poi-button.js +10 -1
  27. package/dist/ar/poi-button/poi-button.js.map +1 -1
  28. package/dist/ar/poi-card/poi-card.d.ts +12 -1
  29. package/dist/ar/poi-card/poi-card.d.ts.map +1 -1
  30. package/dist/ar/poi-card/poi-card.js +4 -1
  31. package/dist/ar/poi-card/poi-card.js.map +1 -1
  32. package/dist/ar/poi-controller/poi-controller.d.ts +45 -1
  33. package/dist/ar/poi-controller/poi-controller.d.ts.map +1 -1
  34. package/dist/ar/poi-controller/poi-controller.js +72 -14
  35. package/dist/ar/poi-controller/poi-controller.js.map +1 -1
  36. package/dist/ar/poi-group/poi-group.d.ts +28 -5
  37. package/dist/ar/poi-group/poi-group.d.ts.map +1 -1
  38. package/dist/ar/poi-group/poi-group.js +50 -7
  39. package/dist/ar/poi-group/poi-group.js.map +1 -1
  40. package/dist/ar/poi-layer/poi-layer.css.js +69 -18
  41. package/dist/ar/poi-layer/poi-layer.css.js.map +1 -1
  42. package/dist/ar/poi-layer/poi-layer.d.ts +64 -5
  43. package/dist/ar/poi-layer/poi-layer.d.ts.map +1 -1
  44. package/dist/ar/poi-layer/poi-layer.js +173 -39
  45. package/dist/ar/poi-layer/poi-layer.js.map +1 -1
  46. package/dist/ar/poi-layer-stack/poi-layer-stack.d.ts +82 -7
  47. package/dist/ar/poi-layer-stack/poi-layer-stack.d.ts.map +1 -1
  48. package/dist/ar/poi-layer-stack/poi-layer-stack.js +172 -100
  49. package/dist/ar/poi-layer-stack/poi-layer-stack.js.map +1 -1
  50. package/dist/ar/poi-projection/poi-projection.d.ts +88 -0
  51. package/dist/ar/poi-projection/poi-projection.d.ts.map +1 -0
  52. package/dist/ar/poi-projection/poi-projection.js +90 -0
  53. package/dist/ar/poi-projection/poi-projection.js.map +1 -0
  54. package/package.json +2 -2
@@ -29,6 +29,7 @@ var ObcPoiLayerStack = class ObcPoiLayerStack extends LitElement {
29
29
  this.handleTargetLayoutChange = () => this.schedulePlacement();
30
30
  this.handleLayerSelectionChanged = () => this.schedulePlacement();
31
31
  this.selectionMap = /* @__PURE__ */ new Map();
32
+ this.displacedTargets = /* @__PURE__ */ new Map();
32
33
  this.selectionCounter = 0;
33
34
  this.placementRaf = 0;
34
35
  }
@@ -70,6 +71,11 @@ var ObcPoiLayerStack = class ObcPoiLayerStack extends LitElement {
70
71
  this.requestPoiRender(target);
71
72
  });
72
73
  this.selectionMap.clear();
74
+ this.displacedTargets.forEach((_, target) => {
75
+ this.clearTargetProjectionStyles(target);
76
+ this.requestPoiRender(target);
77
+ });
78
+ this.displacedTargets.clear();
73
79
  this.selectionCounter = 0;
74
80
  }
75
81
  onStackClick(event) {
@@ -78,25 +84,81 @@ var ObcPoiLayerStack = class ObcPoiLayerStack extends LitElement {
78
84
  if (!target) return;
79
85
  if (target.hasAttribute(_ObcPoiLayerStack.STACK_RETURNING_ATTR)) return;
80
86
  this.cleanupSelection();
81
- const originLayer = this.getTargetLayer(target);
82
- if (!originLayer) return;
83
- const selectedLayer = this.getLayer("selected") ?? this.getLayer("top");
84
- if (!selectedLayer) return;
85
87
  const existing = this.selectionMap.get(target);
86
88
  if (existing) {
87
89
  this.resetSelectionForTarget(target, existing);
88
90
  return;
89
91
  }
92
+ this.performSelection(target);
93
+ }
94
+ /** Currently selected POI targets. */
95
+ get selectedTargets() {
96
+ this.cleanupSelection();
97
+ return Array.from(this.selectionMap.keys());
98
+ }
99
+ /**
100
+ * Programmatically select a target, following the same flow as a user
101
+ * click. `options.selectionId` presets the badge id shown in the
102
+ * stack-managed header; without it the id auto-increments. Returns
103
+ * `false` when selection is disabled, the target is mid-transition or
104
+ * already selected, or no layer can host the selection.
105
+ */
106
+ selectTarget(target, options) {
107
+ if (this.selectionMode === "none") return false;
108
+ if (target.hasAttribute(_ObcPoiLayerStack.STACK_RETURNING_ATTR)) return false;
109
+ this.cleanupSelection();
110
+ if (this.selectionMap.has(target)) return false;
111
+ return this.performSelection(target, options?.selectionId);
112
+ }
113
+ /**
114
+ * Programmatically deselect a target. Returns `false` when it is not
115
+ * selected.
116
+ */
117
+ deselectTarget(target) {
118
+ const record = this.selectionMap.get(target);
119
+ if (!record) return false;
120
+ this.resetSelectionForTarget(target, record);
121
+ return true;
122
+ }
123
+ /** Deselect all targets. */
124
+ clearSelection() {
125
+ Array.from(this.selectionMap.entries()).forEach(([target, record]) => {
126
+ this.resetSelectionForTarget(target, record);
127
+ });
128
+ }
129
+ performSelection(target, selectionId) {
130
+ const homeLayer = this.getTargetLayer(target);
131
+ if (!homeLayer) return false;
132
+ const selectedLayer = this.getLayer("selected") ?? this.getLayer("top");
133
+ if (!selectedLayer) return false;
90
134
  if (this.selectionMode === "single") {
91
135
  this.clearOtherTopSelections(target);
92
136
  this.clearSelectionMapExcept(target);
93
137
  }
94
- const trackedOriginLayer = originLayer === selectedLayer ? this.inferBootstrapOriginLayer(target, selectedLayer) : originLayer;
95
- this.trackSelectionTarget(target, trackedOriginLayer, true);
96
- const record = this.selectionMap.get(target);
97
- if (!record) return;
138
+ const displaced = this.displacedTargets.get(target);
139
+ this.displacedTargets.delete(target);
140
+ const originLayer = displaced?.originLayer ?? (homeLayer === selectedLayer ? this.inferBootstrapOriginLayer(target, selectedLayer) : homeLayer);
141
+ if (selectionId) target.setAttribute("data-stack-selection-id", selectionId);
142
+ const record = {
143
+ homeLayer,
144
+ originLayer
145
+ };
146
+ this.selectionMap.set(target, record);
98
147
  this.activateTrackedTarget(target, record, selectedLayer);
99
148
  this.schedulePlacement();
149
+ this.dispatchSelectionChange(target, null);
150
+ return true;
151
+ }
152
+ dispatchSelectionChange(added, removed) {
153
+ this.dispatchEvent(new CustomEvent("selection-change", {
154
+ detail: {
155
+ selected: this.selectedTargets,
156
+ added,
157
+ removed
158
+ },
159
+ bubbles: true,
160
+ composed: true
161
+ }));
100
162
  }
101
163
  getPoiTargetFromEvent(event) {
102
164
  const path = event.composedPath?.() ?? [];
@@ -123,6 +185,9 @@ var ObcPoiLayerStack = class ObcPoiLayerStack extends LitElement {
123
185
  this.selectionMap.forEach((_, target) => {
124
186
  if (!target.isConnected) this.selectionMap.delete(target);
125
187
  });
188
+ this.displacedTargets.forEach((_, target) => {
189
+ if (!target.isConnected) this.displacedTargets.delete(target);
190
+ });
126
191
  }
127
192
  getLayer(kind) {
128
193
  const layers = this.getAllLayers();
@@ -142,6 +207,7 @@ var ObcPoiLayerStack = class ObcPoiLayerStack extends LitElement {
142
207
  if (!activeLayer) return;
143
208
  this.getLayerTargets(activeLayer).forEach((other) => {
144
209
  if (other === target) return;
210
+ if (this.displacedTargets.has(other)) return;
145
211
  const record = this.selectionMap.get(other);
146
212
  this.resetSelectionForTarget(other, record);
147
213
  });
@@ -199,25 +265,60 @@ var ObcPoiLayerStack = class ObcPoiLayerStack extends LitElement {
199
265
  refreshTargetProjectionLayout(target, trackDurationMs = 0) {
200
266
  target.refreshProjectionLayout?.(trackDurationMs);
201
267
  }
202
- getTargetButtonProjectionOffset(target) {
203
- const raw = target.style.getPropertyValue("--obc-poi-button-projection-y");
268
+ getInlineVarPx(target, name) {
269
+ const raw = target.style.getPropertyValue(name);
204
270
  const parsed = Number.parseFloat(raw);
205
271
  return Number.isFinite(parsed) ? parsed : 0;
206
272
  }
207
- getLayerProjectionOffset(originLayer, destinationLayer) {
208
- if (!destinationLayer || destinationLayer === originLayer) return 0;
209
- const originRect = originLayer.getBoundingClientRect();
210
- return destinationLayer.getBoundingClientRect().bottom - originRect.bottom;
273
+ /** Pixel delta between two layers' bottom edges (`to.bottom - from.bottom`). */
274
+ layerBottomDelta(from, to) {
275
+ if (from === to) return 0;
276
+ return to.getBoundingClientRect().bottom - from.getBoundingClientRect().bottom;
211
277
  }
212
- getTargetProjectionOffset(originLayer, selectedLayer) {
213
- if (!selectedLayer || selectedLayer === originLayer) return 0;
214
- const originRect = originLayer.getBoundingClientRect();
215
- const selectedRect = selectedLayer.getBoundingClientRect();
216
- return originRect.bottom - selectedRect.bottom;
278
+ setProjectionVar(target, name, valuePx) {
279
+ if (Math.abs(valuePx) < .5) target.style.removeProperty(name);
280
+ else target.style.setProperty(name, `${valuePx}px`);
281
+ }
282
+ /**
283
+ * Render the target at the given projection offsets without touching its
284
+ * DOM position. When `animate` is set and an offset actually changes, the
285
+ * jump is FLIP-animated via the Web Animations API.
286
+ */
287
+ async applyTargetProjection(target, buttonOffsetPx, targetOffsetPx, animate) {
288
+ const currentButton = this.getInlineVarPx(target, "--obc-poi-button-projection-y");
289
+ const currentTarget = this.getInlineVarPx(target, "--obc-poi-target-projection-y");
290
+ if (!(Math.abs(buttonOffsetPx - currentButton) >= .5 || Math.abs(targetOffsetPx - currentTarget) >= .5)) {
291
+ this.setProjectionVar(target, "--obc-poi-button-projection-y", buttonOffsetPx);
292
+ this.setProjectionVar(target, "--obc-poi-target-projection-y", targetOffsetPx);
293
+ this.requestPoiRender(target);
294
+ this.refreshTargetProjectionLayout(target);
295
+ return;
296
+ }
297
+ const { button, line } = this.getAnimationElements(target);
298
+ const beforeButtonRect = animate ? button?.getBoundingClientRect() ?? null : null;
299
+ const beforeLineRect = animate ? line?.getBoundingClientRect() ?? null : null;
300
+ this.setProjectionVar(target, "--obc-poi-button-projection-y", buttonOffsetPx);
301
+ this.setProjectionVar(target, "--obc-poi-target-projection-y", targetOffsetPx);
302
+ this.requestPoiRender(target);
303
+ this.refreshTargetProjectionLayout(target);
304
+ if (!animate) return;
305
+ await this.waitForPoiRender(target);
306
+ await this.animateLayerJump(target, beforeButtonRect, beforeLineRect);
307
+ }
308
+ /**
309
+ * The group a target currently belongs to — a light-DOM parent for
310
+ * consumer-managed groups, or the shadow group whose member slot the
311
+ * target is assigned to for layer-created auto groups.
312
+ */
313
+ getContainingGroup(target) {
314
+ if (target.parentElement?.tagName.toLowerCase() === "obc-poi-group") return target.parentElement;
315
+ const slotParent = target.assignedSlot?.parentElement;
316
+ if (slotParent?.tagName.toLowerCase() === "obc-poi-group") return slotParent;
317
+ return null;
217
318
  }
218
319
  detachTargetFromCurrentGroup(target) {
219
320
  const currentLayer = this.getTargetLayer(target);
220
- const sourceGroup = target.parentElement?.tagName.toLowerCase() === "obc-poi-group" ? target.parentElement : null;
321
+ const sourceGroup = this.getContainingGroup(target);
221
322
  if (!sourceGroup) return currentLayer;
222
323
  target.setRuntimeHorizontalOffsets?.(0, 0);
223
324
  if (!target.setRuntimeHorizontalOffsets) {
@@ -304,73 +405,34 @@ var ObcPoiLayerStack = class ObcPoiLayerStack extends LitElement {
304
405
  animations.forEach((a) => a.cancel());
305
406
  }
306
407
  }
307
- async moveTargetIntoSelectedLayer(target, _originLayer, selectedLayer, animate = true) {
308
- const { button, line } = this.getAnimationElements(target);
309
- const beforeButtonRect = button?.getBoundingClientRect() ?? null;
310
- const beforeLineRect = line?.getBoundingClientRect() ?? null;
311
- if (this.getTargetLayer(target) !== selectedLayer) selectedLayer.appendChild(target);
312
- this.requestPoiRender(target);
313
- this.refreshTargetProjectionLayout(target);
314
- await this.waitForPoiRender(target);
315
- if (!animate) return;
316
- await this.animateLayerJump(target, beforeButtonRect, beforeLineRect);
317
- }
318
- async moveTrackedTargetToSelectedLayer(target, record, selectedLayer, animateProjection) {
319
- const currentLayer = this.detachTargetFromCurrentGroup(target) ?? this.getTargetLayer(target) ?? record.originLayer;
320
- clearTargetGroupingAttributes(target);
321
- await this.moveTargetIntoSelectedLayer(target, record.originLayer, selectedLayer, animateProjection);
322
- if (currentLayer !== selectedLayer) currentLayer.requestGroupingUpdate();
323
- selectedLayer.requestGroupingUpdate();
324
- }
325
- async syncTargetProjection(target, originLayer, selectedLayer, animate = true) {
326
- const nextProjectionOffset = this.getLayerProjectionOffset(originLayer, selectedLayer);
327
- const currentProjectionOffset = this.getTargetButtonProjectionOffset(target);
328
- if (Math.abs(nextProjectionOffset - currentProjectionOffset) < .5) {
329
- if (Math.abs(nextProjectionOffset) < .5) target.style.removeProperty("--obc-poi-button-projection-y");
330
- else target.style.setProperty("--obc-poi-button-projection-y", `${nextProjectionOffset}px`);
331
- this.requestPoiRender(target);
332
- this.refreshTargetProjectionLayout(target);
333
- return;
334
- }
335
- if (Math.abs(nextProjectionOffset) < .5) target.style.removeProperty("--obc-poi-button-projection-y");
336
- else target.style.setProperty("--obc-poi-button-projection-y", `${nextProjectionOffset}px`);
337
- this.requestPoiRender(target);
338
- if (animate) {
339
- this.refreshTargetProjectionLayout(target, _ObcPoiLayerStack.STACK_JUMP_DURATION_MS);
340
- await this.waitForPoiRender(target);
341
- return;
342
- }
343
- this.refreshTargetProjectionLayout(target);
344
- }
345
408
  async animateTargetReturnToOrigin(target, record) {
346
409
  target.setAttribute(_ObcPoiLayerStack.STACK_RETURNING_ATTR, "true");
347
410
  try {
348
- const currentLayer = this.detachTargetFromCurrentGroup(target) ?? this.getTargetLayer(target);
411
+ const sourceGroupLayer = this.detachTargetFromCurrentGroup(target);
349
412
  clearTargetGroupingAttributes(target);
350
- const { button: beforeBtn, line: beforeLine } = this.getAnimationElements(target);
351
- const beforeButtonRect = beforeBtn?.getBoundingClientRect() ?? null;
352
- const beforeLineRect = beforeLine?.getBoundingClientRect() ?? null;
353
- target.style.removeProperty("--obc-poi-target-projection-y");
354
- target.style.removeProperty("--obc-poi-button-projection-y");
355
- if (target.parentElement !== record.originLayer) record.originLayer.appendChild(target);
356
- this.requestPoiRender(target);
357
- this.refreshTargetProjectionLayout(target);
358
- await this.waitForPoiRender(target);
359
- await this.animateLayerJump(target, beforeButtonRect, beforeLineRect);
413
+ const originOffset = this.layerBottomDelta(record.homeLayer, record.originLayer);
414
+ await this.applyTargetProjection(target, originOffset, originOffset, true);
360
415
  this.setSelectedTargetInteractivity(target, false);
361
416
  clearTargetGroupingAttributes(target);
362
417
  this.clearTargetSelectedId(target);
363
- this.clearTargetProjectionStyles(target);
418
+ if (record.homeLayer === record.originLayer) this.clearTargetProjectionStyles(target);
419
+ else {
420
+ target.style.removeProperty("--obc-poi-forced-target-transition-duration");
421
+ target.style.removeProperty("--obc-poi-layer-inactive-opacity");
422
+ target.style.removeProperty("z-index");
423
+ this.displacedTargets.set(target, record);
424
+ }
364
425
  this.requestPoiRender(target);
365
- if (currentLayer && currentLayer !== record.originLayer) currentLayer.requestGroupingUpdate();
366
- record.originLayer.requestGroupingUpdate();
426
+ if (sourceGroupLayer && sourceGroupLayer !== record.homeLayer) sourceGroupLayer.requestGroupingUpdate();
427
+ record.homeLayer.requestGroupingUpdate();
367
428
  this.schedulePlacement();
368
429
  } finally {
369
430
  target.removeAttribute(_ObcPoiLayerStack.STACK_RETURNING_ATTR);
431
+ target.removeAttribute("data-stack-selected");
370
432
  }
371
433
  }
372
434
  setSelectedTargetInteractivity(target, selected) {
373
- const isInAutoGroup = target.hasAttribute("data-grouped") || target.closest("obc-poi-group") !== null;
435
+ const isInAutoGroup = target.hasAttribute("data-grouped") || this.getContainingGroup(target) !== null;
374
436
  target.selected = selected;
375
437
  if (selected) {
376
438
  target.style.setProperty("--obc-poi-overlap-pointer-events", "auto");
@@ -385,30 +447,22 @@ var ObcPoiLayerStack = class ObcPoiLayerStack extends LitElement {
385
447
  target.removeAttribute("data-front");
386
448
  }
387
449
  }
388
- trackSelectionTarget(target, originLayer, keepInSelectedLayer = true) {
389
- this.selectionMap.set(target, {
390
- originLayer,
391
- previousAnimatePosition: target.animatePosition ?? false,
392
- keepInSelectedLayer
393
- });
394
- target.removeAttribute("data-stack-selected");
395
- }
396
450
  activateTrackedTarget(target, record, selectedLayer, animateProjection = true) {
397
- if (record.keepInSelectedLayer) {
398
- target.removeAttribute("data-stack-selected");
399
- if (this.getTargetLayer(target) !== selectedLayer) this.moveTrackedTargetToSelectedLayer(target, record, selectedLayer, animateProjection);
400
- else {
401
- const targetProjectionOffset = this.getTargetProjectionOffset(record.originLayer, selectedLayer);
402
- if (Math.abs(targetProjectionOffset) < .5) target.style.removeProperty("--obc-poi-target-projection-y");
403
- else target.style.setProperty("--obc-poi-target-projection-y", `${targetProjectionOffset}px`);
404
- target.style.removeProperty("--obc-poi-button-projection-y");
405
- this.requestPoiRender(target);
406
- this.refreshTargetProjectionLayout(target);
407
- }
408
- } else {
451
+ if (record.homeLayer !== selectedLayer) {
452
+ const sourceGroupLayer = this.detachTargetFromCurrentGroup(target);
409
453
  clearTargetGroupingAttributes(target);
454
+ const firstActivation = !target.hasAttribute("data-stack-selected");
410
455
  target.setAttribute("data-stack-selected", "true");
411
- this.syncTargetProjection(target, record.originLayer, selectedLayer, animateProjection);
456
+ const buttonOffset = this.layerBottomDelta(record.homeLayer, selectedLayer);
457
+ const targetOffset = this.layerBottomDelta(record.homeLayer, record.originLayer);
458
+ this.applyTargetProjection(target, buttonOffset, targetOffset, animateProjection);
459
+ if (firstActivation) {
460
+ if (sourceGroupLayer && sourceGroupLayer !== record.homeLayer) sourceGroupLayer.requestGroupingUpdate();
461
+ record.homeLayer.requestGroupingUpdate();
462
+ }
463
+ } else {
464
+ const targetOffset = this.layerBottomDelta(selectedLayer, record.originLayer);
465
+ this.applyTargetProjection(target, 0, targetOffset, animateProjection);
412
466
  }
413
467
  this.setSelectedTargetInteractivity(target, true);
414
468
  this.setTargetSelectedId(target);
@@ -421,25 +475,26 @@ var ObcPoiLayerStack = class ObcPoiLayerStack extends LitElement {
421
475
  for (const target of selectedTargets) {
422
476
  if (target.hasAttribute(_ObcPoiLayerStack.STACK_RETURNING_ATTR)) continue;
423
477
  if (this.selectionMap.has(target)) continue;
478
+ if (this.displacedTargets.has(target)) continue;
424
479
  if (this.selectionMode === "single" && this.selectionMap.size > 0) break;
425
480
  const originLayer = this.inferBootstrapOriginLayer(target, selectedLayer);
426
481
  this.selectionMap.set(target, {
427
- originLayer,
428
- previousAnimatePosition: target.animatePosition ?? false,
429
- keepInSelectedLayer: true
482
+ homeLayer: selectedLayer,
483
+ originLayer
430
484
  });
431
- target.removeAttribute("data-stack-selected");
432
485
  seededTargets.add(target);
486
+ this.dispatchSelectionChange(target, null);
433
487
  }
434
488
  return seededTargets;
435
489
  }
436
490
  resetSelectionForTarget(target, record) {
437
- target.removeAttribute("data-stack-selected");
438
491
  if (record) {
439
492
  this.selectionMap.delete(target);
440
493
  this.animateTargetReturnToOrigin(target, record);
494
+ this.dispatchSelectionChange(null, target);
441
495
  return;
442
496
  }
497
+ target.removeAttribute("data-stack-selected");
443
498
  this.setSelectedTargetInteractivity(target, false);
444
499
  clearTargetGroupingAttributes(target);
445
500
  this.clearTargetSelectedId(target);
@@ -504,6 +559,7 @@ var ObcPoiLayerStack = class ObcPoiLayerStack extends LitElement {
504
559
  this.selectionMap.forEach((record, target) => {
505
560
  this.resetSelectionForTarget(target, record);
506
561
  });
562
+ this.refreshDisplacedTargets();
507
563
  return;
508
564
  }
509
565
  const seededTargets = this.seedSelectedLayerSelections(selectedLayer);
@@ -513,9 +569,25 @@ var ObcPoiLayerStack = class ObcPoiLayerStack extends LitElement {
513
569
  return;
514
570
  }
515
571
  if (target.hasAttribute(_ObcPoiLayerStack.STACK_RETURNING_ATTR)) return;
516
- if (!record.keepInSelectedLayer && !target.hasAttribute("data-stack-selected")) target.setAttribute("data-stack-selected", "true");
517
572
  this.activateTrackedTarget(target, record, selectedLayer, !seededTargets.has(target));
518
573
  });
574
+ this.refreshDisplacedTargets();
575
+ }
576
+ /**
577
+ * Keep deselected targets that render outside their DOM layer (targets
578
+ * authored in the selected layer whose logical origin is another layer)
579
+ * projected at up-to-date offsets across layer resizes.
580
+ */
581
+ refreshDisplacedTargets() {
582
+ this.displacedTargets.forEach((record, target) => {
583
+ if (!target.isConnected) {
584
+ this.displacedTargets.delete(target);
585
+ return;
586
+ }
587
+ if (target.hasAttribute(_ObcPoiLayerStack.STACK_RETURNING_ATTR)) return;
588
+ const originOffset = this.layerBottomDelta(record.homeLayer, record.originLayer);
589
+ this.applyTargetProjection(target, originOffset, originOffset, false);
590
+ });
519
591
  }
520
592
  render() {
521
593
  return html`
@@ -1 +1 @@
1
- {"version":3,"file":"poi-layer-stack.js","names":[],"sources":["../../../src/ar/poi-layer-stack/poi-layer-stack.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {customElement} from '../../decorator.js';\nimport componentStyle from './poi-layer-stack.css?inline';\n\nimport '../poi-layer/poi-layer.js';\nimport '../poi-group/poi-group.js';\nimport '../poi/poi-data.js';\nimport '../building-blocks/poi-header/poi-header.js';\n\nimport type {ObcPoiLayer} from '../poi-layer/poi-layer.js';\nimport type {ObcPoiGroup} from '../poi-group/poi-group.js';\nimport {PoiDataValue} from '../poi/poi-data.js';\nimport {Poi, isPoi, POI_ATTR} from '../poi/poi.js';\nimport {\n clearTargetGroupingAttributes,\n clearTargetGroupingStyles,\n} from '../poi/poi-grouping-attrs.js';\n\nexport enum PoiLayerSelectionMode {\n None = 'none',\n Single = 'single',\n Multi = 'multi',\n}\n\n/**\n * `<obc-poi-layer-stack>` coordinates multiple POI layers and manages\n * selection behavior across stacked layers.\n *\n * Use `selection-mode` to control whether targets can be selected across the\n * stack (`none`, `single`, or `multi`).\n *\n * ### Slots\n * - Default slot for `obc-poi-layer` elements that participate in the stack.\n *\n * ### Example\n * ```html\n * <obc-poi-layer-stack selection-mode=\"single\">\n * <obc-poi-layer label=\"Radar\" .isSelected=${true}></obc-poi-layer>\n * <obc-poi-layer label=\"AIS\"></obc-poi-layer>\n * </obc-poi-layer-stack>\n * ```\n *\n * @slot - Layers participating in the stack.\n * @experimental\n */\n@customElement('obc-poi-layer-stack')\nexport class ObcPoiLayerStack extends LitElement {\n private static readonly STACK_JUMP_DURATION_MS = 100;\n private static readonly STACK_RETURNING_ATTR = 'data-stack-returning';\n\n @property({type: String, attribute: 'selection-mode'})\n selectionMode: PoiLayerSelectionMode = PoiLayerSelectionMode.None;\n\n private handleStackClick = (event: Event) => this.onStackClick(event);\n private handleSlotChange = () => this.schedulePlacement();\n private handleTargetLayoutChange = () => this.schedulePlacement();\n private handleLayerSelectionChanged = () => this.schedulePlacement();\n private selectionMap = new Map<\n Poi,\n {\n originLayer: ObcPoiLayer;\n previousAnimatePosition: boolean;\n keepInSelectedLayer: boolean;\n }\n >();\n private selectionCounter = 0;\n private placementRaf = 0;\n private mutationObserver?: MutationObserver;\n\n override connectedCallback() {\n super.connectedCallback();\n this.addEventListener('click', this.handleStackClick);\n this.addEventListener(\n 'obc-poi-data-layout-change',\n this.handleTargetLayoutChange as EventListener\n );\n this.addEventListener(\n 'layer-selection-changed',\n this.handleLayerSelectionChanged\n );\n }\n\n override firstUpdated() {\n const slot = this.shadowRoot?.querySelector('slot');\n slot?.addEventListener('slotchange', this.handleSlotChange);\n this.setupMutationObserver();\n this.schedulePlacement();\n requestAnimationFrame(() => {\n this.schedulePlacement();\n requestAnimationFrame(() => this.schedulePlacement());\n });\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('click', this.handleStackClick);\n this.removeEventListener(\n 'obc-poi-data-layout-change',\n this.handleTargetLayoutChange as EventListener\n );\n this.removeEventListener(\n 'layer-selection-changed',\n this.handleLayerSelectionChanged\n );\n const slot = this.shadowRoot?.querySelector('slot');\n slot?.removeEventListener('slotchange', this.handleSlotChange);\n this.mutationObserver?.disconnect();\n this.mutationObserver = undefined;\n if (this.placementRaf) {\n cancelAnimationFrame(this.placementRaf);\n this.placementRaf = 0;\n }\n this.selectionMap.forEach((_, target) => {\n this.clearTargetProjectionStyles(target);\n this.requestPoiRender(target);\n });\n this.selectionMap.clear();\n this.selectionCounter = 0;\n }\n\n private onStackClick(event: Event) {\n if (this.selectionMode === PoiLayerSelectionMode.None) return;\n const target = this.getPoiTargetFromEvent(event);\n if (!target) return;\n if (target.hasAttribute(ObcPoiLayerStack.STACK_RETURNING_ATTR)) return;\n\n this.cleanupSelection();\n const originLayer = this.getTargetLayer(target);\n if (!originLayer) return;\n\n const selectedLayer = this.getLayer('selected') ?? this.getLayer('top');\n if (!selectedLayer) return;\n\n const existing = this.selectionMap.get(target);\n if (existing) {\n this.resetSelectionForTarget(target, existing);\n return;\n }\n\n if (this.selectionMode === PoiLayerSelectionMode.Single) {\n this.clearOtherTopSelections(target);\n this.clearSelectionMapExcept(target);\n }\n\n const trackedOriginLayer =\n originLayer === selectedLayer\n ? this.inferBootstrapOriginLayer(target, selectedLayer)\n : originLayer;\n\n this.trackSelectionTarget(target, trackedOriginLayer, true);\n const record = this.selectionMap.get(target);\n if (!record) return;\n this.activateTrackedTarget(target, record, selectedLayer);\n this.schedulePlacement();\n }\n\n private getPoiTargetFromEvent(event: Event): Poi | null {\n const path = event.composedPath?.() ?? [];\n for (const item of path) {\n if (item instanceof HTMLElement && isPoi(item)) {\n return item as Poi;\n }\n }\n const direct = event.target instanceof HTMLElement ? event.target : null;\n if (!direct) return null;\n const closest = direct.closest(`[${POI_ATTR}]`);\n if (closest && isPoi(closest)) {\n return closest as Poi;\n }\n return null;\n }\n\n private getTargetLayer(target: Element): ObcPoiLayer | null {\n return target.closest('obc-poi-layer') as ObcPoiLayer | null;\n }\n\n private getLayerTargets(layer: ParentNode): Poi[] {\n return Array.from(layer.querySelectorAll(`[${POI_ATTR}]`)).filter(\n (el): el is Poi => isPoi(el)\n );\n }\n\n private getAllLayers(): ObcPoiLayer[] {\n return Array.from(this.querySelectorAll('obc-poi-layer')) as ObcPoiLayer[];\n }\n\n private isLayerSelected(layer: ObcPoiLayer): boolean {\n return layer.isSelected === true;\n }\n\n private cleanupSelection() {\n this.selectionMap.forEach((_, target) => {\n if (!target.isConnected) {\n this.selectionMap.delete(target);\n }\n });\n }\n\n private getLayer(\n kind: 'top' | 'secondTop' | 'selected' | 'default'\n ): ObcPoiLayer | null {\n const layers = this.getAllLayers();\n switch (kind) {\n case 'top':\n return layers[layers.length - 1] ?? null;\n case 'secondTop':\n return layers.length >= 2 ? (layers[layers.length - 2] ?? null) : null;\n case 'selected':\n return layers.find((layer) => this.isLayerSelected(layer)) ?? null;\n case 'default': {\n const nonSelected = layers.filter(\n (layer) => !this.isLayerSelected(layer)\n );\n return nonSelected[nonSelected.length - 1] ?? null;\n }\n }\n }\n\n private clearOtherTopSelections(target: Poi) {\n const topLayer = this.getLayer('top');\n const activeLayer = this.getLayer('selected') ?? topLayer;\n if (!activeLayer) return;\n const topTargets = this.getLayerTargets(activeLayer);\n topTargets.forEach((other) => {\n if (other === target) return;\n const record = this.selectionMap.get(other);\n this.resetSelectionForTarget(other, record);\n });\n }\n\n private getTargetTagName(target: Poi): string {\n return target.tagName.toLowerCase();\n }\n\n private inferBootstrapOriginLayer(\n target: Poi,\n selectedLayer: ObcPoiLayer\n ): ObcPoiLayer {\n const targetTagName = this.getTargetTagName(target);\n const nonSelectedLayers = this.getAllLayers().filter(\n (layer) => layer !== selectedLayer\n );\n\n const typedOrigin = nonSelectedLayers.find((layer) =>\n this.getLayerTargets(layer).some(\n (candidate) => this.getTargetTagName(candidate) === targetTagName\n )\n );\n if (typedOrigin) {\n return typedOrigin;\n }\n\n return this.getLayer('default') ?? selectedLayer;\n }\n\n private collectPoiHeaders(target: Poi): HTMLElement[] {\n const headers = new Set<HTMLElement>();\n\n const visit = (node: ParentNode) => {\n if (node instanceof Element && node.matches('obc-poi-header')) {\n headers.add(node as HTMLElement);\n }\n\n const children =\n node instanceof ShadowRoot || node instanceof Element\n ? Array.from(node.children)\n : [];\n\n for (const child of children) {\n if (child.matches('obc-poi-header')) {\n headers.add(child as HTMLElement);\n }\n if (child.shadowRoot) {\n visit(child.shadowRoot);\n }\n visit(child);\n }\n };\n\n visit(target);\n if (target.shadowRoot) {\n visit(target.shadowRoot);\n }\n\n return Array.from(headers);\n }\n\n private setTargetSelectedId(target: Poi) {\n if (target.hasHeader === undefined) return;\n const headers = this.collectPoiHeaders(target);\n const hasExternalHeader = headers.some(\n (header) => !header.hasAttribute('data-stack-header')\n );\n if (hasExternalHeader) {\n target.hasHeader = true;\n return;\n }\n\n let selectedId = target.getAttribute('data-stack-selection-id');\n if (!selectedId) {\n selectedId = String(++this.selectionCounter);\n target.setAttribute('data-stack-selection-id', selectedId);\n }\n if ('headerContent' in target) {\n target.headerContent = selectedId;\n }\n target.hasHeader = true;\n }\n\n private clearTargetSelectedId(target: Poi) {\n const headers = this.collectPoiHeaders(target);\n headers\n .filter((header) => header.hasAttribute('data-stack-header'))\n .forEach((header) => header.remove());\n if (target.hasHeader !== undefined) {\n target.hasHeader = false;\n }\n if ('headerContent' in target) {\n target.headerContent = '';\n }\n }\n\n private async waitForPoiRender(target: Poi) {\n const component = target as unknown as {updateComplete?: Promise<unknown>};\n await component.updateComplete;\n await new Promise<void>((resolve) =>\n requestAnimationFrame(() => resolve())\n );\n }\n\n private requestPoiRender(target: Poi) {\n const component = target as unknown as {requestUpdate?: () => void};\n component.requestUpdate?.();\n }\n\n private refreshTargetProjectionLayout(target: Poi, trackDurationMs = 0) {\n target.refreshProjectionLayout?.(trackDurationMs);\n }\n\n private getTargetButtonProjectionOffset(target: Poi): number {\n const raw = target.style.getPropertyValue('--obc-poi-button-projection-y');\n const parsed = Number.parseFloat(raw);\n return Number.isFinite(parsed) ? parsed : 0;\n }\n\n private getLayerProjectionOffset(\n originLayer: ObcPoiLayer,\n destinationLayer: ObcPoiLayer | null\n ): number {\n if (!destinationLayer || destinationLayer === originLayer) {\n return 0;\n }\n\n const originRect = originLayer.getBoundingClientRect();\n const destinationRect = destinationLayer.getBoundingClientRect();\n return destinationRect.bottom - originRect.bottom;\n }\n\n private getTargetProjectionOffset(\n originLayer: ObcPoiLayer,\n selectedLayer: ObcPoiLayer | null\n ): number {\n if (!selectedLayer || selectedLayer === originLayer) {\n return 0;\n }\n\n const originRect = originLayer.getBoundingClientRect();\n const selectedRect = selectedLayer.getBoundingClientRect();\n return originRect.bottom - selectedRect.bottom;\n }\n\n private detachTargetFromCurrentGroup(target: Poi): ObcPoiLayer | null {\n const currentLayer = this.getTargetLayer(target);\n const sourceGroup =\n target.parentElement?.tagName.toLowerCase() === 'obc-poi-group'\n ? (target.parentElement as ObcPoiGroup)\n : null;\n\n if (!sourceGroup) {\n return currentLayer;\n }\n\n // Yank target out immediately — don't await group collapse.\n // Clean up group-owned state (mirrors releaseTargetToParent in poi-group).\n target.setRuntimeHorizontalOffsets?.(0, 0);\n if (!target.setRuntimeHorizontalOffsets) {\n target.buttonOffsetX = 0;\n target.targetOffsetX = 0;\n }\n clearTargetGroupingStyles(target);\n\n // Collapse the group independently — it handles its own cleanup.\n // Set collapsing BEFORE expand=false so updateGrouping (which may\n // fire via mutation observer before the group's updated() runs)\n // sees collapsing=true and returns early instead of disbanding.\n if (sourceGroup.expand) {\n sourceGroup.collapsing = true;\n sourceGroup.expand = false;\n }\n\n // Hide the wrapper immediately so it doesn't flash for one frame\n // while updateGrouping catches up.\n sourceGroup.removeAttribute('data-visible');\n\n return currentLayer;\n }\n\n private applySelectedTargetProjectionState(target: Poi) {\n // Leave `animatePosition` off: it drops the no-motion class, and the CSS\n // transitions that unlocks fight the group's frame-by-frame expand and\n // collapse, which shows up as X wiggle. The FLIP jump runs on the Web\n // Animations API and overrides CSS anyway.\n target.style.setProperty(\n '--obc-poi-forced-target-transition-duration',\n '0ms'\n );\n target.style.setProperty('--obc-poi-layer-inactive-opacity', '1');\n target.style.setProperty('z-index', '3');\n }\n\n private clearTargetProjectionStyles(target: Poi) {\n target.style.removeProperty('--obc-poi-button-projection-y');\n target.style.removeProperty('--obc-poi-target-projection-y');\n target.style.removeProperty('--obc-poi-forced-target-transition-duration');\n target.style.removeProperty('--obc-poi-layer-inactive-opacity');\n target.style.removeProperty('z-index');\n }\n\n /**\n * Find the button and line elements inside the POI's shadow DOM.\n */\n private getAnimationElements(target: Poi): {\n button: HTMLElement | null;\n line: HTMLElement | null;\n } {\n const host = target as HTMLElement;\n const innerPoi = host.shadowRoot?.querySelector('obc-poi');\n const poiShadow = innerPoi?.shadowRoot;\n\n // Button is slotted — find via slot.assignedElements\n let button: HTMLElement | null = null;\n const buttonSlot = poiShadow?.querySelector(\n 'slot[name=\"button\"]'\n ) as HTMLSlotElement | null;\n if (buttonSlot) {\n const assigned = buttonSlot.assignedElements({flatten: true});\n button = (assigned[0] as HTMLElement) ?? null;\n }\n\n const line = poiShadow?.querySelector('.line') as HTMLElement | null;\n return {button, line};\n }\n\n /**\n * Animate a layer jump using Web Animations API.\n * fill:'forwards' overrides ALL CSS/Lit styles during animation.\n * After cancel(), Lit's final-state styles take over.\n */\n private async animateLayerJump(\n target: Poi,\n beforeButtonRect: DOMRect | null,\n beforeLineRect: DOMRect | null\n ): Promise<void> {\n const {button, line} = this.getAnimationElements(target);\n\n const afterButtonRect = button?.getBoundingClientRect();\n const afterLineRect = line?.getBoundingClientRect();\n\n const duration = ObcPoiLayerStack.STACK_JUMP_DURATION_MS;\n const easing = 'ease-out';\n const animations: Animation[] = [];\n\n // Button: animate translateY from old position to new\n if (button && beforeButtonRect && afterButtonRect) {\n const deltaY = beforeButtonRect.top - afterButtonRect.top;\n if (Math.abs(deltaY) >= 0.5) {\n // Read the current (final) computed transform to use as end state\n const finalTransform = getComputedStyle(button).transform;\n const startTransform =\n finalTransform === 'none'\n ? `translateY(${deltaY}px)`\n : `${finalTransform} translateY(${deltaY}px)`;\n\n animations.push(\n button.animate(\n [{transform: startTransform}, {transform: finalTransform}],\n {duration, easing, fill: 'forwards'}\n )\n );\n }\n }\n\n // Line: animate both position (translateY matching button) and\n // height (scaleY). Web Animations don't affect layout, so the line's\n // CSS top:100% stays at the final position — we must translate it\n // by the same delta as the button.\n if (line && button && beforeButtonRect && afterButtonRect) {\n const buttonDeltaY = beforeButtonRect.top - afterButtonRect.top;\n // Line height: before vs after\n const beforeH = beforeLineRect?.height ?? 0;\n const afterH = afterLineRect?.height ?? (beforeH || 1);\n const scaleRatio = afterH > 0 ? beforeH / afterH : 1;\n\n if (Math.abs(buttonDeltaY) >= 0.5 || Math.abs(scaleRatio - 1) > 0.01) {\n animations.push(\n line.animate(\n [\n {\n transform: `translateX(-50%) translateY(${buttonDeltaY}px) scaleY(${scaleRatio})`,\n transformOrigin: 'top center',\n },\n {\n transform: 'translateX(-50%) translateY(0px) scaleY(1)',\n transformOrigin: 'top center',\n },\n ],\n {duration, easing, fill: 'forwards'}\n )\n );\n }\n }\n\n if (animations.length > 0) {\n await Promise.all(animations.map((a) => a.finished));\n animations.forEach((a) => a.cancel());\n }\n }\n\n private async moveTargetIntoSelectedLayer(\n target: Poi,\n _originLayer: ObcPoiLayer,\n selectedLayer: ObcPoiLayer,\n animate = true\n ) {\n // BEFORE: measure button and line positions\n const {button, line} = this.getAnimationElements(target);\n const beforeButtonRect = button?.getBoundingClientRect() ?? null;\n const beforeLineRect = line?.getBoundingClientRect() ?? null;\n\n // Move to destination layer\n if (this.getTargetLayer(target) !== selectedLayer) {\n selectedLayer.appendChild(target);\n }\n\n // Render at final state (no projection variables needed)\n this.requestPoiRender(target);\n this.refreshTargetProjectionLayout(target);\n await this.waitForPoiRender(target);\n\n if (!animate) return;\n\n // AFTER: animate from old positions to new\n await this.animateLayerJump(target, beforeButtonRect, beforeLineRect);\n }\n\n private async moveTrackedTargetToSelectedLayer(\n target: Poi,\n record: {\n originLayer: ObcPoiLayer;\n previousAnimatePosition: boolean;\n keepInSelectedLayer: boolean;\n },\n selectedLayer: ObcPoiLayer,\n animateProjection: boolean\n ) {\n const currentLayer =\n this.detachTargetFromCurrentGroup(target) ??\n this.getTargetLayer(target) ??\n record.originLayer;\n\n clearTargetGroupingAttributes(target);\n await this.moveTargetIntoSelectedLayer(\n target,\n record.originLayer,\n selectedLayer,\n animateProjection\n );\n\n if (currentLayer !== selectedLayer) {\n currentLayer.requestGroupingUpdate();\n }\n selectedLayer.requestGroupingUpdate();\n }\n\n private async syncTargetProjection(\n target: Poi,\n originLayer: ObcPoiLayer,\n selectedLayer: ObcPoiLayer | null,\n animate = true\n ) {\n const nextProjectionOffset = this.getLayerProjectionOffset(\n originLayer,\n selectedLayer\n );\n const currentProjectionOffset =\n this.getTargetButtonProjectionOffset(target);\n\n if (Math.abs(nextProjectionOffset - currentProjectionOffset) < 0.5) {\n if (Math.abs(nextProjectionOffset) < 0.5) {\n target.style.removeProperty('--obc-poi-button-projection-y');\n } else {\n target.style.setProperty(\n '--obc-poi-button-projection-y',\n `${nextProjectionOffset}px`\n );\n }\n this.requestPoiRender(target);\n this.refreshTargetProjectionLayout(target);\n return;\n }\n\n if (Math.abs(nextProjectionOffset) < 0.5) {\n target.style.removeProperty('--obc-poi-button-projection-y');\n } else {\n target.style.setProperty(\n '--obc-poi-button-projection-y',\n `${nextProjectionOffset}px`\n );\n }\n this.requestPoiRender(target);\n if (animate) {\n this.refreshTargetProjectionLayout(\n target,\n ObcPoiLayerStack.STACK_JUMP_DURATION_MS\n );\n await this.waitForPoiRender(target);\n return;\n }\n this.refreshTargetProjectionLayout(target);\n }\n\n private async animateTargetReturnToOrigin(\n target: Poi,\n record: {\n originLayer: ObcPoiLayer;\n previousAnimatePosition: boolean;\n keepInSelectedLayer: boolean;\n }\n ) {\n target.setAttribute(ObcPoiLayerStack.STACK_RETURNING_ATTR, 'true');\n\n try {\n const currentLayer =\n this.detachTargetFromCurrentGroup(target) ??\n this.getTargetLayer(target);\n\n // Clear grouping attributes immediately so the target doesn't\n // arrive in the origin layer with data-grouped (which sets opacity:0).\n clearTargetGroupingAttributes(target);\n\n // BEFORE: measure button and line\n const {button: beforeBtn, line: beforeLine} =\n this.getAnimationElements(target);\n const beforeButtonRect = beforeBtn?.getBoundingClientRect() ?? null;\n const beforeLineRect = beforeLine?.getBoundingClientRect() ?? null;\n\n // Clear projections, move to origin layer, render at final state\n target.style.removeProperty('--obc-poi-target-projection-y');\n target.style.removeProperty('--obc-poi-button-projection-y');\n if (target.parentElement !== record.originLayer) {\n record.originLayer.appendChild(target);\n }\n this.requestPoiRender(target);\n this.refreshTargetProjectionLayout(target);\n await this.waitForPoiRender(target);\n\n // AFTER: animate from old positions to new\n await this.animateLayerJump(target, beforeButtonRect, beforeLineRect);\n this.setSelectedTargetInteractivity(target, false);\n clearTargetGroupingAttributes(target);\n this.clearTargetSelectedId(target);\n this.clearTargetProjectionStyles(target);\n this.requestPoiRender(target);\n if (currentLayer && currentLayer !== record.originLayer) {\n currentLayer.requestGroupingUpdate();\n }\n record.originLayer.requestGroupingUpdate();\n this.schedulePlacement();\n } finally {\n target.removeAttribute(ObcPoiLayerStack.STACK_RETURNING_ATTR);\n }\n }\n\n private setSelectedTargetInteractivity(target: Poi, selected: boolean) {\n const isInAutoGroup =\n target.hasAttribute('data-grouped') ||\n target.closest('obc-poi-group') !== null;\n\n target.selected = selected;\n if (selected) {\n target.style.setProperty('--obc-poi-overlap-pointer-events', 'auto');\n if (!isInAutoGroup && target.value !== PoiDataValue.Overlapped) {\n target.value = PoiDataValue.Checked;\n target.removeAttribute('data-behind');\n target.setAttribute('data-front', 'true');\n }\n } else {\n target.value = PoiDataValue.Unchecked;\n target.style.removeProperty('--obc-poi-overlap-pointer-events');\n target.removeAttribute('data-front');\n }\n }\n\n private trackSelectionTarget(\n target: Poi,\n originLayer: ObcPoiLayer,\n keepInSelectedLayer = true\n ) {\n this.selectionMap.set(target, {\n originLayer,\n previousAnimatePosition: target.animatePosition ?? false,\n keepInSelectedLayer,\n });\n target.removeAttribute('data-stack-selected');\n }\n\n private activateTrackedTarget(\n target: Poi,\n record: {\n originLayer: ObcPoiLayer;\n previousAnimatePosition: boolean;\n keepInSelectedLayer: boolean;\n },\n selectedLayer: ObcPoiLayer,\n animateProjection = true\n ) {\n if (record.keepInSelectedLayer) {\n target.removeAttribute('data-stack-selected');\n const needsMove = this.getTargetLayer(target) !== selectedLayer;\n if (needsMove) {\n void this.moveTrackedTargetToSelectedLayer(\n target,\n record,\n selectedLayer,\n animateProjection\n );\n } else {\n const targetProjectionOffset = this.getTargetProjectionOffset(\n record.originLayer,\n selectedLayer\n );\n if (Math.abs(targetProjectionOffset) < 0.5) {\n target.style.removeProperty('--obc-poi-target-projection-y');\n } else {\n target.style.setProperty(\n '--obc-poi-target-projection-y',\n `${targetProjectionOffset}px`\n );\n }\n target.style.removeProperty('--obc-poi-button-projection-y');\n this.requestPoiRender(target);\n this.refreshTargetProjectionLayout(target);\n }\n } else {\n clearTargetGroupingAttributes(target);\n target.setAttribute('data-stack-selected', 'true');\n void this.syncTargetProjection(\n target,\n record.originLayer,\n selectedLayer,\n animateProjection\n );\n }\n this.setSelectedTargetInteractivity(target, true);\n this.setTargetSelectedId(target);\n this.applySelectedTargetProjectionState(target);\n }\n\n private seedSelectedLayerSelections(selectedLayer: ObcPoiLayer): Set<Poi> {\n const seededTargets = new Set<Poi>();\n if (this.selectionMode === PoiLayerSelectionMode.None) {\n return seededTargets;\n }\n\n const selectedTargets = this.getLayerTargets(selectedLayer);\n for (const target of selectedTargets) {\n if (target.hasAttribute(ObcPoiLayerStack.STACK_RETURNING_ATTR)) {\n continue;\n }\n if (this.selectionMap.has(target)) {\n continue;\n }\n if (\n this.selectionMode === PoiLayerSelectionMode.Single &&\n this.selectionMap.size > 0\n ) {\n break;\n }\n\n const originLayer = this.inferBootstrapOriginLayer(target, selectedLayer);\n this.selectionMap.set(target, {\n originLayer,\n previousAnimatePosition: target.animatePosition ?? false,\n keepInSelectedLayer: true,\n });\n target.removeAttribute('data-stack-selected');\n seededTargets.add(target);\n }\n return seededTargets;\n }\n\n private resetSelectionForTarget(\n target: Poi,\n record?: {\n originLayer: ObcPoiLayer;\n previousAnimatePosition: boolean;\n keepInSelectedLayer: boolean;\n }\n ) {\n target.removeAttribute('data-stack-selected');\n if (record) {\n this.selectionMap.delete(target);\n void this.animateTargetReturnToOrigin(target, record);\n return;\n }\n this.setSelectedTargetInteractivity(target, false);\n clearTargetGroupingAttributes(target);\n this.clearTargetSelectedId(target);\n this.clearTargetProjectionStyles(target);\n }\n\n private clearSelectionMapExcept(target: Poi) {\n const entries = Array.from(this.selectionMap.entries());\n entries.forEach(([other, record]) => {\n if (other === target) return;\n this.resetSelectionForTarget(other, record);\n });\n }\n\n private setupMutationObserver() {\n this.mutationObserver?.disconnect();\n this.mutationObserver = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (\n mutation.type === 'attributes' &&\n mutation.target instanceof HTMLElement\n ) {\n if (mutation.attributeName === POI_ATTR) {\n this.schedulePlacement();\n return;\n }\n }\n for (const node of Array.from(mutation.addedNodes)) {\n if (!(node instanceof HTMLElement)) continue;\n if (isPoi(node) || node.querySelector?.(`[${POI_ATTR}]`)) {\n this.schedulePlacement();\n return;\n }\n }\n }\n });\n this.mutationObserver.observe(this, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [POI_ATTR],\n });\n }\n\n private schedulePlacement() {\n if (this.placementRaf) return;\n this.placementRaf = requestAnimationFrame(() => {\n this.placementRaf = 0;\n this.updateLayerOrders();\n this.syncSelectedLayerTargets();\n });\n }\n\n private updateLayerInactiveState(selectedLayer: ObcPoiLayer | null) {\n const layers = this.getAllLayers();\n layers.forEach((layer) => {\n if (selectedLayer && layer !== selectedLayer) {\n layer.setAttribute('data-stack-inactive', 'true');\n } else {\n layer.removeAttribute('data-stack-inactive');\n }\n });\n }\n\n private updateLayerOrders() {\n const layers = this.getAllLayers();\n layers.forEach((layer, index) => {\n layer.style.order = String(index);\n });\n\n const selectedLayer = this.getLayer('selected');\n this.updateLayerInactiveState(selectedLayer);\n }\n\n private syncSelectedLayerTargets() {\n const selectedLayer = this.getLayer('selected');\n\n if (!selectedLayer) {\n this.selectionMap.forEach((record, target) => {\n this.resetSelectionForTarget(target, record);\n });\n return;\n }\n\n const seededTargets = this.seedSelectedLayerSelections(selectedLayer);\n\n this.selectionMap.forEach((record, target) => {\n if (!target.isConnected) {\n this.selectionMap.delete(target);\n return;\n }\n if (target.hasAttribute(ObcPoiLayerStack.STACK_RETURNING_ATTR)) {\n return;\n }\n if (\n !record.keepInSelectedLayer &&\n !target.hasAttribute('data-stack-selected')\n ) {\n target.setAttribute('data-stack-selected', 'true');\n }\n this.activateTrackedTarget(\n target,\n record,\n selectedLayer,\n !seededTargets.has(target)\n );\n });\n }\n\n override render() {\n return html`\n <div class=\"wrapper\">\n <slot></slot>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-poi-layer-stack': ObcPoiLayerStack;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"poi-layer-stack.js","names":[],"sources":["../../../src/ar/poi-layer-stack/poi-layer-stack.ts"],"sourcesContent":["import {LitElement, html, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {customElement} from '../../decorator.js';\nimport componentStyle from './poi-layer-stack.css?inline';\n\nimport '../poi-layer/poi-layer.js';\nimport '../poi-group/poi-group.js';\nimport '../poi/poi-data.js';\nimport '../building-blocks/poi-header/poi-header.js';\n\nimport type {ObcPoiLayer} from '../poi-layer/poi-layer.js';\nimport type {ObcPoiGroup} from '../poi-group/poi-group.js';\nimport {PoiDataValue} from '../poi/poi-data.js';\nimport {Poi, isPoi, POI_ATTR} from '../poi/poi.js';\nimport {\n clearTargetGroupingAttributes,\n clearTargetGroupingStyles,\n} from '../poi/poi-grouping-attrs.js';\n\nexport enum PoiLayerSelectionMode {\n None = 'none',\n Single = 'single',\n Multi = 'multi',\n}\n\n/**\n * Tracking record for a selected target. The stack never re-parents targets;\n * it renders selection by projecting the target's button (and, for targets\n * authored inside the selected layer, its pointer) between layers via CSS\n * custom properties.\n */\ntype SelectionRecord = {\n /** The layer that owns the target in the DOM. Never modified by the stack. */\n homeLayer: ObcPoiLayer;\n /**\n * The logical origin layer: equal to `homeLayer` for normal targets;\n * inferred for targets authored directly inside the selected layer.\n */\n originLayer: ObcPoiLayer;\n};\n\n/**\n * `<obc-poi-layer-stack>` coordinates multiple POI layers and manages\n * selection behavior across stacked layers.\n *\n * Use `selection-mode` to control whether targets can be selected across the\n * stack (`none`, `single`, or `multi`).\n *\n * ### Required Setup\n * 1. Place the stack in `obc-poi-controller`'s `slot=\"stack\"`, or manage the\n * stack's height and media geometry yourself.\n * 2. Give exactly one child `obc-poi-layer` the `is-selected` attribute — the\n * stack projects selected targets' buttons into it and resets all\n * selection state if no selected layer exists.\n * 3. Mark the background/default layer with\n * `data-controller-layer=\"background\"` when the stack is used inside\n * `obc-poi-controller`.\n * 4. Set `--obc-poi-layer-min-height` on layers that can start empty, so they\n * do not collapse to 0px height.\n *\n * ### DOM Ownership\n * The stack never moves, creates, or removes consumer-owned DOM. Selection is\n * rendered by projecting the target's button into the selected layer via CSS\n * custom properties (`--obc-poi-button-projection-y` /\n * `--obc-poi-target-projection-y`); the target element stays where the\n * consumer put it. Declarative renderers (React, Vue, Lit) can manage POI\n * children as ordinary framework-owned elements.\n *\n * ### Selection API\n * Selection state is fully reachable without DOM inspection:\n * - `selectedTargets` — the currently selected POI targets.\n * - `selectTarget(target, {selectionId?})` — select programmatically;\n * `selectionId` presets the stack-managed badge id.\n * - `deselectTarget(target)` / `clearSelection()` — deselect one/all.\n * - `selection-change` event — fired on every selection mutation\n * (user click, programmatic call, or bootstrap seeding) with\n * `{selected, added, removed}` in `detail`.\n *\n * ### Slots\n * - Default slot for `obc-poi-layer` elements that participate in the stack.\n *\n * ### Example\n * ```html\n * <obc-poi-layer-stack selection-mode=\"single\">\n * <obc-poi-layer label=\"Radar\" .isSelected=${true}></obc-poi-layer>\n * <obc-poi-layer label=\"AIS\"></obc-poi-layer>\n * </obc-poi-layer-stack>\n * ```\n *\n * @slot - Layers participating in the stack.\n * @fires {CustomEvent<{selected: Poi[]; added: Poi | null; removed: Poi | null}>} selection-change - Fired whenever the selection set changes (user click, programmatic call, or bootstrap seeding). Bubbles and is composed.\n * @experimental\n */\n@customElement('obc-poi-layer-stack')\nexport class ObcPoiLayerStack extends LitElement {\n private static readonly STACK_JUMP_DURATION_MS = 100;\n private static readonly STACK_RETURNING_ATTR = 'data-stack-returning';\n\n @property({type: String, attribute: 'selection-mode'})\n selectionMode: PoiLayerSelectionMode = PoiLayerSelectionMode.None;\n\n private handleStackClick = (event: Event) => this.onStackClick(event);\n private handleSlotChange = () => this.schedulePlacement();\n private handleTargetLayoutChange = () => this.schedulePlacement();\n private handleLayerSelectionChanged = () => this.schedulePlacement();\n private selectionMap = new Map<Poi, SelectionRecord>();\n /**\n * Deselected targets that live in one layer but render in another (targets\n * authored inside the selected layer whose logical origin is a different\n * layer). Their projections are refreshed on every placement pass so layer\n * resizes do not leave stale pixel offsets.\n */\n private displacedTargets = new Map<Poi, SelectionRecord>();\n private selectionCounter = 0;\n private placementRaf = 0;\n private mutationObserver?: MutationObserver;\n\n override connectedCallback() {\n super.connectedCallback();\n this.addEventListener('click', this.handleStackClick);\n this.addEventListener(\n 'obc-poi-data-layout-change',\n this.handleTargetLayoutChange as EventListener\n );\n this.addEventListener(\n 'layer-selection-changed',\n this.handleLayerSelectionChanged\n );\n }\n\n override firstUpdated() {\n const slot = this.shadowRoot?.querySelector('slot');\n slot?.addEventListener('slotchange', this.handleSlotChange);\n this.setupMutationObserver();\n this.schedulePlacement();\n requestAnimationFrame(() => {\n this.schedulePlacement();\n requestAnimationFrame(() => this.schedulePlacement());\n });\n }\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('click', this.handleStackClick);\n this.removeEventListener(\n 'obc-poi-data-layout-change',\n this.handleTargetLayoutChange as EventListener\n );\n this.removeEventListener(\n 'layer-selection-changed',\n this.handleLayerSelectionChanged\n );\n const slot = this.shadowRoot?.querySelector('slot');\n slot?.removeEventListener('slotchange', this.handleSlotChange);\n this.mutationObserver?.disconnect();\n this.mutationObserver = undefined;\n if (this.placementRaf) {\n cancelAnimationFrame(this.placementRaf);\n this.placementRaf = 0;\n }\n this.selectionMap.forEach((_, target) => {\n this.clearTargetProjectionStyles(target);\n this.requestPoiRender(target);\n });\n this.selectionMap.clear();\n this.displacedTargets.forEach((_, target) => {\n this.clearTargetProjectionStyles(target);\n this.requestPoiRender(target);\n });\n this.displacedTargets.clear();\n this.selectionCounter = 0;\n }\n\n private onStackClick(event: Event) {\n if (this.selectionMode === PoiLayerSelectionMode.None) return;\n const target = this.getPoiTargetFromEvent(event);\n if (!target) return;\n if (target.hasAttribute(ObcPoiLayerStack.STACK_RETURNING_ATTR)) return;\n\n this.cleanupSelection();\n const existing = this.selectionMap.get(target);\n if (existing) {\n this.resetSelectionForTarget(target, existing);\n return;\n }\n this.performSelection(target);\n }\n\n /** Currently selected POI targets. */\n get selectedTargets(): Poi[] {\n this.cleanupSelection();\n return Array.from(this.selectionMap.keys());\n }\n\n /**\n * Programmatically select a target, following the same flow as a user\n * click. `options.selectionId` presets the badge id shown in the\n * stack-managed header; without it the id auto-increments. Returns\n * `false` when selection is disabled, the target is mid-transition or\n * already selected, or no layer can host the selection.\n */\n selectTarget(target: Poi, options?: {selectionId?: string}): boolean {\n if (this.selectionMode === PoiLayerSelectionMode.None) return false;\n if (target.hasAttribute(ObcPoiLayerStack.STACK_RETURNING_ATTR)) {\n return false;\n }\n this.cleanupSelection();\n if (this.selectionMap.has(target)) return false;\n return this.performSelection(target, options?.selectionId);\n }\n\n /**\n * Programmatically deselect a target. Returns `false` when it is not\n * selected.\n */\n deselectTarget(target: Poi): boolean {\n const record = this.selectionMap.get(target);\n if (!record) return false;\n this.resetSelectionForTarget(target, record);\n return true;\n }\n\n /** Deselect all targets. */\n clearSelection(): void {\n Array.from(this.selectionMap.entries()).forEach(([target, record]) => {\n this.resetSelectionForTarget(target, record);\n });\n }\n\n private performSelection(target: Poi, selectionId?: string): boolean {\n const homeLayer = this.getTargetLayer(target);\n if (!homeLayer) return false;\n\n const selectedLayer = this.getLayer('selected') ?? this.getLayer('top');\n if (!selectedLayer) return false;\n\n if (this.selectionMode === PoiLayerSelectionMode.Single) {\n this.clearOtherTopSelections(target);\n this.clearSelectionMapExcept(target);\n }\n\n const displaced = this.displacedTargets.get(target);\n this.displacedTargets.delete(target);\n const originLayer =\n displaced?.originLayer ??\n (homeLayer === selectedLayer\n ? this.inferBootstrapOriginLayer(target, selectedLayer)\n : homeLayer);\n\n if (selectionId) {\n target.setAttribute('data-stack-selection-id', selectionId);\n }\n const record: SelectionRecord = {homeLayer, originLayer};\n this.selectionMap.set(target, record);\n this.activateTrackedTarget(target, record, selectedLayer);\n this.schedulePlacement();\n this.dispatchSelectionChange(target, null);\n return true;\n }\n\n private dispatchSelectionChange(added: Poi | null, removed: Poi | null) {\n this.dispatchEvent(\n new CustomEvent('selection-change', {\n detail: {selected: this.selectedTargets, added, removed},\n bubbles: true,\n composed: true,\n })\n );\n }\n\n private getPoiTargetFromEvent(event: Event): Poi | null {\n const path = event.composedPath?.() ?? [];\n for (const item of path) {\n if (item instanceof HTMLElement && isPoi(item)) {\n return item as Poi;\n }\n }\n const direct = event.target instanceof HTMLElement ? event.target : null;\n if (!direct) return null;\n const closest = direct.closest(`[${POI_ATTR}]`);\n if (closest && isPoi(closest)) {\n return closest as Poi;\n }\n return null;\n }\n\n private getTargetLayer(target: Element): ObcPoiLayer | null {\n return target.closest('obc-poi-layer') as ObcPoiLayer | null;\n }\n\n private getLayerTargets(layer: ParentNode): Poi[] {\n return Array.from(layer.querySelectorAll(`[${POI_ATTR}]`)).filter(\n (el): el is Poi => isPoi(el)\n );\n }\n\n private getAllLayers(): ObcPoiLayer[] {\n return Array.from(this.querySelectorAll('obc-poi-layer')) as ObcPoiLayer[];\n }\n\n private isLayerSelected(layer: ObcPoiLayer): boolean {\n return layer.isSelected === true;\n }\n\n private cleanupSelection() {\n this.selectionMap.forEach((_, target) => {\n if (!target.isConnected) {\n this.selectionMap.delete(target);\n }\n });\n this.displacedTargets.forEach((_, target) => {\n if (!target.isConnected) {\n this.displacedTargets.delete(target);\n }\n });\n }\n\n private getLayer(\n kind: 'top' | 'secondTop' | 'selected' | 'default'\n ): ObcPoiLayer | null {\n const layers = this.getAllLayers();\n switch (kind) {\n case 'top':\n return layers[layers.length - 1] ?? null;\n case 'secondTop':\n return layers.length >= 2 ? (layers[layers.length - 2] ?? null) : null;\n case 'selected':\n return layers.find((layer) => this.isLayerSelected(layer)) ?? null;\n case 'default': {\n const nonSelected = layers.filter(\n (layer) => !this.isLayerSelected(layer)\n );\n return nonSelected[nonSelected.length - 1] ?? null;\n }\n }\n }\n\n private clearOtherTopSelections(target: Poi) {\n const topLayer = this.getLayer('top');\n const activeLayer = this.getLayer('selected') ?? topLayer;\n if (!activeLayer) return;\n const topTargets = this.getLayerTargets(activeLayer);\n topTargets.forEach((other) => {\n if (other === target) return;\n if (this.displacedTargets.has(other)) return;\n const record = this.selectionMap.get(other);\n this.resetSelectionForTarget(other, record);\n });\n }\n\n private getTargetTagName(target: Poi): string {\n return target.tagName.toLowerCase();\n }\n\n private inferBootstrapOriginLayer(\n target: Poi,\n selectedLayer: ObcPoiLayer\n ): ObcPoiLayer {\n const targetTagName = this.getTargetTagName(target);\n const nonSelectedLayers = this.getAllLayers().filter(\n (layer) => layer !== selectedLayer\n );\n\n const typedOrigin = nonSelectedLayers.find((layer) =>\n this.getLayerTargets(layer).some(\n (candidate) => this.getTargetTagName(candidate) === targetTagName\n )\n );\n if (typedOrigin) {\n return typedOrigin;\n }\n\n return this.getLayer('default') ?? selectedLayer;\n }\n\n private collectPoiHeaders(target: Poi): HTMLElement[] {\n const headers = new Set<HTMLElement>();\n\n const visit = (node: ParentNode) => {\n if (node instanceof Element && node.matches('obc-poi-header')) {\n headers.add(node as HTMLElement);\n }\n\n const children =\n node instanceof ShadowRoot || node instanceof Element\n ? Array.from(node.children)\n : [];\n\n for (const child of children) {\n if (child.matches('obc-poi-header')) {\n headers.add(child as HTMLElement);\n }\n if (child.shadowRoot) {\n visit(child.shadowRoot);\n }\n visit(child);\n }\n };\n\n visit(target);\n if (target.shadowRoot) {\n visit(target.shadowRoot);\n }\n\n return Array.from(headers);\n }\n\n private setTargetSelectedId(target: Poi) {\n if (target.hasHeader === undefined) return;\n const headers = this.collectPoiHeaders(target);\n const hasExternalHeader = headers.some(\n (header) => !header.hasAttribute('data-stack-header')\n );\n if (hasExternalHeader) {\n target.hasHeader = true;\n return;\n }\n\n let selectedId = target.getAttribute('data-stack-selection-id');\n if (!selectedId) {\n selectedId = String(++this.selectionCounter);\n target.setAttribute('data-stack-selection-id', selectedId);\n }\n if ('headerContent' in target) {\n target.headerContent = selectedId;\n }\n target.hasHeader = true;\n }\n\n private clearTargetSelectedId(target: Poi) {\n const headers = this.collectPoiHeaders(target);\n headers\n .filter((header) => header.hasAttribute('data-stack-header'))\n .forEach((header) => header.remove());\n if (target.hasHeader !== undefined) {\n target.hasHeader = false;\n }\n if ('headerContent' in target) {\n target.headerContent = '';\n }\n }\n\n private async waitForPoiRender(target: Poi) {\n const component = target as unknown as {updateComplete?: Promise<unknown>};\n await component.updateComplete;\n await new Promise<void>((resolve) =>\n requestAnimationFrame(() => resolve())\n );\n }\n\n private requestPoiRender(target: Poi) {\n const component = target as unknown as {requestUpdate?: () => void};\n component.requestUpdate?.();\n }\n\n private refreshTargetProjectionLayout(target: Poi, trackDurationMs = 0) {\n target.refreshProjectionLayout?.(trackDurationMs);\n }\n\n private getInlineVarPx(target: Poi, name: string): number {\n const raw = target.style.getPropertyValue(name);\n const parsed = Number.parseFloat(raw);\n return Number.isFinite(parsed) ? parsed : 0;\n }\n\n /** Pixel delta between two layers' bottom edges (`to.bottom - from.bottom`). */\n private layerBottomDelta(from: ObcPoiLayer, to: ObcPoiLayer): number {\n if (from === to) {\n return 0;\n }\n return (\n to.getBoundingClientRect().bottom - from.getBoundingClientRect().bottom\n );\n }\n\n private setProjectionVar(target: Poi, name: string, valuePx: number) {\n if (Math.abs(valuePx) < 0.5) {\n target.style.removeProperty(name);\n } else {\n target.style.setProperty(name, `${valuePx}px`);\n }\n }\n\n /**\n * Render the target at the given projection offsets without touching its\n * DOM position. When `animate` is set and an offset actually changes, the\n * jump is FLIP-animated via the Web Animations API.\n */\n private async applyTargetProjection(\n target: Poi,\n buttonOffsetPx: number,\n targetOffsetPx: number,\n animate: boolean\n ) {\n const currentButton = this.getInlineVarPx(\n target,\n '--obc-poi-button-projection-y'\n );\n const currentTarget = this.getInlineVarPx(\n target,\n '--obc-poi-target-projection-y'\n );\n const changed =\n Math.abs(buttonOffsetPx - currentButton) >= 0.5 ||\n Math.abs(targetOffsetPx - currentTarget) >= 0.5;\n\n if (!changed) {\n this.setProjectionVar(\n target,\n '--obc-poi-button-projection-y',\n buttonOffsetPx\n );\n this.setProjectionVar(\n target,\n '--obc-poi-target-projection-y',\n targetOffsetPx\n );\n this.requestPoiRender(target);\n this.refreshTargetProjectionLayout(target);\n return;\n }\n\n const {button, line} = this.getAnimationElements(target);\n const beforeButtonRect = animate\n ? (button?.getBoundingClientRect() ?? null)\n : null;\n const beforeLineRect = animate\n ? (line?.getBoundingClientRect() ?? null)\n : null;\n\n this.setProjectionVar(\n target,\n '--obc-poi-button-projection-y',\n buttonOffsetPx\n );\n this.setProjectionVar(\n target,\n '--obc-poi-target-projection-y',\n targetOffsetPx\n );\n this.requestPoiRender(target);\n this.refreshTargetProjectionLayout(target);\n if (!animate) {\n return;\n }\n await this.waitForPoiRender(target);\n await this.animateLayerJump(target, beforeButtonRect, beforeLineRect);\n }\n\n /**\n * The group a target currently belongs to — a light-DOM parent for\n * consumer-managed groups, or the shadow group whose member slot the\n * target is assigned to for layer-created auto groups.\n */\n private getContainingGroup(target: Poi): ObcPoiGroup | null {\n if (target.parentElement?.tagName.toLowerCase() === 'obc-poi-group') {\n return target.parentElement as ObcPoiGroup;\n }\n const slotParent = target.assignedSlot?.parentElement;\n if (slotParent?.tagName.toLowerCase() === 'obc-poi-group') {\n return slotParent as ObcPoiGroup;\n }\n return null;\n }\n\n private detachTargetFromCurrentGroup(target: Poi): ObcPoiLayer | null {\n const currentLayer = this.getTargetLayer(target);\n const sourceGroup = this.getContainingGroup(target);\n\n if (!sourceGroup) {\n return currentLayer;\n }\n\n // Yank target out immediately — don't await group collapse.\n // Clean up group-owned state (mirrors releaseTargetToParent in poi-group).\n target.setRuntimeHorizontalOffsets?.(0, 0);\n if (!target.setRuntimeHorizontalOffsets) {\n target.buttonOffsetX = 0;\n target.targetOffsetX = 0;\n }\n clearTargetGroupingStyles(target);\n\n // Collapse the group independently — it handles its own cleanup.\n // Set collapsing BEFORE expand=false so updateGrouping (which may\n // fire via mutation observer before the group's updated() runs)\n // sees collapsing=true and returns early instead of disbanding.\n if (sourceGroup.expand) {\n sourceGroup.collapsing = true;\n sourceGroup.expand = false;\n }\n\n // Hide the wrapper immediately so it doesn't flash for one frame\n // while updateGrouping catches up.\n sourceGroup.removeAttribute('data-visible');\n\n return currentLayer;\n }\n\n private applySelectedTargetProjectionState(target: Poi) {\n // Leave `animatePosition` off: it drops the no-motion class, and the CSS\n // transitions that unlocks fight the group's frame-by-frame expand and\n // collapse, which shows up as X wiggle. The FLIP jump runs on the Web\n // Animations API and overrides CSS anyway.\n target.style.setProperty(\n '--obc-poi-forced-target-transition-duration',\n '0ms'\n );\n target.style.setProperty('--obc-poi-layer-inactive-opacity', '1');\n target.style.setProperty('z-index', '3');\n }\n\n private clearTargetProjectionStyles(target: Poi) {\n target.style.removeProperty('--obc-poi-button-projection-y');\n target.style.removeProperty('--obc-poi-target-projection-y');\n target.style.removeProperty('--obc-poi-forced-target-transition-duration');\n target.style.removeProperty('--obc-poi-layer-inactive-opacity');\n target.style.removeProperty('z-index');\n }\n\n /**\n * Find the button and line elements inside the POI's shadow DOM.\n */\n private getAnimationElements(target: Poi): {\n button: HTMLElement | null;\n line: HTMLElement | null;\n } {\n const host = target as HTMLElement;\n const innerPoi = host.shadowRoot?.querySelector('obc-poi');\n const poiShadow = innerPoi?.shadowRoot;\n\n // Button is slotted — find via slot.assignedElements\n let button: HTMLElement | null = null;\n const buttonSlot = poiShadow?.querySelector(\n 'slot[name=\"button\"]'\n ) as HTMLSlotElement | null;\n if (buttonSlot) {\n const assigned = buttonSlot.assignedElements({flatten: true});\n button = (assigned[0] as HTMLElement) ?? null;\n }\n\n const line = poiShadow?.querySelector('.line') as HTMLElement | null;\n return {button, line};\n }\n\n /**\n * Animate a layer jump using Web Animations API.\n * fill:'forwards' overrides ALL CSS/Lit styles during animation.\n * After cancel(), Lit's final-state styles take over.\n */\n private async animateLayerJump(\n target: Poi,\n beforeButtonRect: DOMRect | null,\n beforeLineRect: DOMRect | null\n ): Promise<void> {\n const {button, line} = this.getAnimationElements(target);\n\n const afterButtonRect = button?.getBoundingClientRect();\n const afterLineRect = line?.getBoundingClientRect();\n\n const duration = ObcPoiLayerStack.STACK_JUMP_DURATION_MS;\n const easing = 'ease-out';\n const animations: Animation[] = [];\n\n // Button: animate translateY from old position to new\n if (button && beforeButtonRect && afterButtonRect) {\n const deltaY = beforeButtonRect.top - afterButtonRect.top;\n if (Math.abs(deltaY) >= 0.5) {\n // Read the current (final) computed transform to use as end state\n const finalTransform = getComputedStyle(button).transform;\n const startTransform =\n finalTransform === 'none'\n ? `translateY(${deltaY}px)`\n : `${finalTransform} translateY(${deltaY}px)`;\n\n animations.push(\n button.animate(\n [{transform: startTransform}, {transform: finalTransform}],\n {duration, easing, fill: 'forwards'}\n )\n );\n }\n }\n\n // Line: animate both position (translateY matching button) and\n // height (scaleY). Web Animations don't affect layout, so the line's\n // CSS top:100% stays at the final position — we must translate it\n // by the same delta as the button.\n if (line && button && beforeButtonRect && afterButtonRect) {\n const buttonDeltaY = beforeButtonRect.top - afterButtonRect.top;\n // Line height: before vs after\n const beforeH = beforeLineRect?.height ?? 0;\n const afterH = afterLineRect?.height ?? (beforeH || 1);\n const scaleRatio = afterH > 0 ? beforeH / afterH : 1;\n\n if (Math.abs(buttonDeltaY) >= 0.5 || Math.abs(scaleRatio - 1) > 0.01) {\n animations.push(\n line.animate(\n [\n {\n transform: `translateX(-50%) translateY(${buttonDeltaY}px) scaleY(${scaleRatio})`,\n transformOrigin: 'top center',\n },\n {\n transform: 'translateX(-50%) translateY(0px) scaleY(1)',\n transformOrigin: 'top center',\n },\n ],\n {duration, easing, fill: 'forwards'}\n )\n );\n }\n }\n\n if (animations.length > 0) {\n await Promise.all(animations.map((a) => a.finished));\n animations.forEach((a) => a.cancel());\n }\n }\n\n private async animateTargetReturnToOrigin(\n target: Poi,\n record: SelectionRecord\n ) {\n target.setAttribute(ObcPoiLayerStack.STACK_RETURNING_ATTR, 'true');\n\n try {\n const sourceGroupLayer = this.detachTargetFromCurrentGroup(target);\n\n // Clear grouping attributes immediately so the target doesn't render\n // in the origin position with data-grouped (which sets opacity:0).\n clearTargetGroupingAttributes(target);\n\n // Project the whole target (button and pointer) to its logical origin\n // layer; for normal targets that is its own layer, so both offsets\n // resolve to 0 and the inline variables are removed.\n const originOffset = this.layerBottomDelta(\n record.homeLayer,\n record.originLayer\n );\n await this.applyTargetProjection(\n target,\n originOffset,\n originOffset,\n true\n );\n\n this.setSelectedTargetInteractivity(target, false);\n clearTargetGroupingAttributes(target);\n this.clearTargetSelectedId(target);\n if (record.homeLayer === record.originLayer) {\n this.clearTargetProjectionStyles(target);\n } else {\n // The target stays displaced into its origin layer — keep the\n // projection variables and track it so layer resizes refresh them.\n target.style.removeProperty(\n '--obc-poi-forced-target-transition-duration'\n );\n target.style.removeProperty('--obc-poi-layer-inactive-opacity');\n target.style.removeProperty('z-index');\n this.displacedTargets.set(target, record);\n }\n this.requestPoiRender(target);\n if (sourceGroupLayer && sourceGroupLayer !== record.homeLayer) {\n sourceGroupLayer.requestGroupingUpdate();\n }\n record.homeLayer.requestGroupingUpdate();\n this.schedulePlacement();\n } finally {\n target.removeAttribute(ObcPoiLayerStack.STACK_RETURNING_ATTR);\n target.removeAttribute('data-stack-selected');\n }\n }\n\n private setSelectedTargetInteractivity(target: Poi, selected: boolean) {\n const isInAutoGroup =\n target.hasAttribute('data-grouped') ||\n this.getContainingGroup(target) !== null;\n\n target.selected = selected;\n if (selected) {\n target.style.setProperty('--obc-poi-overlap-pointer-events', 'auto');\n if (!isInAutoGroup && target.value !== PoiDataValue.Overlapped) {\n target.value = PoiDataValue.Checked;\n target.removeAttribute('data-behind');\n target.setAttribute('data-front', 'true');\n }\n } else {\n target.value = PoiDataValue.Unchecked;\n target.style.removeProperty('--obc-poi-overlap-pointer-events');\n target.removeAttribute('data-front');\n }\n }\n\n private activateTrackedTarget(\n target: Poi,\n record: SelectionRecord,\n selectedLayer: ObcPoiLayer,\n animateProjection = true\n ) {\n if (record.homeLayer !== selectedLayer) {\n // Cross-layer selection: the target stays a DOM child of its home\n // layer; `data-stack-selected` excludes it from that layer's grouping\n // and its button is projected into the selected layer. The pointer\n // stays anchored at the origin position.\n const sourceGroupLayer = this.detachTargetFromCurrentGroup(target);\n clearTargetGroupingAttributes(target);\n const firstActivation = !target.hasAttribute('data-stack-selected');\n target.setAttribute('data-stack-selected', 'true');\n const buttonOffset = this.layerBottomDelta(\n record.homeLayer,\n selectedLayer\n );\n const targetOffset = this.layerBottomDelta(\n record.homeLayer,\n record.originLayer\n );\n void this.applyTargetProjection(\n target,\n buttonOffset,\n targetOffset,\n animateProjection\n );\n if (firstActivation) {\n if (sourceGroupLayer && sourceGroupLayer !== record.homeLayer) {\n sourceGroupLayer.requestGroupingUpdate();\n }\n record.homeLayer.requestGroupingUpdate();\n }\n } else {\n // Target authored inside the selected layer: it remains a normal\n // resident there (grouped and measured as before); only its pointer\n // projects down to the inferred origin layer.\n const targetOffset = this.layerBottomDelta(\n selectedLayer,\n record.originLayer\n );\n void this.applyTargetProjection(\n target,\n 0,\n targetOffset,\n animateProjection\n );\n }\n this.setSelectedTargetInteractivity(target, true);\n this.setTargetSelectedId(target);\n this.applySelectedTargetProjectionState(target);\n }\n\n private seedSelectedLayerSelections(selectedLayer: ObcPoiLayer): Set<Poi> {\n const seededTargets = new Set<Poi>();\n if (this.selectionMode === PoiLayerSelectionMode.None) {\n return seededTargets;\n }\n\n const selectedTargets = this.getLayerTargets(selectedLayer);\n for (const target of selectedTargets) {\n if (target.hasAttribute(ObcPoiLayerStack.STACK_RETURNING_ATTR)) {\n continue;\n }\n if (this.selectionMap.has(target)) {\n continue;\n }\n if (this.displacedTargets.has(target)) {\n continue;\n }\n if (\n this.selectionMode === PoiLayerSelectionMode.Single &&\n this.selectionMap.size > 0\n ) {\n break;\n }\n\n const originLayer = this.inferBootstrapOriginLayer(target, selectedLayer);\n this.selectionMap.set(target, {homeLayer: selectedLayer, originLayer});\n seededTargets.add(target);\n this.dispatchSelectionChange(target, null);\n }\n return seededTargets;\n }\n\n private resetSelectionForTarget(target: Poi, record?: SelectionRecord) {\n if (record) {\n this.selectionMap.delete(target);\n void this.animateTargetReturnToOrigin(target, record);\n this.dispatchSelectionChange(null, target);\n return;\n }\n target.removeAttribute('data-stack-selected');\n this.setSelectedTargetInteractivity(target, false);\n clearTargetGroupingAttributes(target);\n this.clearTargetSelectedId(target);\n this.clearTargetProjectionStyles(target);\n }\n\n private clearSelectionMapExcept(target: Poi) {\n const entries = Array.from(this.selectionMap.entries());\n entries.forEach(([other, record]) => {\n if (other === target) return;\n this.resetSelectionForTarget(other, record);\n });\n }\n\n private setupMutationObserver() {\n this.mutationObserver?.disconnect();\n this.mutationObserver = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (\n mutation.type === 'attributes' &&\n mutation.target instanceof HTMLElement\n ) {\n if (mutation.attributeName === POI_ATTR) {\n this.schedulePlacement();\n return;\n }\n }\n for (const node of Array.from(mutation.addedNodes)) {\n if (!(node instanceof HTMLElement)) continue;\n if (isPoi(node) || node.querySelector?.(`[${POI_ATTR}]`)) {\n this.schedulePlacement();\n return;\n }\n }\n }\n });\n this.mutationObserver.observe(this, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: [POI_ATTR],\n });\n }\n\n private schedulePlacement() {\n if (this.placementRaf) return;\n this.placementRaf = requestAnimationFrame(() => {\n this.placementRaf = 0;\n this.updateLayerOrders();\n this.syncSelectedLayerTargets();\n });\n }\n\n private updateLayerInactiveState(selectedLayer: ObcPoiLayer | null) {\n const layers = this.getAllLayers();\n layers.forEach((layer) => {\n if (selectedLayer && layer !== selectedLayer) {\n layer.setAttribute('data-stack-inactive', 'true');\n } else {\n layer.removeAttribute('data-stack-inactive');\n }\n });\n }\n\n private updateLayerOrders() {\n const layers = this.getAllLayers();\n layers.forEach((layer, index) => {\n layer.style.order = String(index);\n });\n\n const selectedLayer = this.getLayer('selected');\n this.updateLayerInactiveState(selectedLayer);\n }\n\n private syncSelectedLayerTargets() {\n const selectedLayer = this.getLayer('selected');\n\n if (!selectedLayer) {\n this.selectionMap.forEach((record, target) => {\n this.resetSelectionForTarget(target, record);\n });\n this.refreshDisplacedTargets();\n return;\n }\n\n const seededTargets = this.seedSelectedLayerSelections(selectedLayer);\n\n this.selectionMap.forEach((record, target) => {\n if (!target.isConnected) {\n this.selectionMap.delete(target);\n return;\n }\n if (target.hasAttribute(ObcPoiLayerStack.STACK_RETURNING_ATTR)) {\n return;\n }\n this.activateTrackedTarget(\n target,\n record,\n selectedLayer,\n !seededTargets.has(target)\n );\n });\n this.refreshDisplacedTargets();\n }\n\n /**\n * Keep deselected targets that render outside their DOM layer (targets\n * authored in the selected layer whose logical origin is another layer)\n * projected at up-to-date offsets across layer resizes.\n */\n private refreshDisplacedTargets() {\n this.displacedTargets.forEach((record, target) => {\n if (!target.isConnected) {\n this.displacedTargets.delete(target);\n return;\n }\n if (target.hasAttribute(ObcPoiLayerStack.STACK_RETURNING_ATTR)) {\n return;\n }\n const originOffset = this.layerBottomDelta(\n record.homeLayer,\n record.originLayer\n );\n void this.applyTargetProjection(\n target,\n originOffset,\n originOffset,\n false\n );\n });\n }\n\n override render() {\n return html`\n <div class=\"wrapper\">\n <slot></slot>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-poi-layer-stack': ObcPoiLayerStack;\n }\n}\n"],"mappings":"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"}