@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
@@ -10,6 +10,7 @@ export { ObcPoiObjectState as ObcPoiObjectAtonState };
10
10
  *
11
11
  * Extends `PoiBase` to provide the "aton" variant of the POI system.
12
12
  * Renders `<obc-poi>` with a slotted `<obc-poi-button-aton>`.
13
+ * See the "Coordinate Model" section in `PoiBase` (poi-base.ts) for how `x`, `y`, and `buttonY` position the marker.
13
14
  *
14
15
  * @slot - Icon content forwarded to the inner aton diamond.
15
16
  * @slot header - Optional header content forwarded to the poi button.
@@ -1 +1 @@
1
- {"version":3,"file":"poi-aton.d.ts","sourceRoot":"","sources":["../../../src/ar/poi/poi-aton.ts"],"names":[],"mappings":"AAGA,OAAO,kCAAkC,CAAC;AAC1C,OAAO,yCAAyC,CAAC;AACjD,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AACtC,OAAO,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAC,oBAAoB,EAAE,qBAAqB,EAAC,CAAC;AACrD,OAAO,EAAC,iBAAiB,IAAI,qBAAqB,EAAC,CAAC;AAEpD;;;;;;;;;;GAUG;AACH,qBACa,UAAW,SAAQ,OAAO;IAErC,QAAQ,EAAE,oBAAoB,CAA6B;IAG3D,SAAS,EAAE,qBAAqB,CAAiC;IAGjE,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAG3C,eAAe,UAAS;cAEL,cAAc;;;;;;cAId,gBAAgB;IAuBnC,OAAgB,MAAM,4BAAkB;CACzC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,UAAU,CAAC;KAC5B;CACF"}
1
+ {"version":3,"file":"poi-aton.d.ts","sourceRoot":"","sources":["../../../src/ar/poi/poi-aton.ts"],"names":[],"mappings":"AAGA,OAAO,kCAAkC,CAAC;AAC1C,OAAO,yCAAyC,CAAC;AACjD,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AACtC,OAAO,EAAC,iBAAiB,EAAC,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,EAAC,oBAAoB,EAAE,qBAAqB,EAAC,CAAC;AACrD,OAAO,EAAC,iBAAiB,IAAI,qBAAqB,EAAC,CAAC;AAEpD;;;;;;;;;;;GAWG;AACH,qBACa,UAAW,SAAQ,OAAO;IAErC,QAAQ,EAAE,oBAAoB,CAA6B;IAG3D,SAAS,EAAE,qBAAqB,CAAiC;IAGjE,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAG3C,eAAe,UAAS;cAEL,cAAc;;;;;;cAId,gBAAgB;IAwBnC,OAAgB,MAAM,4BAAkB;CACzC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,UAAU,CAAC;KAC5B;CACF"}
@@ -38,6 +38,7 @@ var ObcPoiAton = class ObcPoiAton extends PoiBase {
38
38
  .atonInteractive=${this.atonInteractive}
39
39
  >
40
40
  <slot><obi-beacon-general-east></obi-beacon-general-east></slot>
41
+ <slot name="header" slot="header"></slot>
41
42
  </obc-poi-button-aton>
42
43
  `;
43
44
  }
@@ -1 +1 @@
1
- {"version":3,"file":"poi-aton.js","names":[],"sources":["../../../src/ar/poi/poi-aton.ts"],"sourcesContent":["import {html} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {customElement} from '../../decorator.js';\nimport '../poi-button/poi-button-aton.js';\nimport '../../icons/icon-beacon-general-east.js';\nimport {PoiBase} from './poi-base.js';\nimport {ObcPoiObjectState} from '../poi-object/poi-object.js';\nimport {\n ObcPoiObjectAtonType,\n ObcPoiObjectAtonStyle,\n} from '../poi-object/poi-object-aton.js';\n\nexport {ObcPoiObjectAtonType, ObcPoiObjectAtonStyle};\nexport {ObcPoiObjectState as ObcPoiObjectAtonState};\n\n/**\n * `<obc-poi-aton>` - AtoN marker variant with layout positioning and layer integration.\n *\n * Extends `PoiBase` to provide the \"aton\" variant of the POI system.\n * Renders `<obc-poi>` with a slotted `<obc-poi-button-aton>`.\n *\n * @slot - Icon content forwarded to the inner aton diamond.\n * @slot header - Optional header content forwarded to the poi button.\n * @fires {CustomEvent<void>} obc-poi-data-layout-change - Fired when layout-driving properties change.\n * @experimental\n */\n@customElement('obc-poi-aton')\nexport class ObcPoiAton extends PoiBase {\n @property({type: String, attribute: 'aton-type'})\n atonType: ObcPoiObjectAtonType = ObcPoiObjectAtonType.AtoN;\n\n @property({type: String, attribute: 'aton-style'})\n atonStyle: ObcPoiObjectAtonStyle = ObcPoiObjectAtonStyle.Regular;\n\n @property({type: String, attribute: 'aton-state'})\n atonState: ObcPoiObjectState | null = null;\n\n @property({type: Boolean, attribute: 'aton-interactive'})\n atonInteractive = false;\n\n protected override getVisualNodes() {\n return this.queryVisualNodes('obc-poi', 'obc-poi-button-aton');\n }\n\n protected override renderButtonSlot() {\n return html`\n <obc-poi-button-aton\n slot=\"button\"\n .relativeDirection=${this.relativeDirection}\n .selected=${this.selected}\n .hasHeader=${this.hasHeader}\n .headerContent=${this.headerContent}\n .state=${this.resolvedPoiState}\n .value=${this.value}\n .overlapOpaque=${this.overlapOpaque}\n .type=${this.buttonType}\n .data=${this.data}\n .atonType=${this.atonType}\n .atonStyle=${this.atonStyle}\n .atonState=${this.atonState}\n .atonInteractive=${this.atonInteractive}\n >\n <slot><obi-beacon-general-east></obi-beacon-general-east></slot>\n </obc-poi-button-aton>\n `;\n }\n\n static override styles = PoiBase.styles;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-poi-aton': ObcPoiAton;\n }\n}\n"],"mappings":";;;;;;;;;;AA2BO,IAAM,aAAN,MAAM,mBAAmB,QAAQ;;;EAEL,KAAA,WAAA,qBAAqB;EAGnB,KAAA,YAAA,sBAAsB;EAGnB,KAAA,YAAA;EAGpB,KAAA,kBAAA;;CAElB,iBAAoC;EAClC,OAAO,KAAK,iBAAiB,WAAW,qBAAqB;CAC/D;CAEA,mBAAsC;EACpC,OAAO,IAAI;;;6BAGc,KAAK,kBAAkB;oBAChC,KAAK,SAAS;qBACb,KAAK,UAAU;yBACX,KAAK,cAAc;iBAC3B,KAAK,iBAAiB;iBACtB,KAAK,MAAM;yBACH,KAAK,cAAc;gBAC5B,KAAK,WAAW;gBAChB,KAAK,KAAK;oBACN,KAAK,SAAS;qBACb,KAAK,UAAU;qBACf,KAAK,UAAU;2BACT,KAAK,gBAAgB;;;;;CAK9C;;EAEyB,KAAA,SAAA,QAAQ;;AACnC;AAxCG,WAAA,CAAA,SAAS;CAAC,MAAM;CAAQ,WAAW;AAAW,CAAC,CAAA,GAAA,WAAA,WAAA,YAAA,KAAA,CAAA;AAG/C,WAAA,CAAA,SAAS;CAAC,MAAM;CAAQ,WAAW;AAAY,CAAC,CAAA,GAAA,WAAA,WAAA,aAAA,KAAA,CAAA;AAGhD,WAAA,CAAA,SAAS;CAAC,MAAM;CAAQ,WAAW;AAAY,CAAC,CAAA,GAAA,WAAA,WAAA,aAAA,KAAA,CAAA;AAGhD,WAAA,CAAA,SAAS;CAAC,MAAM;CAAS,WAAW;AAAkB,CAAC,CAAA,GAAA,WAAA,WAAA,mBAAA,KAAA,CAAA;AAXzD,aAAA,WAAA,CAAA,cAAc,cAAc,CAAA,GAAA,UAAA"}
1
+ {"version":3,"file":"poi-aton.js","names":[],"sources":["../../../src/ar/poi/poi-aton.ts"],"sourcesContent":["import {html} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport {customElement} from '../../decorator.js';\nimport '../poi-button/poi-button-aton.js';\nimport '../../icons/icon-beacon-general-east.js';\nimport {PoiBase} from './poi-base.js';\nimport {ObcPoiObjectState} from '../poi-object/poi-object.js';\nimport {\n ObcPoiObjectAtonType,\n ObcPoiObjectAtonStyle,\n} from '../poi-object/poi-object-aton.js';\n\nexport {ObcPoiObjectAtonType, ObcPoiObjectAtonStyle};\nexport {ObcPoiObjectState as ObcPoiObjectAtonState};\n\n/**\n * `<obc-poi-aton>` - AtoN marker variant with layout positioning and layer integration.\n *\n * Extends `PoiBase` to provide the \"aton\" variant of the POI system.\n * Renders `<obc-poi>` with a slotted `<obc-poi-button-aton>`.\n * See the \"Coordinate Model\" section in `PoiBase` (poi-base.ts) for how `x`, `y`, and `buttonY` position the marker.\n *\n * @slot - Icon content forwarded to the inner aton diamond.\n * @slot header - Optional header content forwarded to the poi button.\n * @fires {CustomEvent<void>} obc-poi-data-layout-change - Fired when layout-driving properties change.\n * @experimental\n */\n@customElement('obc-poi-aton')\nexport class ObcPoiAton extends PoiBase {\n @property({type: String, attribute: 'aton-type'})\n atonType: ObcPoiObjectAtonType = ObcPoiObjectAtonType.AtoN;\n\n @property({type: String, attribute: 'aton-style'})\n atonStyle: ObcPoiObjectAtonStyle = ObcPoiObjectAtonStyle.Regular;\n\n @property({type: String, attribute: 'aton-state'})\n atonState: ObcPoiObjectState | null = null;\n\n @property({type: Boolean, attribute: 'aton-interactive'})\n atonInteractive = false;\n\n protected override getVisualNodes() {\n return this.queryVisualNodes('obc-poi', 'obc-poi-button-aton');\n }\n\n protected override renderButtonSlot() {\n return html`\n <obc-poi-button-aton\n slot=\"button\"\n .relativeDirection=${this.relativeDirection}\n .selected=${this.selected}\n .hasHeader=${this.hasHeader}\n .headerContent=${this.headerContent}\n .state=${this.resolvedPoiState}\n .value=${this.value}\n .overlapOpaque=${this.overlapOpaque}\n .type=${this.buttonType}\n .data=${this.data}\n .atonType=${this.atonType}\n .atonStyle=${this.atonStyle}\n .atonState=${this.atonState}\n .atonInteractive=${this.atonInteractive}\n >\n <slot><obi-beacon-general-east></obi-beacon-general-east></slot>\n <slot name=\"header\" slot=\"header\"></slot>\n </obc-poi-button-aton>\n `;\n }\n\n static override styles = PoiBase.styles;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-poi-aton': ObcPoiAton;\n }\n}\n"],"mappings":";;;;;;;;;;AA4BO,IAAM,aAAN,MAAM,mBAAmB,QAAQ;;;EAEL,KAAA,WAAA,qBAAqB;EAGnB,KAAA,YAAA,sBAAsB;EAGnB,KAAA,YAAA;EAGpB,KAAA,kBAAA;;CAElB,iBAAoC;EAClC,OAAO,KAAK,iBAAiB,WAAW,qBAAqB;CAC/D;CAEA,mBAAsC;EACpC,OAAO,IAAI;;;6BAGc,KAAK,kBAAkB;oBAChC,KAAK,SAAS;qBACb,KAAK,UAAU;yBACX,KAAK,cAAc;iBAC3B,KAAK,iBAAiB;iBACtB,KAAK,MAAM;yBACH,KAAK,cAAc;gBAC5B,KAAK,WAAW;gBAChB,KAAK,KAAK;oBACN,KAAK,SAAS;qBACb,KAAK,UAAU;qBACf,KAAK,UAAU;2BACT,KAAK,gBAAgB;;;;;;CAM9C;;EAEyB,KAAA,SAAA,QAAQ;;AACnC;AAzCG,WAAA,CAAA,SAAS;CAAC,MAAM;CAAQ,WAAW;AAAW,CAAC,CAAA,GAAA,WAAA,WAAA,YAAA,KAAA,CAAA;AAG/C,WAAA,CAAA,SAAS;CAAC,MAAM;CAAQ,WAAW;AAAY,CAAC,CAAA,GAAA,WAAA,WAAA,aAAA,KAAA,CAAA;AAGhD,WAAA,CAAA,SAAS;CAAC,MAAM;CAAQ,WAAW;AAAY,CAAC,CAAA,GAAA,WAAA,WAAA,aAAA,KAAA,CAAA;AAGhD,WAAA,CAAA,SAAS;CAAC,MAAM;CAAS,WAAW;AAAkB,CAAC,CAAA,GAAA,WAAA,WAAA,mBAAA,KAAA,CAAA;AAXzD,aAAA,WAAA,CAAA,cAAc,cAAc,CAAA,GAAA,UAAA"}
@@ -1,6 +1,5 @@
1
1
  import { LitElement, TemplateResult } from 'lit';
2
2
  import { ObcPoiButtonType, ObcPoiButtonDataItem } from '../poi-button/poi-button.js';
3
- import { ObcPoiHeaderState } from '../building-blocks/poi-header/poi-header.js';
4
3
  import { ObcPoiState, ObcPoiType, ObcPoiValue, Poi, PoiDataVisualRectPreference } from './poi.js';
5
4
  import { ObcPoiPointerState, ObcPoiPointerType } from '../building-blocks/poi-pointer/poi-pointer.js';
6
5
  import './poi.js';
@@ -8,6 +7,8 @@ export { ObcPoiValue as PoiBaseValue };
8
7
  export { PoiDataVisualRectPreference as PoiBaseVisualRectPreference };
9
8
  /** @internal */
10
9
  type VisualElementPreference = PoiDataVisualRectPreference.Group | PoiDataVisualRectPreference.Anchor | PoiDataVisualRectPreference.Size;
10
+ export declare const X_FILTER_CUTOFF_HZ = 16;
11
+ export declare const Y_FILTER_CUTOFF_HZ = 16;
11
12
  /**
12
13
  * Shared base class for top-level POI variant components (`obc-poi-data`,
13
14
  * `obc-poi-aton`, `obc-poi-vessel`).
@@ -16,12 +17,29 @@ type VisualElementPreference = PoiDataVisualRectPreference.Group | PoiDataVisual
16
17
  * layout-change dispatch, and visual-query logic so that each variant
17
18
  * only needs to override `renderContent()` and `getVisualNodes()`.
18
19
  *
20
+ * ### Coordinate Model
21
+ * - `x` is the horizontal center position in px within the layer.
22
+ * - Targets are anchored at the layer's bottom edge; `y` is the connector
23
+ * line length in px extending downward from that anchor to the target
24
+ * point (default `192`, the shared `DEFAULT_LINE_LENGTH_PX`). The button
25
+ * renders at the top of the connector, inside the layer.
26
+ * - `buttonY` positions the button; its interaction with `fixedTarget` is
27
+ * described in the `obc-poi` documentation.
28
+ * - `x` and `y` updates pass through built-in low-pass filters (see
29
+ * `xFilterCutoffHz` and `yFilterCutoffHz`).
30
+ *
19
31
  * The `@fires` tag below documents the dispatch site, which lives here rather
20
32
  * than in the variants. It is deliberately duplicated on each concrete
21
33
  * subclass — that is where `custom-elements.json` and the framework wrappers
22
34
  * pick the event up, since this class is not registered. Do not remove it from
23
35
  * the subclasses. `@ignore` keeps this class out of the generated docs.
24
36
  *
37
+ * @property xFilterCutoffHz - Cutoff frequency (Hz) of the built-in low-pass filter applied to `x`.
38
+ * Lower values smooth noisy input more aggressively; `0` or a negative
39
+ * value disables filtering so `x` is applied directly.
40
+ * @property yFilterCutoffHz - Cutoff frequency (Hz) of the built-in low-pass filter applied to `y`.
41
+ * Lower values smooth noisy input more aggressively; `0` or a negative
42
+ * value disables filtering so `y` is applied directly.
25
43
  * @fires {CustomEvent<void>} obc-poi-data-layout-change - Fired when layout-driving properties change. Bubbles and is composed.
26
44
  * @ignore
27
45
  */
@@ -46,6 +64,8 @@ export declare class PoiBase extends LitElement implements Poi {
46
64
  x: number;
47
65
  y: number;
48
66
  buttonY: number | null;
67
+ xFilterCutoffHz: number;
68
+ yFilterCutoffHz: number;
49
69
  fixedTarget: boolean;
50
70
  boxWidth: number | null;
51
71
  boxHeight: number | null;
@@ -61,9 +81,19 @@ export declare class PoiBase extends LitElement implements Poi {
61
81
  private lastXFilterTimestampMs;
62
82
  private xFilterRaf;
63
83
  private xMovingHintTimeout;
84
+ private get resolvedXFilterCutoffHz();
85
+ private filteredY;
86
+ private yFilterTarget;
87
+ private yFilterInitialized;
88
+ private lastYFilterTimestampMs;
89
+ private yFilterRaf;
90
+ private get resolvedYFilterCutoffHz();
64
91
  private dispatchLayoutChange;
65
92
  private stepXFilter;
66
93
  private syncXFilterTarget;
94
+ private stepYFilter;
95
+ private applyFilteredY;
96
+ private syncYFilterTarget;
67
97
  private markXMoving;
68
98
  disconnectedCallback(): void;
69
99
  private setupHeaderObserver;
@@ -102,7 +132,7 @@ export declare class PoiBase extends LitElement implements Poi {
102
132
  getVisualRect(preference?: PoiDataVisualRectPreference): DOMRect;
103
133
  getVisualElement(preference?: VisualElementPreference): HTMLElement;
104
134
  getPointerElement(): HTMLElement | null;
105
- /** Public `y` normalized as the target Y input. */
135
+ /** Public `y` normalized as the target Y input, after the y filter. */
106
136
  protected get resolvedTargetY(): number;
107
137
  /** Public `buttonY` normalized as the button Y input. */
108
138
  protected get resolvedButtonY(): number;
@@ -114,10 +144,14 @@ export declare class PoiBase extends LitElement implements Poi {
114
144
  * `<obc-poi>` wrapper with all shared property bindings.
115
145
  */
116
146
  protected renderButtonSlot(): TemplateResult;
117
- protected get resolvedHeaderState(): ObcPoiHeaderState;
147
+ /**
148
+ * Auto-enable `hasHeader` when the consumer slots header content directly
149
+ * (outside a stack, which manages `hasHeader` itself). Header elements stay
150
+ * in the consumer's light DOM and reach the inner button through the
151
+ * `<slot name="header">` forwarding chain; their `state` is synced by
152
+ * `obc-poi-button`.
153
+ */
118
154
  private syncHeaderContent;
119
- private applyHeaderState;
120
- private syncHeaderState;
121
155
  render(): TemplateResult<1>;
122
156
  static styles: import('lit').CSSResult[];
123
157
  }
@@ -1 +1 @@
1
- {"version":3,"file":"poi-base.d.ts","sourceRoot":"","sources":["../../../src/ar/poi/poi-base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAE,cAAc,EAAkB,MAAM,KAAK,CAAC;AAGhE,OAAO,UAAU,CAAC;AAClB,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAC,iBAAiB,EAAC,MAAM,6CAA6C,CAAC;AAC9E,OAAO,EAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAC,MAAM,UAAU,CAAC;AAC9D,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EAClB,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAW,GAAG,EAAE,2BAA2B,EAAC,MAAM,UAAU,CAAC;AAEpE,OAAO,EAAC,WAAW,IAAI,YAAY,EAAC,CAAC;AACrC,OAAO,EAAC,2BAA2B,IAAI,2BAA2B,EAAC,CAAC;AAEpE,gBAAgB;AAChB,KAAK,uBAAuB,GACxB,2BAA2B,CAAC,KAAK,GACjC,2BAA2B,CAAC,MAAM,GAClC,2BAA2B,CAAC,IAAI,CAAC;AAmBrC;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,OAAQ,SAAQ,UAAW,YAAW,GAAG;IACpD,OAAO,CAAC,cAAc,CAAC,CAAmB;IAC1C,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,cAAc,CAAK;IAElB,iBAAiB;IASA,IAAI,EAAE,UAAU,CAAmB;IACnC,KAAK,EAAE,WAAW,CAAyB;IAC3C,KAAK,EAAE,WAAW,CAAuB;IACxC,QAAQ,UAAS;IAE5C,UAAU,mBAA2B;IAErC,aAAa,UAAS;IAEtB,IAAI,EAAE,oBAAoB,EAAE,CAAM;IACkB,SAAS,UAAS;IACf,aAAa,SAAM;IAC/C,UAAU,UAAS;IAE9C,WAAW,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAE7C,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAQ;IACrB,iBAAiB,SAAK;IAItB,CAAC,SAAK;IACN,CAAC,SAAO;IACe,OAAO,EAAE,MAAM,GAAG,IAAI,CAAK;IACtB,WAAW,UAAS;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAClE;IAC4C,SAAS,EAAE,MAAM,GAAG,IAAI,CACpE;IAC+C,YAAY,SAAO;IAEzE,eAAe,UAAS;IAExB,IACI,aAAa,IAAI,MAAM,CAE1B;IAED,IAAI,aAAa,CAAC,KAAK,EAAE,MAAM,EAS9B;IAED,IACI,aAAa,IAAI,MAAM,CAE1B;IAED,IAAI,aAAa,CAAC,KAAK,EAAE,MAAM,EAS9B;IAID,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,sBAAsB,CAAK;IACnC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,kBAAkB,CAAuB;IAIjD,OAAO,CAAC,oBAAoB;IAW5B,OAAO,CAAC,WAAW,CAsCjB;IAEF,OAAO,CAAC,iBAAiB;IA8BzB,OAAO,CAAC,WAAW;IAaV,oBAAoB;IAe7B,OAAO,CAAC,mBAAmB;IA2BlB,OAAO,CAAC,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;cA8BrC,YAAY,CAAC,kBAAkB,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC;IAOxE,OAAO,CAAC,cAAc;IAYtB,SAAS,KAAK,sBAAsB,IAAI,MAAM,CAS7C;IAED,SAAS,KAAK,eAAe,IAAI,UAAU,CAI1C;IAED,SAAS,KAAK,gBAAgB,IAAI,WAAW,CAI5C;IAID;;;OAGG;IACH,SAAS,CAAC,cAAc,IAAI;QAC1B,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;QACxB,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;QAC3B,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;QAC5B,aAAa,EAAE,WAAW,GAAG,IAAI,CAAC;KACnC;IAID;;;;;OAKG;IACH,SAAS,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;;;;;;IAc5D,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,kBAAkB;IAWnB,uBAAuB,CAAC,eAAe,SAAI;IAM3C,2BAA2B,CAChC,aAAa,EAAE,MAAM,EACrB,aAAa,SAAsB;IAoC9B,aAAa,CAClB,UAAU,GAAE,2BAAiE,GAC5E,OAAO;IAkDH,gBAAgB,CACrB,UAAU,GAAE,uBAA0D,GACrE,WAAW;IAsBP,iBAAiB,IAAI,WAAW,GAAG,IAAI;IAW9C,mDAAmD;IACnD,SAAS,KAAK,eAAe,IAAI,MAAM,CAEtC;IAED,yDAAyD;IACzD,SAAS,KAAK,eAAe,IAAI,MAAM,CAItC;IAED,gDAAgD;IAChD,SAAS,KAAK,qBAAqB,IAAI,MAAM,CAE5C;IAED;;;;OAIG;IACH,SAAS,CAAC,gBAAgB,IAAI,cAAc;IAoB5C,SAAS,KAAK,mBAAmB,IAAI,iBAAiB,CAcrD;IAED,OAAO,CAAC,iBAAiB;IAgCzB,OAAO,CAAC,gBAAgB;IAcxB,OAAO,CAAC,eAAe;IAId,MAAM;IAgCf,OAAgB,MAAM,4BAA+B;CACtD"}
1
+ {"version":3,"file":"poi-base.d.ts","sourceRoot":"","sources":["../../../src/ar/poi/poi-base.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,5 @@
1
1
  import { clamp } from "../../svghelpers/math.js";
2
2
  import __decorate from "../../_virtual/_@oxc-project_runtime@0.150.0/helpers/esm/decorate.js";
3
- import { ObcPoiHeaderState } from "../building-blocks/poi-header/poi-header.js";
4
3
  import { ObcPoiButtonType } from "../poi-button/poi-button.js";
5
4
  import poi_base_default from "./poi-base.css.js";
6
5
  import { ObcPoiState, ObcPoiType, ObcPoiValue, POI_ATTR, PoiDataVisualRectPreference } from "./poi.js";
@@ -11,6 +10,7 @@ function stripWhitespaceTextNodes(el) {
11
10
  for (const node of Array.from(el.childNodes)) if (node.nodeType === Node.TEXT_NODE && (node.textContent ?? "").trim() === "") node.remove();
12
11
  }
13
12
  var X_FILTER_CUTOFF_HZ = 16;
13
+ var Y_FILTER_CUTOFF_HZ = 16;
14
14
  var X_FILTER_DEADBAND_PX = .1;
15
15
  var X_MOVING_HINT_MS = 120;
16
16
  var VALID_POI_TYPES = new Set(Object.values(ObcPoiType));
@@ -23,12 +23,29 @@ var VALID_POI_STATES = new Set(Object.values(ObcPoiState));
23
23
  * layout-change dispatch, and visual-query logic so that each variant
24
24
  * only needs to override `renderContent()` and `getVisualNodes()`.
25
25
  *
26
+ * ### Coordinate Model
27
+ * - `x` is the horizontal center position in px within the layer.
28
+ * - Targets are anchored at the layer's bottom edge; `y` is the connector
29
+ * line length in px extending downward from that anchor to the target
30
+ * point (default `192`, the shared `DEFAULT_LINE_LENGTH_PX`). The button
31
+ * renders at the top of the connector, inside the layer.
32
+ * - `buttonY` positions the button; its interaction with `fixedTarget` is
33
+ * described in the `obc-poi` documentation.
34
+ * - `x` and `y` updates pass through built-in low-pass filters (see
35
+ * `xFilterCutoffHz` and `yFilterCutoffHz`).
36
+ *
26
37
  * The `@fires` tag below documents the dispatch site, which lives here rather
27
38
  * than in the variants. It is deliberately duplicated on each concrete
28
39
  * subclass — that is where `custom-elements.json` and the framework wrappers
29
40
  * pick the event up, since this class is not registered. Do not remove it from
30
41
  * the subclasses. `@ignore` keeps this class out of the generated docs.
31
42
  *
43
+ * @property xFilterCutoffHz - Cutoff frequency (Hz) of the built-in low-pass filter applied to `x`.
44
+ * Lower values smooth noisy input more aggressively; `0` or a negative
45
+ * value disables filtering so `x` is applied directly.
46
+ * @property yFilterCutoffHz - Cutoff frequency (Hz) of the built-in low-pass filter applied to `y`.
47
+ * Lower values smooth noisy input more aggressively; `0` or a negative
48
+ * value disables filtering so `y` is applied directly.
32
49
  * @fires {CustomEvent<void>} obc-poi-data-layout-change - Fired when layout-driving properties change. Bubbles and is composed.
33
50
  * @ignore
34
51
  */
@@ -53,6 +70,8 @@ var PoiBase = class extends LitElement {
53
70
  this.x = 0;
54
71
  this.y = 192;
55
72
  this.buttonY = 0;
73
+ this.xFilterCutoffHz = 16;
74
+ this.yFilterCutoffHz = 16;
56
75
  this.fixedTarget = false;
57
76
  this.boxWidth = null;
58
77
  this.boxHeight = null;
@@ -64,12 +83,18 @@ var PoiBase = class extends LitElement {
64
83
  this.lastXFilterTimestampMs = 0;
65
84
  this.xFilterRaf = 0;
66
85
  this.xMovingHintTimeout = null;
86
+ this.filteredY = 0;
87
+ this.yFilterTarget = 0;
88
+ this.yFilterInitialized = false;
89
+ this.lastYFilterTimestampMs = 0;
90
+ this.yFilterRaf = 0;
67
91
  this.stepXFilter = (nowMs) => {
68
92
  this.xFilterRaf = 0;
69
93
  if (!this.isConnected || !this.xFilterInitialized) return;
70
94
  const dtSeconds = this.lastXFilterTimestampMs > 0 ? clamp((nowMs - this.lastXFilterTimestampMs) / 1e3, 1 / 120, .25) : 1 / 60;
71
95
  this.lastXFilterTimestampMs = nowMs;
72
- const alpha = 1 - Math.exp(-2 * Math.PI * X_FILTER_CUTOFF_HZ * dtSeconds);
96
+ const cutoffHz = this.resolvedXFilterCutoffHz;
97
+ const alpha = cutoffHz <= 0 ? 1 : 1 - Math.exp(-2 * Math.PI * cutoffHz * dtSeconds);
73
98
  const delta = this.xFilterTarget - this.filteredX;
74
99
  const nextX = Math.abs(delta) <= X_FILTER_DEADBAND_PX ? this.xFilterTarget : this.filteredX + delta * alpha;
75
100
  const changed = Math.abs(nextX - this.filteredX) > 1e-6;
@@ -88,6 +113,26 @@ var PoiBase = class extends LitElement {
88
113
  this.markXMoving();
89
114
  this.xFilterRaf = requestAnimationFrame(this.stepXFilter);
90
115
  };
116
+ this.stepYFilter = (nowMs) => {
117
+ this.yFilterRaf = 0;
118
+ if (!this.isConnected || !this.yFilterInitialized) return;
119
+ const dtSeconds = this.lastYFilterTimestampMs > 0 ? clamp((nowMs - this.lastYFilterTimestampMs) / 1e3, 1 / 120, .25) : 1 / 60;
120
+ this.lastYFilterTimestampMs = nowMs;
121
+ const cutoffHz = this.resolvedYFilterCutoffHz;
122
+ const alpha = cutoffHz <= 0 ? 1 : 1 - Math.exp(-2 * Math.PI * cutoffHz * dtSeconds);
123
+ const delta = this.yFilterTarget - this.filteredY;
124
+ const nextY = Math.abs(delta) <= X_FILTER_DEADBAND_PX ? this.yFilterTarget : this.filteredY + delta * alpha;
125
+ const changed = Math.abs(nextY - this.filteredY) > 1e-6;
126
+ this.filteredY = nextY;
127
+ if (changed) this.applyFilteredY();
128
+ if (Math.abs(this.yFilterTarget - this.filteredY) <= X_FILTER_DEADBAND_PX) {
129
+ this.filteredY = this.yFilterTarget;
130
+ this.applyFilteredY();
131
+ this.lastYFilterTimestampMs = 0;
132
+ return;
133
+ }
134
+ this.yFilterRaf = requestAnimationFrame(this.stepYFilter);
135
+ };
91
136
  }
92
137
  connectedCallback() {
93
138
  stripWhitespaceTextNodes(this);
@@ -115,6 +160,12 @@ var PoiBase = class extends LitElement {
115
160
  this._targetOffsetX = nextValue;
116
161
  this.requestUpdate("targetOffsetX", oldValue);
117
162
  }
163
+ get resolvedXFilterCutoffHz() {
164
+ return Number.isFinite(this.xFilterCutoffHz) ? this.xFilterCutoffHz : 16;
165
+ }
166
+ get resolvedYFilterCutoffHz() {
167
+ return Number.isFinite(this.yFilterCutoffHz) ? this.yFilterCutoffHz : 16;
168
+ }
118
169
  dispatchLayoutChange() {
119
170
  this.dispatchEvent(new CustomEvent("obc-poi-data-layout-change", {
120
171
  bubbles: true,
@@ -130,7 +181,7 @@ var PoiBase = class extends LitElement {
130
181
  this.markXMoving();
131
182
  return;
132
183
  }
133
- if (Math.abs(nextX - this.filteredX) <= X_FILTER_DEADBAND_PX) {
184
+ if (this.resolvedXFilterCutoffHz <= 0 || Math.abs(nextX - this.filteredX) <= X_FILTER_DEADBAND_PX) {
134
185
  this.filteredX = this.xFilterTarget;
135
186
  this.style.setProperty("--obc-poi-data-x", `${this.filteredX}px`);
136
187
  if (this.xFilterRaf) {
@@ -147,6 +198,33 @@ var PoiBase = class extends LitElement {
147
198
  this.xFilterRaf = requestAnimationFrame(this.stepXFilter);
148
199
  }
149
200
  }
201
+ applyFilteredY() {
202
+ this.requestUpdate();
203
+ this.updatePosition();
204
+ this.dispatchLayoutChange();
205
+ }
206
+ syncYFilterTarget(nextY) {
207
+ this.yFilterTarget = nextY;
208
+ if (!this.yFilterInitialized) {
209
+ this.yFilterInitialized = true;
210
+ this.filteredY = nextY;
211
+ return;
212
+ }
213
+ if (this.resolvedYFilterCutoffHz <= 0 || Math.abs(nextY - this.filteredY) <= X_FILTER_DEADBAND_PX) {
214
+ this.filteredY = this.yFilterTarget;
215
+ this.applyFilteredY();
216
+ if (this.yFilterRaf) {
217
+ cancelAnimationFrame(this.yFilterRaf);
218
+ this.yFilterRaf = 0;
219
+ }
220
+ this.lastYFilterTimestampMs = 0;
221
+ return;
222
+ }
223
+ if (!this.yFilterRaf) {
224
+ this.lastYFilterTimestampMs = 0;
225
+ this.yFilterRaf = requestAnimationFrame(this.stepYFilter);
226
+ }
227
+ }
150
228
  markXMoving() {
151
229
  this.setAttribute("data-x-moving", "true");
152
230
  if (this.xMovingHintTimeout !== null) window.clearTimeout(this.xMovingHintTimeout);
@@ -164,6 +242,11 @@ var PoiBase = class extends LitElement {
164
242
  this.xFilterRaf = 0;
165
243
  }
166
244
  this.lastXFilterTimestampMs = 0;
245
+ if (this.yFilterRaf) {
246
+ cancelAnimationFrame(this.yFilterRaf);
247
+ this.yFilterRaf = 0;
248
+ }
249
+ this.lastYFilterTimestampMs = 0;
167
250
  if (this.xMovingHintTimeout !== null) {
168
251
  window.clearTimeout(this.xMovingHintTimeout);
169
252
  this.xMovingHintTimeout = null;
@@ -175,12 +258,10 @@ var PoiBase = class extends LitElement {
175
258
  for (const mutation of mutations) {
176
259
  if (mutation.type === "childList") {
177
260
  this.syncHeaderContent();
178
- this.syncHeaderState();
179
261
  return;
180
262
  }
181
263
  if (mutation.type === "attributes" && mutation.target instanceof HTMLElement && mutation.target.getAttribute("slot") === "header") {
182
264
  this.syncHeaderContent();
183
- this.syncHeaderState();
184
265
  return;
185
266
  }
186
267
  }
@@ -193,17 +274,16 @@ var PoiBase = class extends LitElement {
193
274
  }
194
275
  updated(changedProperties) {
195
276
  if (changedProperties.has("x")) this.syncXFilterTarget(Number.isFinite(this.x) ? this.x : 0);
277
+ if (changedProperties.has("y")) this.syncYFilterTarget(Number.isFinite(this.y) ? this.y : 0);
196
278
  if (changedProperties.has("buttonY") || changedProperties.has("y") || changedProperties.has("fixedTarget") || changedProperties.has("selected") || changedProperties.has("type")) {
197
279
  this.updatePosition();
198
280
  this.syncInnerPoiLayout();
199
281
  }
200
282
  if (changedProperties.has("x") || changedProperties.has("buttonY") || changedProperties.has("y") || changedProperties.has("buttonOffsetX") || changedProperties.has("targetOffsetX") || changedProperties.has("fixedTarget") || changedProperties.has("selected") || changedProperties.has("type")) this.dispatchLayoutChange();
201
283
  this.syncHeaderContent();
202
- this.syncHeaderState();
203
284
  }
204
285
  firstUpdated(_changedProperties) {
205
286
  this.syncHeaderContent();
206
- this.syncHeaderState();
207
287
  }
208
288
  updatePosition() {
209
289
  if (this.fixedTarget) {
@@ -307,8 +387,9 @@ var PoiBase = class extends LitElement {
307
387
  const { poi } = this.getVisualNodes();
308
388
  return poi?.shadowRoot?.querySelector("obc-poi-pointer.pointer") ?? null;
309
389
  }
310
- /** Public `y` normalized as the target Y input. */
390
+ /** Public `y` normalized as the target Y input, after the y filter. */
311
391
  get resolvedTargetY() {
392
+ if (this.yFilterInitialized) return this.filteredY;
312
393
  return Number.isFinite(this.y) ? this.y : 0;
313
394
  }
314
395
  /** Public `buttonY` normalized as the button Y input. */
@@ -340,38 +421,20 @@ var PoiBase = class extends LitElement {
340
421
  .data=${this.data}
341
422
  >
342
423
  <slot></slot>
424
+ <slot name="header" slot="header"></slot>
343
425
  </obc-poi-button>
344
426
  `;
345
427
  }
346
- get resolvedHeaderState() {
347
- switch (this.resolvedPoiState) {
348
- case ObcPoiState.Caution: return ObcPoiHeaderState.Caution;
349
- case ObcPoiState.Warning: return ObcPoiHeaderState.Warning;
350
- case ObcPoiState.Alarm: return ObcPoiHeaderState.Alarm;
351
- case ObcPoiState.Enabled:
352
- default: return this.selected ? ObcPoiHeaderState.Selected : ObcPoiHeaderState.Enabled;
353
- }
354
- }
428
+ /**
429
+ * Auto-enable `hasHeader` when the consumer slots header content directly
430
+ * (outside a stack, which manages `hasHeader` itself). Header elements stay
431
+ * in the consumer's light DOM and reach the inner button through the
432
+ * `<slot name="header">` forwarding chain; their `state` is synced by
433
+ * `obc-poi-button`.
434
+ */
355
435
  syncHeaderContent() {
356
- const headerChildren = Array.from(this.children).filter((child) => child instanceof HTMLElement && child.getAttribute("slot") === "header");
357
- if (headerChildren.length === 0 && !this.hasHeader) return;
358
- if (headerChildren.length > 0 && !this.hasHeader && this.closest("obc-poi-layer-stack") === null) this.hasHeader = true;
359
- const target = this.shadowRoot?.querySelector("[slot=\"button\"]") ?? this.shadowRoot?.querySelector("obc-poi");
360
- if (!target) return;
361
- for (const child of headerChildren) {
362
- if (child.parentElement !== target) target.appendChild(child);
363
- this.applyHeaderState(child);
364
- }
365
- }
366
- applyHeaderState(root) {
367
- const headers = [...root instanceof Element && root.matches("obc-poi-header") ? [root] : [], ...root.querySelectorAll("obc-poi-header")];
368
- for (const header of headers) {
369
- header.state = this.resolvedHeaderState;
370
- header.setAttribute("state", this.resolvedHeaderState);
371
- }
372
- }
373
- syncHeaderState() {
374
- this.applyHeaderState(this.renderRoot);
436
+ if (this.hasHeader) return;
437
+ if (Array.from(this.children).some((child) => child instanceof HTMLElement && child.getAttribute("slot") === "header") && this.closest("obc-poi-layer-stack") === null) this.hasHeader = true;
375
438
  }
376
439
  render() {
377
440
  return html`
@@ -448,6 +511,14 @@ __decorate([property({
448
511
  type: Number,
449
512
  attribute: "button-y"
450
513
  })], PoiBase.prototype, "buttonY", void 0);
514
+ __decorate([property({
515
+ type: Number,
516
+ attribute: "x-filter-cutoff-hz"
517
+ })], PoiBase.prototype, "xFilterCutoffHz", void 0);
518
+ __decorate([property({
519
+ type: Number,
520
+ attribute: "y-filter-cutoff-hz"
521
+ })], PoiBase.prototype, "yFilterCutoffHz", void 0);
451
522
  __decorate([property({
452
523
  type: Boolean,
453
524
  attribute: "fixed-target"
@@ -477,6 +548,6 @@ __decorate([property({
477
548
  attribute: "target-offset-x"
478
549
  })], PoiBase.prototype, "targetOffsetX", null);
479
550
  //#endregion
480
- export { PoiBase, ObcPoiValue as PoiBaseValue, PoiDataVisualRectPreference as PoiBaseVisualRectPreference };
551
+ export { PoiBase, ObcPoiValue as PoiBaseValue, PoiDataVisualRectPreference as PoiBaseVisualRectPreference, X_FILTER_CUTOFF_HZ, Y_FILTER_CUTOFF_HZ };
481
552
 
482
553
  //# sourceMappingURL=poi-base.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"poi-base.js","names":[],"sources":["../../../src/ar/poi/poi-base.ts"],"sourcesContent":["import {LitElement, TemplateResult, html, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport componentStyle from './poi-base.css?inline';\nimport './poi.js';\nimport {\n ObcPoiButtonType,\n ObcPoiButtonDataItem,\n} from '../poi-button/poi-button.js';\nimport {ObcPoiHeaderState} from '../building-blocks/poi-header/poi-header.js';\nimport {ObcPoiState, ObcPoiType, ObcPoiValue} from './poi.js';\nimport {\n ObcPoiPointerState,\n ObcPoiPointerType,\n} from '../building-blocks/poi-pointer/poi-pointer.js';\nimport {POI_ATTR, Poi, PoiDataVisualRectPreference} from './poi.js';\nimport {clamp} from '../../svghelpers/math.js';\nexport {ObcPoiValue as PoiBaseValue};\nexport {PoiDataVisualRectPreference as PoiBaseVisualRectPreference};\n\n/** @internal */\ntype VisualElementPreference =\n | PoiDataVisualRectPreference.Group\n | PoiDataVisualRectPreference.Anchor\n | PoiDataVisualRectPreference.Size;\n\nfunction stripWhitespaceTextNodes(el: Element): void {\n for (const node of Array.from(el.childNodes)) {\n if (\n node.nodeType === Node.TEXT_NODE &&\n (node.textContent ?? '').trim() === ''\n ) {\n node.remove();\n }\n }\n}\n\nconst X_FILTER_CUTOFF_HZ = 16;\nconst X_FILTER_DEADBAND_PX = 0.1;\nconst X_MOVING_HINT_MS = 120;\nconst VALID_POI_TYPES = new Set(Object.values(ObcPoiType));\nconst VALID_POI_STATES = new Set(Object.values(ObcPoiState));\n\n/**\n * Shared base class for top-level POI variant components (`obc-poi-data`,\n * `obc-poi-aton`, `obc-poi-vessel`).\n *\n * Implements `Poi` and contains all positioning, X-filter,\n * layout-change dispatch, and visual-query logic so that each variant\n * only needs to override `renderContent()` and `getVisualNodes()`.\n *\n * The `@fires` tag below documents the dispatch site, which lives here rather\n * than in the variants. It is deliberately duplicated on each concrete\n * subclass — that is where `custom-elements.json` and the framework wrappers\n * pick the event up, since this class is not registered. Do not remove it from\n * the subclasses. `@ignore` keeps this class out of the generated docs.\n *\n * @fires {CustomEvent<void>} obc-poi-data-layout-change - Fired when layout-driving properties change. Bubbles and is composed.\n * @ignore\n */\nexport class PoiBase extends LitElement implements Poi {\n private headerObserver?: MutationObserver;\n private _buttonOffsetX = 0;\n private _targetOffsetX = 0;\n\n override connectedCallback() {\n stripWhitespaceTextNodes(this);\n super.connectedCallback();\n this.setAttribute(POI_ATTR, '');\n this.setupHeaderObserver();\n }\n\n /* ---------- POI marker properties ---------- */\n\n @property({type: String}) type: ObcPoiType = ObcPoiType.Line;\n @property({type: String}) value: ObcPoiValue = ObcPoiValue.Unchecked;\n @property({type: String}) state: ObcPoiState = ObcPoiState.Enabled;\n @property({type: Boolean}) selected = false;\n @property({type: String, attribute: 'button-type'})\n buttonType = ObcPoiButtonType.Button;\n @property({type: Boolean, attribute: 'overlap-opaque'})\n overlapOpaque = false;\n @property({type: Array, attribute: false})\n data: ObcPoiButtonDataItem[] = [];\n @property({type: Boolean, attribute: 'has-header'}) hasHeader = false;\n @property({type: String, attribute: 'header-content'}) headerContent = '';\n @property({type: Boolean}) hasPointer = false;\n @property({type: String, attribute: 'pointer-type'})\n pointerType: ObcPoiPointerType | null = null;\n @property({type: String, attribute: 'pointer-state'})\n pointerState: ObcPoiPointerState | null = null;\n @property({type: Number}) relativeDirection = 0;\n\n /* ---------- Poi — position ---------- */\n\n @property({type: Number}) x = 0;\n @property({type: Number}) y = 192;\n @property({type: Number, attribute: 'button-y'}) buttonY: number | null = 0;\n @property({type: Boolean, attribute: 'fixed-target'}) fixedTarget = false;\n @property({type: Number, attribute: 'box-width'}) boxWidth: number | null =\n null;\n @property({type: Number, attribute: 'box-height'}) boxHeight: number | null =\n null;\n @property({type: Number, attribute: 'outside-angle'}) outsideAngle = 315;\n @property({type: Boolean, attribute: 'animate-position'})\n animatePosition = false;\n\n @property({type: Number, attribute: 'button-offset-x'})\n get buttonOffsetX(): number {\n return this._buttonOffsetX;\n }\n\n set buttonOffsetX(value: number) {\n const nextValue = Number.isFinite(value) ? value : 0;\n const oldValue = this._buttonOffsetX;\n if (oldValue === nextValue) {\n return;\n }\n\n this._buttonOffsetX = nextValue;\n this.requestUpdate('buttonOffsetX', oldValue);\n }\n\n @property({type: Number, attribute: 'target-offset-x'})\n get targetOffsetX(): number {\n return this._targetOffsetX;\n }\n\n set targetOffsetX(value: number) {\n const nextValue = Number.isFinite(value) ? value : 0;\n const oldValue = this._targetOffsetX;\n if (oldValue === nextValue) {\n return;\n }\n\n this._targetOffsetX = nextValue;\n this.requestUpdate('targetOffsetX', oldValue);\n }\n\n /* ---------- X-filter state ---------- */\n\n private filteredX = 0;\n private xFilterTarget = 0;\n private xFilterInitialized = false;\n private lastXFilterTimestampMs = 0;\n private xFilterRaf = 0;\n private xMovingHintTimeout: number | null = null;\n\n /* ---------- Layout change ---------- */\n\n private dispatchLayoutChange() {\n this.dispatchEvent(\n new CustomEvent('obc-poi-data-layout-change', {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n /* ---------- X filter (low-pass) ---------- */\n\n private stepXFilter = (nowMs: number) => {\n this.xFilterRaf = 0;\n if (!this.isConnected || !this.xFilterInitialized) {\n return;\n }\n\n const dtSeconds =\n this.lastXFilterTimestampMs > 0\n ? clamp((nowMs - this.lastXFilterTimestampMs) / 1000, 1 / 120, 0.25)\n : 1 / 60;\n this.lastXFilterTimestampMs = nowMs;\n\n const alpha = 1 - Math.exp(-2 * Math.PI * X_FILTER_CUTOFF_HZ * dtSeconds);\n const delta = this.xFilterTarget - this.filteredX;\n const nextX =\n Math.abs(delta) <= X_FILTER_DEADBAND_PX\n ? this.xFilterTarget\n : this.filteredX + delta * alpha;\n const changed = Math.abs(nextX - this.filteredX) > 1e-6;\n this.filteredX = nextX;\n if (changed) {\n this.style.setProperty('--obc-poi-data-x', `${this.filteredX}px`);\n this.dispatchLayoutChange();\n }\n\n const settled =\n Math.abs(this.xFilterTarget - this.filteredX) <= X_FILTER_DEADBAND_PX;\n\n if (settled) {\n this.filteredX = this.xFilterTarget;\n this.style.setProperty('--obc-poi-data-x', `${this.filteredX}px`);\n this.lastXFilterTimestampMs = 0;\n this.markXMoving();\n return;\n }\n\n this.markXMoving();\n this.xFilterRaf = requestAnimationFrame(this.stepXFilter);\n };\n\n private syncXFilterTarget(nextX: number) {\n this.xFilterTarget = nextX;\n\n if (!this.xFilterInitialized) {\n this.xFilterInitialized = true;\n this.filteredX = nextX;\n this.style.setProperty('--obc-poi-data-x', `${this.filteredX}px`);\n this.markXMoving();\n return;\n }\n\n if (Math.abs(nextX - this.filteredX) <= X_FILTER_DEADBAND_PX) {\n this.filteredX = this.xFilterTarget;\n this.style.setProperty('--obc-poi-data-x', `${this.filteredX}px`);\n if (this.xFilterRaf) {\n cancelAnimationFrame(this.xFilterRaf);\n this.xFilterRaf = 0;\n }\n this.lastXFilterTimestampMs = 0;\n this.markXMoving();\n return;\n }\n\n if (!this.xFilterRaf) {\n this.lastXFilterTimestampMs = 0;\n this.markXMoving();\n this.xFilterRaf = requestAnimationFrame(this.stepXFilter);\n }\n }\n\n private markXMoving() {\n this.setAttribute('data-x-moving', 'true');\n if (this.xMovingHintTimeout !== null) {\n window.clearTimeout(this.xMovingHintTimeout);\n }\n this.xMovingHintTimeout = window.setTimeout(() => {\n this.removeAttribute('data-x-moving');\n this.xMovingHintTimeout = null;\n }, X_MOVING_HINT_MS);\n }\n\n /* ---------- Lifecycle ---------- */\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.headerObserver?.disconnect();\n this.headerObserver = undefined;\n if (this.xFilterRaf) {\n cancelAnimationFrame(this.xFilterRaf);\n this.xFilterRaf = 0;\n }\n this.lastXFilterTimestampMs = 0;\n if (this.xMovingHintTimeout !== null) {\n window.clearTimeout(this.xMovingHintTimeout);\n this.xMovingHintTimeout = null;\n }\n }\n\n private setupHeaderObserver() {\n this.headerObserver?.disconnect();\n this.headerObserver = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (mutation.type === 'childList') {\n this.syncHeaderContent();\n this.syncHeaderState();\n return;\n }\n if (\n mutation.type === 'attributes' &&\n mutation.target instanceof HTMLElement &&\n mutation.target.getAttribute('slot') === 'header'\n ) {\n this.syncHeaderContent();\n this.syncHeaderState();\n return;\n }\n }\n });\n this.headerObserver.observe(this, {\n childList: true,\n attributes: true,\n attributeFilter: ['slot'],\n });\n }\n\n override updated(changedProperties: Map<string, unknown>) {\n if (changedProperties.has('x')) {\n this.syncXFilterTarget(Number.isFinite(this.x) ? this.x : 0);\n }\n if (\n changedProperties.has('buttonY') ||\n changedProperties.has('y') ||\n changedProperties.has('fixedTarget') ||\n changedProperties.has('selected') ||\n changedProperties.has('type')\n ) {\n this.updatePosition();\n this.syncInnerPoiLayout();\n }\n if (\n changedProperties.has('x') ||\n changedProperties.has('buttonY') ||\n changedProperties.has('y') ||\n changedProperties.has('buttonOffsetX') ||\n changedProperties.has('targetOffsetX') ||\n changedProperties.has('fixedTarget') ||\n changedProperties.has('selected') ||\n changedProperties.has('type')\n ) {\n this.dispatchLayoutChange();\n }\n this.syncHeaderContent();\n this.syncHeaderState();\n }\n\n protected override firstUpdated(_changedProperties: Map<string, unknown>) {\n this.syncHeaderContent();\n this.syncHeaderState();\n }\n\n /* ---------- Vertical positioning ---------- */\n\n private updatePosition() {\n if (this.fixedTarget) {\n if (Number.isFinite(this.resolvedButtonY)) {\n this.style.top = `${this.resolvedButtonY - this.resolvedTargetY}px`;\n } else {\n this.style.removeProperty('top');\n }\n } else {\n this.style.removeProperty('top');\n }\n }\n\n protected get selectedVerticalOffset(): number {\n if (!this.selected) {\n return 0;\n }\n const offset = getComputedStyle(this).getPropertyValue(\n '--obc-poi-target-selected-vertical-offset'\n );\n const parsed = Number.parseFloat(offset);\n return Number.isFinite(parsed) ? parsed : 0;\n }\n\n protected get resolvedPoiType(): ObcPoiType {\n return VALID_POI_TYPES.has(this.type as ObcPoiType)\n ? (this.type as ObcPoiType)\n : ObcPoiType.Line;\n }\n\n protected get resolvedPoiState(): ObcPoiState {\n return VALID_POI_STATES.has(this.state as ObcPoiState)\n ? (this.state as ObcPoiState)\n : ObcPoiState.Enabled;\n }\n\n /* ---------- Poi — visual query ---------- */\n\n /**\n * Override in each variant to query the correct inner component tag names.\n * Returns the poi wrapper element and poi-button element from the shadow DOM.\n */\n protected getVisualNodes(): {\n poi: HTMLElement | null;\n button: HTMLElement | null;\n wrapper: HTMLElement | null;\n buttonWrapper: HTMLElement | null;\n } {\n return this.queryVisualNodes('obc-poi', 'obc-poi-button');\n }\n\n /**\n * Helper for common `getVisualNodes()` pattern: query poi tag in own shadow,\n * then button tag. When the button is slotted into poi (aton/vessel variants),\n * it lives in this variant's shadow root. When using the fallback (data variant),\n * it lives inside poi's shadow root.\n */\n protected queryVisualNodes(poiTag: string, buttonTag: string) {\n const poi = this.shadowRoot?.querySelector(poiTag) as HTMLElement | null;\n const button = (this.shadowRoot?.querySelector(buttonTag) ??\n poi?.shadowRoot?.querySelector(buttonTag)) as HTMLElement | null;\n const buttonShadow = button?.shadowRoot ?? null;\n const buttonWrapper = buttonShadow?.querySelector(\n '.button-wrapper'\n ) as HTMLElement | null;\n const wrapper = buttonShadow?.querySelector(\n '.wrapper'\n ) as HTMLElement | null;\n return {poi, button, wrapper, buttonWrapper};\n }\n\n private getInnerPoi() {\n return this.shadowRoot?.querySelector('obc-poi') as {\n requestUpdate?: () => void;\n refreshProjectionLayout?: (trackDurationMs?: number) => void;\n buttonOffsetX?: number;\n targetOffsetX?: number;\n } | null;\n }\n\n private syncInnerPoiLayout() {\n const poi = this.getInnerPoi();\n\n if (poi) {\n poi.buttonOffsetX = this._buttonOffsetX;\n poi.targetOffsetX = this._targetOffsetX;\n }\n poi?.requestUpdate?.();\n poi?.refreshProjectionLayout?.();\n }\n\n public refreshProjectionLayout(trackDurationMs = 0) {\n const poi = this.getInnerPoi();\n poi?.refreshProjectionLayout?.(trackDurationMs);\n this.dispatchLayoutChange();\n }\n\n public setRuntimeHorizontalOffsets(\n buttonOffsetX: number,\n targetOffsetX = this._targetOffsetX\n ) {\n const nextButtonOffsetX = Number.isFinite(buttonOffsetX)\n ? buttonOffsetX\n : 0;\n const nextTargetOffsetX = Number.isFinite(targetOffsetX)\n ? targetOffsetX\n : 0;\n const oldButtonOffsetX = this._buttonOffsetX;\n const oldTargetOffsetX = this._targetOffsetX;\n const buttonOffsetChanged = this._buttonOffsetX !== nextButtonOffsetX;\n const targetOffsetChanged = this._targetOffsetX !== nextTargetOffsetX;\n\n if (!buttonOffsetChanged && !targetOffsetChanged) {\n return;\n }\n\n this._buttonOffsetX = nextButtonOffsetX;\n this._targetOffsetX = nextTargetOffsetX;\n\n const poi = this.getInnerPoi();\n\n if (!poi) {\n if (buttonOffsetChanged) {\n this.requestUpdate('buttonOffsetX', oldButtonOffsetX);\n }\n if (targetOffsetChanged) {\n this.requestUpdate('targetOffsetX', oldTargetOffsetX);\n }\n return;\n }\n\n poi.buttonOffsetX = nextButtonOffsetX;\n poi.targetOffsetX = nextTargetOffsetX;\n }\n\n public getVisualRect(\n preference: PoiDataVisualRectPreference = PoiDataVisualRectPreference.Largest\n ): DOMRect {\n const {poi, button, wrapper, buttonWrapper} = this.getVisualNodes();\n const candidates = [wrapper, buttonWrapper, button, poi].filter(\n (element): element is HTMLElement => !!element\n );\n\n if (preference === PoiDataVisualRectPreference.Group) {\n const hasDataWrapper = wrapper?.classList.contains('has-data') ?? false;\n return (\n (hasDataWrapper ? wrapper?.getBoundingClientRect() : null) ??\n buttonWrapper?.getBoundingClientRect() ??\n wrapper?.getBoundingClientRect() ??\n button?.getBoundingClientRect() ??\n poi?.getBoundingClientRect() ??\n this.getBoundingClientRect()\n );\n }\n\n if (preference === PoiDataVisualRectPreference.Anchor) {\n return (\n buttonWrapper?.getBoundingClientRect() ??\n button?.getBoundingClientRect() ??\n wrapper?.getBoundingClientRect() ??\n poi?.getBoundingClientRect() ??\n this.getBoundingClientRect()\n );\n }\n\n if (preference === PoiDataVisualRectPreference.Size) {\n return (\n wrapper?.getBoundingClientRect() ??\n buttonWrapper?.getBoundingClientRect() ??\n button?.getBoundingClientRect() ??\n poi?.getBoundingClientRect() ??\n this.getBoundingClientRect()\n );\n }\n\n if (candidates.length === 0) {\n return this.getBoundingClientRect();\n }\n\n const candidateRects = candidates.map((element) =>\n element.getBoundingClientRect()\n );\n return candidateRects.reduce((best, rect) =>\n rect.height > best.height ? rect : best\n );\n }\n\n public getVisualElement(\n preference: VisualElementPreference = PoiDataVisualRectPreference.Size\n ): HTMLElement {\n const {poi, button, wrapper, buttonWrapper} = this.getVisualNodes();\n\n if (preference === PoiDataVisualRectPreference.Group) {\n const hasDataWrapper = wrapper?.classList.contains('has-data') ?? false;\n return (\n (hasDataWrapper ? wrapper : null) ??\n buttonWrapper ??\n wrapper ??\n button ??\n poi ??\n this\n );\n }\n\n if (preference === PoiDataVisualRectPreference.Anchor) {\n return buttonWrapper ?? button ?? wrapper ?? poi ?? this;\n }\n\n return wrapper ?? buttonWrapper ?? button ?? poi ?? this;\n }\n\n public getPointerElement(): HTMLElement | null {\n const {poi} = this.getVisualNodes();\n return (\n (poi?.shadowRoot?.querySelector(\n 'obc-poi-pointer.pointer'\n ) as HTMLElement | null) ?? null\n );\n }\n\n /* ---------- Render helpers ---------- */\n\n /** Public `y` normalized as the target Y input. */\n protected get resolvedTargetY(): number {\n return Number.isFinite(this.y) ? this.y : 0;\n }\n\n /** Public `buttonY` normalized as the button Y input. */\n protected get resolvedButtonY(): number {\n return typeof this.buttonY === 'number' && Number.isFinite(this.buttonY)\n ? this.buttonY\n : 0;\n }\n\n /** Computed effective local button Y offset. */\n protected get effectiveLocalButtonY(): number {\n return this.resolvedButtonY - this.selectedVerticalOffset;\n }\n\n /**\n * Override in each variant to render the button slot content\n * placed inside `<obc-poi>`. The base class provides the outer\n * `<obc-poi>` wrapper with all shared property bindings.\n */\n protected renderButtonSlot(): TemplateResult {\n return html`\n <obc-poi-button\n slot=\"button\"\n exportparts=\"icon\"\n .relativeDirection=${this.relativeDirection}\n .selected=${this.selected}\n .hasHeader=${this.hasHeader}\n .headerContent=${this.headerContent}\n .state=${this.resolvedPoiState}\n .value=${this.value}\n .overlapOpaque=${this.overlapOpaque}\n .type=${this.buttonType}\n .data=${this.data}\n >\n <slot></slot>\n </obc-poi-button>\n `;\n }\n\n protected get resolvedHeaderState(): ObcPoiHeaderState {\n switch (this.resolvedPoiState) {\n case ObcPoiState.Caution:\n return ObcPoiHeaderState.Caution;\n case ObcPoiState.Warning:\n return ObcPoiHeaderState.Warning;\n case ObcPoiState.Alarm:\n return ObcPoiHeaderState.Alarm;\n case ObcPoiState.Enabled:\n default:\n return this.selected\n ? ObcPoiHeaderState.Selected\n : ObcPoiHeaderState.Enabled;\n }\n }\n\n private syncHeaderContent() {\n const headerChildren = Array.from(this.children).filter(\n (child): child is HTMLElement =>\n child instanceof HTMLElement && child.getAttribute('slot') === 'header'\n );\n\n if (headerChildren.length === 0 && !this.hasHeader) {\n return;\n }\n\n if (\n headerChildren.length > 0 &&\n !this.hasHeader &&\n this.closest('obc-poi-layer-stack') === null\n ) {\n this.hasHeader = true;\n }\n\n const target = (this.shadowRoot?.querySelector('[slot=\"button\"]') ??\n this.shadowRoot?.querySelector('obc-poi')) as HTMLElement | null;\n if (!target) {\n return;\n }\n\n for (const child of headerChildren) {\n if (child.parentElement !== target) {\n target.appendChild(child);\n }\n this.applyHeaderState(child);\n }\n }\n\n private applyHeaderState(root: ParentNode) {\n const headers = [\n ...(root instanceof Element && root.matches('obc-poi-header')\n ? [root]\n : []),\n ...root.querySelectorAll('obc-poi-header'),\n ] as HTMLElement[];\n\n for (const header of headers) {\n (header as {state?: ObcPoiHeaderState}).state = this.resolvedHeaderState;\n header.setAttribute('state', this.resolvedHeaderState);\n }\n }\n\n private syncHeaderState() {\n this.applyHeaderState(this.renderRoot);\n }\n\n override render() {\n return html`\n <obc-poi\n .type=${this.resolvedPoiType}\n .value=${this.value}\n .state=${this.resolvedPoiState}\n .x=${0}\n .y=${this.resolvedTargetY}\n .buttonY=${this.effectiveLocalButtonY}\n .fixedTarget=${false}\n .outsideAngle=${this.outsideAngle}\n .hasPointer=${this.hasPointer}\n .hasHeader=${this.hasHeader}\n .headerContent=${this.headerContent}\n .animatePosition=${this.animatePosition}\n .relativeDirection=${this.relativeDirection}\n .buttonType=${this.buttonType}\n .overlapOpaque=${this.overlapOpaque}\n .pointerType=${this.pointerType}\n .pointerState=${this.pointerState}\n .selected=${this.selected}\n .data=${this.data}\n .buttonOffsetX=${this.buttonOffsetX}\n .targetOffsetX=${this.targetOffsetX}\n .boxWidth=${this.boxWidth}\n .boxHeight=${this.boxHeight}\n >\n ${this.renderButtonSlot()}\n </obc-poi>\n `;\n }\n\n static override styles = [unsafeCSS(componentStyle)];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"poi-base.js","names":[],"sources":["../../../src/ar/poi/poi-base.ts"],"sourcesContent":["import {LitElement, TemplateResult, html, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport componentStyle from './poi-base.css?inline';\nimport './poi.js';\nimport {\n ObcPoiButtonType,\n ObcPoiButtonDataItem,\n} from '../poi-button/poi-button.js';\nimport {\n DEFAULT_LINE_LENGTH_PX,\n ObcPoiState,\n ObcPoiType,\n ObcPoiValue,\n} from './poi.js';\nimport {\n ObcPoiPointerState,\n ObcPoiPointerType,\n} from '../building-blocks/poi-pointer/poi-pointer.js';\nimport {POI_ATTR, Poi, PoiDataVisualRectPreference} from './poi.js';\nimport {clamp} from '../../svghelpers/math.js';\nexport {ObcPoiValue as PoiBaseValue};\nexport {PoiDataVisualRectPreference as PoiBaseVisualRectPreference};\n\n/** @internal */\ntype VisualElementPreference =\n | PoiDataVisualRectPreference.Group\n | PoiDataVisualRectPreference.Anchor\n | PoiDataVisualRectPreference.Size;\n\nfunction stripWhitespaceTextNodes(el: Element): void {\n for (const node of Array.from(el.childNodes)) {\n if (\n node.nodeType === Node.TEXT_NODE &&\n (node.textContent ?? '').trim() === ''\n ) {\n node.remove();\n }\n }\n}\n\nexport const X_FILTER_CUTOFF_HZ = 16;\nexport const Y_FILTER_CUTOFF_HZ = 16;\nconst X_FILTER_DEADBAND_PX = 0.1;\nconst X_MOVING_HINT_MS = 120;\nconst VALID_POI_TYPES = new Set(Object.values(ObcPoiType));\nconst VALID_POI_STATES = new Set(Object.values(ObcPoiState));\n\n/**\n * Shared base class for top-level POI variant components (`obc-poi-data`,\n * `obc-poi-aton`, `obc-poi-vessel`).\n *\n * Implements `Poi` and contains all positioning, X-filter,\n * layout-change dispatch, and visual-query logic so that each variant\n * only needs to override `renderContent()` and `getVisualNodes()`.\n *\n * ### Coordinate Model\n * - `x` is the horizontal center position in px within the layer.\n * - Targets are anchored at the layer's bottom edge; `y` is the connector\n * line length in px extending downward from that anchor to the target\n * point (default `192`, the shared `DEFAULT_LINE_LENGTH_PX`). The button\n * renders at the top of the connector, inside the layer.\n * - `buttonY` positions the button; its interaction with `fixedTarget` is\n * described in the `obc-poi` documentation.\n * - `x` and `y` updates pass through built-in low-pass filters (see\n * `xFilterCutoffHz` and `yFilterCutoffHz`).\n *\n * The `@fires` tag below documents the dispatch site, which lives here rather\n * than in the variants. It is deliberately duplicated on each concrete\n * subclass — that is where `custom-elements.json` and the framework wrappers\n * pick the event up, since this class is not registered. Do not remove it from\n * the subclasses. `@ignore` keeps this class out of the generated docs.\n *\n * @property xFilterCutoffHz - Cutoff frequency (Hz) of the built-in low-pass filter applied to `x`.\n * Lower values smooth noisy input more aggressively; `0` or a negative\n * value disables filtering so `x` is applied directly.\n * @property yFilterCutoffHz - Cutoff frequency (Hz) of the built-in low-pass filter applied to `y`.\n * Lower values smooth noisy input more aggressively; `0` or a negative\n * value disables filtering so `y` is applied directly.\n * @fires {CustomEvent<void>} obc-poi-data-layout-change - Fired when layout-driving properties change. Bubbles and is composed.\n * @ignore\n */\nexport class PoiBase extends LitElement implements Poi {\n private headerObserver?: MutationObserver;\n private _buttonOffsetX = 0;\n private _targetOffsetX = 0;\n\n override connectedCallback() {\n stripWhitespaceTextNodes(this);\n super.connectedCallback();\n this.setAttribute(POI_ATTR, '');\n this.setupHeaderObserver();\n }\n\n /* ---------- POI marker properties ---------- */\n\n @property({type: String}) type: ObcPoiType = ObcPoiType.Line;\n @property({type: String}) value: ObcPoiValue = ObcPoiValue.Unchecked;\n @property({type: String}) state: ObcPoiState = ObcPoiState.Enabled;\n @property({type: Boolean}) selected = false;\n @property({type: String, attribute: 'button-type'})\n buttonType = ObcPoiButtonType.Button;\n @property({type: Boolean, attribute: 'overlap-opaque'})\n overlapOpaque = false;\n @property({type: Array, attribute: false})\n data: ObcPoiButtonDataItem[] = [];\n @property({type: Boolean, attribute: 'has-header'}) hasHeader = false;\n @property({type: String, attribute: 'header-content'}) headerContent = '';\n @property({type: Boolean}) hasPointer = false;\n @property({type: String, attribute: 'pointer-type'})\n pointerType: ObcPoiPointerType | null = null;\n @property({type: String, attribute: 'pointer-state'})\n pointerState: ObcPoiPointerState | null = null;\n @property({type: Number}) relativeDirection = 0;\n\n /* ---------- Poi — position ---------- */\n\n @property({type: Number}) x = 0;\n @property({type: Number}) y = DEFAULT_LINE_LENGTH_PX;\n @property({type: Number, attribute: 'button-y'}) buttonY: number | null = 0;\n @property({type: Number, attribute: 'x-filter-cutoff-hz'})\n xFilterCutoffHz = X_FILTER_CUTOFF_HZ;\n @property({type: Number, attribute: 'y-filter-cutoff-hz'})\n yFilterCutoffHz = Y_FILTER_CUTOFF_HZ;\n @property({type: Boolean, attribute: 'fixed-target'}) fixedTarget = false;\n @property({type: Number, attribute: 'box-width'}) boxWidth: number | null =\n null;\n @property({type: Number, attribute: 'box-height'}) boxHeight: number | null =\n null;\n @property({type: Number, attribute: 'outside-angle'}) outsideAngle = 315;\n @property({type: Boolean, attribute: 'animate-position'})\n animatePosition = false;\n\n @property({type: Number, attribute: 'button-offset-x'})\n get buttonOffsetX(): number {\n return this._buttonOffsetX;\n }\n\n set buttonOffsetX(value: number) {\n const nextValue = Number.isFinite(value) ? value : 0;\n const oldValue = this._buttonOffsetX;\n if (oldValue === nextValue) {\n return;\n }\n\n this._buttonOffsetX = nextValue;\n this.requestUpdate('buttonOffsetX', oldValue);\n }\n\n @property({type: Number, attribute: 'target-offset-x'})\n get targetOffsetX(): number {\n return this._targetOffsetX;\n }\n\n set targetOffsetX(value: number) {\n const nextValue = Number.isFinite(value) ? value : 0;\n const oldValue = this._targetOffsetX;\n if (oldValue === nextValue) {\n return;\n }\n\n this._targetOffsetX = nextValue;\n this.requestUpdate('targetOffsetX', oldValue);\n }\n\n /* ---------- X-filter state ---------- */\n\n private filteredX = 0;\n private xFilterTarget = 0;\n private xFilterInitialized = false;\n private lastXFilterTimestampMs = 0;\n private xFilterRaf = 0;\n private xMovingHintTimeout: number | null = null;\n\n private get resolvedXFilterCutoffHz(): number {\n return Number.isFinite(this.xFilterCutoffHz)\n ? this.xFilterCutoffHz\n : X_FILTER_CUTOFF_HZ;\n }\n\n /* ---------- Y-filter state ---------- */\n\n private filteredY = 0;\n private yFilterTarget = 0;\n private yFilterInitialized = false;\n private lastYFilterTimestampMs = 0;\n private yFilterRaf = 0;\n\n private get resolvedYFilterCutoffHz(): number {\n return Number.isFinite(this.yFilterCutoffHz)\n ? this.yFilterCutoffHz\n : Y_FILTER_CUTOFF_HZ;\n }\n\n /* ---------- Layout change ---------- */\n\n private dispatchLayoutChange() {\n this.dispatchEvent(\n new CustomEvent('obc-poi-data-layout-change', {\n bubbles: true,\n composed: true,\n })\n );\n }\n\n /* ---------- X filter (low-pass) ---------- */\n\n private stepXFilter = (nowMs: number) => {\n this.xFilterRaf = 0;\n if (!this.isConnected || !this.xFilterInitialized) {\n return;\n }\n\n const dtSeconds =\n this.lastXFilterTimestampMs > 0\n ? clamp((nowMs - this.lastXFilterTimestampMs) / 1000, 1 / 120, 0.25)\n : 1 / 60;\n this.lastXFilterTimestampMs = nowMs;\n\n const cutoffHz = this.resolvedXFilterCutoffHz;\n const alpha =\n cutoffHz <= 0 ? 1 : 1 - Math.exp(-2 * Math.PI * cutoffHz * dtSeconds);\n const delta = this.xFilterTarget - this.filteredX;\n const nextX =\n Math.abs(delta) <= X_FILTER_DEADBAND_PX\n ? this.xFilterTarget\n : this.filteredX + delta * alpha;\n const changed = Math.abs(nextX - this.filteredX) > 1e-6;\n this.filteredX = nextX;\n if (changed) {\n this.style.setProperty('--obc-poi-data-x', `${this.filteredX}px`);\n this.dispatchLayoutChange();\n }\n\n const settled =\n Math.abs(this.xFilterTarget - this.filteredX) <= X_FILTER_DEADBAND_PX;\n\n if (settled) {\n this.filteredX = this.xFilterTarget;\n this.style.setProperty('--obc-poi-data-x', `${this.filteredX}px`);\n this.lastXFilterTimestampMs = 0;\n this.markXMoving();\n return;\n }\n\n this.markXMoving();\n this.xFilterRaf = requestAnimationFrame(this.stepXFilter);\n };\n\n private syncXFilterTarget(nextX: number) {\n this.xFilterTarget = nextX;\n\n if (!this.xFilterInitialized) {\n this.xFilterInitialized = true;\n this.filteredX = nextX;\n this.style.setProperty('--obc-poi-data-x', `${this.filteredX}px`);\n this.markXMoving();\n return;\n }\n\n if (\n this.resolvedXFilterCutoffHz <= 0 ||\n Math.abs(nextX - this.filteredX) <= X_FILTER_DEADBAND_PX\n ) {\n this.filteredX = this.xFilterTarget;\n this.style.setProperty('--obc-poi-data-x', `${this.filteredX}px`);\n if (this.xFilterRaf) {\n cancelAnimationFrame(this.xFilterRaf);\n this.xFilterRaf = 0;\n }\n this.lastXFilterTimestampMs = 0;\n this.markXMoving();\n return;\n }\n\n if (!this.xFilterRaf) {\n this.lastXFilterTimestampMs = 0;\n this.markXMoving();\n this.xFilterRaf = requestAnimationFrame(this.stepXFilter);\n }\n }\n\n /* ---------- Y filter (low-pass) ---------- */\n\n private stepYFilter = (nowMs: number) => {\n this.yFilterRaf = 0;\n if (!this.isConnected || !this.yFilterInitialized) {\n return;\n }\n\n const dtSeconds =\n this.lastYFilterTimestampMs > 0\n ? clamp((nowMs - this.lastYFilterTimestampMs) / 1000, 1 / 120, 0.25)\n : 1 / 60;\n this.lastYFilterTimestampMs = nowMs;\n\n const cutoffHz = this.resolvedYFilterCutoffHz;\n const alpha =\n cutoffHz <= 0 ? 1 : 1 - Math.exp(-2 * Math.PI * cutoffHz * dtSeconds);\n const delta = this.yFilterTarget - this.filteredY;\n const nextY =\n Math.abs(delta) <= X_FILTER_DEADBAND_PX\n ? this.yFilterTarget\n : this.filteredY + delta * alpha;\n const changed = Math.abs(nextY - this.filteredY) > 1e-6;\n this.filteredY = nextY;\n if (changed) {\n this.applyFilteredY();\n }\n\n const settled =\n Math.abs(this.yFilterTarget - this.filteredY) <= X_FILTER_DEADBAND_PX;\n\n if (settled) {\n this.filteredY = this.yFilterTarget;\n this.applyFilteredY();\n this.lastYFilterTimestampMs = 0;\n return;\n }\n\n this.yFilterRaf = requestAnimationFrame(this.stepYFilter);\n };\n\n private applyFilteredY() {\n this.requestUpdate();\n this.updatePosition();\n this.dispatchLayoutChange();\n }\n\n private syncYFilterTarget(nextY: number) {\n this.yFilterTarget = nextY;\n\n if (!this.yFilterInitialized) {\n this.yFilterInitialized = true;\n this.filteredY = nextY;\n return;\n }\n\n if (\n this.resolvedYFilterCutoffHz <= 0 ||\n Math.abs(nextY - this.filteredY) <= X_FILTER_DEADBAND_PX\n ) {\n this.filteredY = this.yFilterTarget;\n this.applyFilteredY();\n if (this.yFilterRaf) {\n cancelAnimationFrame(this.yFilterRaf);\n this.yFilterRaf = 0;\n }\n this.lastYFilterTimestampMs = 0;\n return;\n }\n\n if (!this.yFilterRaf) {\n this.lastYFilterTimestampMs = 0;\n this.yFilterRaf = requestAnimationFrame(this.stepYFilter);\n }\n }\n\n private markXMoving() {\n this.setAttribute('data-x-moving', 'true');\n if (this.xMovingHintTimeout !== null) {\n window.clearTimeout(this.xMovingHintTimeout);\n }\n this.xMovingHintTimeout = window.setTimeout(() => {\n this.removeAttribute('data-x-moving');\n this.xMovingHintTimeout = null;\n }, X_MOVING_HINT_MS);\n }\n\n /* ---------- Lifecycle ---------- */\n\n override disconnectedCallback() {\n super.disconnectedCallback();\n this.headerObserver?.disconnect();\n this.headerObserver = undefined;\n if (this.xFilterRaf) {\n cancelAnimationFrame(this.xFilterRaf);\n this.xFilterRaf = 0;\n }\n this.lastXFilterTimestampMs = 0;\n if (this.yFilterRaf) {\n cancelAnimationFrame(this.yFilterRaf);\n this.yFilterRaf = 0;\n }\n this.lastYFilterTimestampMs = 0;\n if (this.xMovingHintTimeout !== null) {\n window.clearTimeout(this.xMovingHintTimeout);\n this.xMovingHintTimeout = null;\n }\n }\n\n private setupHeaderObserver() {\n this.headerObserver?.disconnect();\n this.headerObserver = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (mutation.type === 'childList') {\n this.syncHeaderContent();\n return;\n }\n if (\n mutation.type === 'attributes' &&\n mutation.target instanceof HTMLElement &&\n mutation.target.getAttribute('slot') === 'header'\n ) {\n this.syncHeaderContent();\n return;\n }\n }\n });\n this.headerObserver.observe(this, {\n childList: true,\n attributes: true,\n attributeFilter: ['slot'],\n });\n }\n\n override updated(changedProperties: Map<string, unknown>) {\n if (changedProperties.has('x')) {\n this.syncXFilterTarget(Number.isFinite(this.x) ? this.x : 0);\n }\n if (changedProperties.has('y')) {\n this.syncYFilterTarget(Number.isFinite(this.y) ? this.y : 0);\n }\n if (\n changedProperties.has('buttonY') ||\n changedProperties.has('y') ||\n changedProperties.has('fixedTarget') ||\n changedProperties.has('selected') ||\n changedProperties.has('type')\n ) {\n this.updatePosition();\n this.syncInnerPoiLayout();\n }\n if (\n changedProperties.has('x') ||\n changedProperties.has('buttonY') ||\n changedProperties.has('y') ||\n changedProperties.has('buttonOffsetX') ||\n changedProperties.has('targetOffsetX') ||\n changedProperties.has('fixedTarget') ||\n changedProperties.has('selected') ||\n changedProperties.has('type')\n ) {\n this.dispatchLayoutChange();\n }\n this.syncHeaderContent();\n }\n\n protected override firstUpdated(_changedProperties: Map<string, unknown>) {\n this.syncHeaderContent();\n }\n\n /* ---------- Vertical positioning ---------- */\n\n private updatePosition() {\n if (this.fixedTarget) {\n if (Number.isFinite(this.resolvedButtonY)) {\n this.style.top = `${this.resolvedButtonY - this.resolvedTargetY}px`;\n } else {\n this.style.removeProperty('top');\n }\n } else {\n this.style.removeProperty('top');\n }\n }\n\n protected get selectedVerticalOffset(): number {\n if (!this.selected) {\n return 0;\n }\n const offset = getComputedStyle(this).getPropertyValue(\n '--obc-poi-target-selected-vertical-offset'\n );\n const parsed = Number.parseFloat(offset);\n return Number.isFinite(parsed) ? parsed : 0;\n }\n\n protected get resolvedPoiType(): ObcPoiType {\n return VALID_POI_TYPES.has(this.type as ObcPoiType)\n ? (this.type as ObcPoiType)\n : ObcPoiType.Line;\n }\n\n protected get resolvedPoiState(): ObcPoiState {\n return VALID_POI_STATES.has(this.state as ObcPoiState)\n ? (this.state as ObcPoiState)\n : ObcPoiState.Enabled;\n }\n\n /* ---------- Poi — visual query ---------- */\n\n /**\n * Override in each variant to query the correct inner component tag names.\n * Returns the poi wrapper element and poi-button element from the shadow DOM.\n */\n protected getVisualNodes(): {\n poi: HTMLElement | null;\n button: HTMLElement | null;\n wrapper: HTMLElement | null;\n buttonWrapper: HTMLElement | null;\n } {\n return this.queryVisualNodes('obc-poi', 'obc-poi-button');\n }\n\n /**\n * Helper for common `getVisualNodes()` pattern: query poi tag in own shadow,\n * then button tag. When the button is slotted into poi (aton/vessel variants),\n * it lives in this variant's shadow root. When using the fallback (data variant),\n * it lives inside poi's shadow root.\n */\n protected queryVisualNodes(poiTag: string, buttonTag: string) {\n const poi = this.shadowRoot?.querySelector(poiTag) as HTMLElement | null;\n const button = (this.shadowRoot?.querySelector(buttonTag) ??\n poi?.shadowRoot?.querySelector(buttonTag)) as HTMLElement | null;\n const buttonShadow = button?.shadowRoot ?? null;\n const buttonWrapper = buttonShadow?.querySelector(\n '.button-wrapper'\n ) as HTMLElement | null;\n const wrapper = buttonShadow?.querySelector(\n '.wrapper'\n ) as HTMLElement | null;\n return {poi, button, wrapper, buttonWrapper};\n }\n\n private getInnerPoi() {\n return this.shadowRoot?.querySelector('obc-poi') as {\n requestUpdate?: () => void;\n refreshProjectionLayout?: (trackDurationMs?: number) => void;\n buttonOffsetX?: number;\n targetOffsetX?: number;\n } | null;\n }\n\n private syncInnerPoiLayout() {\n const poi = this.getInnerPoi();\n\n if (poi) {\n poi.buttonOffsetX = this._buttonOffsetX;\n poi.targetOffsetX = this._targetOffsetX;\n }\n poi?.requestUpdate?.();\n poi?.refreshProjectionLayout?.();\n }\n\n public refreshProjectionLayout(trackDurationMs = 0) {\n const poi = this.getInnerPoi();\n poi?.refreshProjectionLayout?.(trackDurationMs);\n this.dispatchLayoutChange();\n }\n\n public setRuntimeHorizontalOffsets(\n buttonOffsetX: number,\n targetOffsetX = this._targetOffsetX\n ) {\n const nextButtonOffsetX = Number.isFinite(buttonOffsetX)\n ? buttonOffsetX\n : 0;\n const nextTargetOffsetX = Number.isFinite(targetOffsetX)\n ? targetOffsetX\n : 0;\n const oldButtonOffsetX = this._buttonOffsetX;\n const oldTargetOffsetX = this._targetOffsetX;\n const buttonOffsetChanged = this._buttonOffsetX !== nextButtonOffsetX;\n const targetOffsetChanged = this._targetOffsetX !== nextTargetOffsetX;\n\n if (!buttonOffsetChanged && !targetOffsetChanged) {\n return;\n }\n\n this._buttonOffsetX = nextButtonOffsetX;\n this._targetOffsetX = nextTargetOffsetX;\n\n const poi = this.getInnerPoi();\n\n if (!poi) {\n if (buttonOffsetChanged) {\n this.requestUpdate('buttonOffsetX', oldButtonOffsetX);\n }\n if (targetOffsetChanged) {\n this.requestUpdate('targetOffsetX', oldTargetOffsetX);\n }\n return;\n }\n\n poi.buttonOffsetX = nextButtonOffsetX;\n poi.targetOffsetX = nextTargetOffsetX;\n }\n\n public getVisualRect(\n preference: PoiDataVisualRectPreference = PoiDataVisualRectPreference.Largest\n ): DOMRect {\n const {poi, button, wrapper, buttonWrapper} = this.getVisualNodes();\n const candidates = [wrapper, buttonWrapper, button, poi].filter(\n (element): element is HTMLElement => !!element\n );\n\n if (preference === PoiDataVisualRectPreference.Group) {\n const hasDataWrapper = wrapper?.classList.contains('has-data') ?? false;\n return (\n (hasDataWrapper ? wrapper?.getBoundingClientRect() : null) ??\n buttonWrapper?.getBoundingClientRect() ??\n wrapper?.getBoundingClientRect() ??\n button?.getBoundingClientRect() ??\n poi?.getBoundingClientRect() ??\n this.getBoundingClientRect()\n );\n }\n\n if (preference === PoiDataVisualRectPreference.Anchor) {\n return (\n buttonWrapper?.getBoundingClientRect() ??\n button?.getBoundingClientRect() ??\n wrapper?.getBoundingClientRect() ??\n poi?.getBoundingClientRect() ??\n this.getBoundingClientRect()\n );\n }\n\n if (preference === PoiDataVisualRectPreference.Size) {\n return (\n wrapper?.getBoundingClientRect() ??\n buttonWrapper?.getBoundingClientRect() ??\n button?.getBoundingClientRect() ??\n poi?.getBoundingClientRect() ??\n this.getBoundingClientRect()\n );\n }\n\n if (candidates.length === 0) {\n return this.getBoundingClientRect();\n }\n\n const candidateRects = candidates.map((element) =>\n element.getBoundingClientRect()\n );\n return candidateRects.reduce((best, rect) =>\n rect.height > best.height ? rect : best\n );\n }\n\n public getVisualElement(\n preference: VisualElementPreference = PoiDataVisualRectPreference.Size\n ): HTMLElement {\n const {poi, button, wrapper, buttonWrapper} = this.getVisualNodes();\n\n if (preference === PoiDataVisualRectPreference.Group) {\n const hasDataWrapper = wrapper?.classList.contains('has-data') ?? false;\n return (\n (hasDataWrapper ? wrapper : null) ??\n buttonWrapper ??\n wrapper ??\n button ??\n poi ??\n this\n );\n }\n\n if (preference === PoiDataVisualRectPreference.Anchor) {\n return buttonWrapper ?? button ?? wrapper ?? poi ?? this;\n }\n\n return wrapper ?? buttonWrapper ?? button ?? poi ?? this;\n }\n\n public getPointerElement(): HTMLElement | null {\n const {poi} = this.getVisualNodes();\n return (\n (poi?.shadowRoot?.querySelector(\n 'obc-poi-pointer.pointer'\n ) as HTMLElement | null) ?? null\n );\n }\n\n /* ---------- Render helpers ---------- */\n\n /** Public `y` normalized as the target Y input, after the y filter. */\n protected get resolvedTargetY(): number {\n if (this.yFilterInitialized) {\n return this.filteredY;\n }\n return Number.isFinite(this.y) ? this.y : 0;\n }\n\n /** Public `buttonY` normalized as the button Y input. */\n protected get resolvedButtonY(): number {\n return typeof this.buttonY === 'number' && Number.isFinite(this.buttonY)\n ? this.buttonY\n : 0;\n }\n\n /** Computed effective local button Y offset. */\n protected get effectiveLocalButtonY(): number {\n return this.resolvedButtonY - this.selectedVerticalOffset;\n }\n\n /**\n * Override in each variant to render the button slot content\n * placed inside `<obc-poi>`. The base class provides the outer\n * `<obc-poi>` wrapper with all shared property bindings.\n */\n protected renderButtonSlot(): TemplateResult {\n return html`\n <obc-poi-button\n slot=\"button\"\n exportparts=\"icon\"\n .relativeDirection=${this.relativeDirection}\n .selected=${this.selected}\n .hasHeader=${this.hasHeader}\n .headerContent=${this.headerContent}\n .state=${this.resolvedPoiState}\n .value=${this.value}\n .overlapOpaque=${this.overlapOpaque}\n .type=${this.buttonType}\n .data=${this.data}\n >\n <slot></slot>\n <slot name=\"header\" slot=\"header\"></slot>\n </obc-poi-button>\n `;\n }\n\n /**\n * Auto-enable `hasHeader` when the consumer slots header content directly\n * (outside a stack, which manages `hasHeader` itself). Header elements stay\n * in the consumer's light DOM and reach the inner button through the\n * `<slot name=\"header\">` forwarding chain; their `state` is synced by\n * `obc-poi-button`.\n */\n private syncHeaderContent() {\n if (this.hasHeader) {\n return;\n }\n const hasHeaderChildren = Array.from(this.children).some(\n (child) =>\n child instanceof HTMLElement && child.getAttribute('slot') === 'header'\n );\n if (hasHeaderChildren && this.closest('obc-poi-layer-stack') === null) {\n this.hasHeader = true;\n }\n }\n\n override render() {\n return html`\n <obc-poi\n .type=${this.resolvedPoiType}\n .value=${this.value}\n .state=${this.resolvedPoiState}\n .x=${0}\n .y=${this.resolvedTargetY}\n .buttonY=${this.effectiveLocalButtonY}\n .fixedTarget=${false}\n .outsideAngle=${this.outsideAngle}\n .hasPointer=${this.hasPointer}\n .hasHeader=${this.hasHeader}\n .headerContent=${this.headerContent}\n .animatePosition=${this.animatePosition}\n .relativeDirection=${this.relativeDirection}\n .buttonType=${this.buttonType}\n .overlapOpaque=${this.overlapOpaque}\n .pointerType=${this.pointerType}\n .pointerState=${this.pointerState}\n .selected=${this.selected}\n .data=${this.data}\n .buttonOffsetX=${this.buttonOffsetX}\n .targetOffsetX=${this.targetOffsetX}\n .boxWidth=${this.boxWidth}\n .boxHeight=${this.boxHeight}\n >\n ${this.renderButtonSlot()}\n </obc-poi>\n `;\n }\n\n static override styles = [unsafeCSS(componentStyle)];\n}\n"],"mappings":"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"}
@@ -11,6 +11,7 @@ export { ObcPoiObjectState as PoiDataObjectState };
11
11
  *
12
12
  * Extends `PoiBase` to provide the "data" variant of the POI system.
13
13
  * Renders `<obc-poi>` with a slotted `<obc-poi-button-data>`.
14
+ * See the "Coordinate Model" section in `PoiBase` (poi-base.ts) for how `x`, `y`, and `buttonY` position the marker.
14
15
  *
15
16
  * @slot - Icon content forwarded to the inner POI object. Defaults to a vessel icon.
16
17
  * @slot header - Optional custom header content forwarded into `obc-poi`.
@@ -1 +1 @@
1
- {"version":3,"file":"poi-data.d.ts","sourceRoot":"","sources":["../../../src/ar/poi/poi-data.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AACtC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,mDAAmD,CAAC;AAC3D,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAC,YAAY,IAAI,YAAY,EAAC,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAC,2BAA2B,EAAC,MAAM,UAAU,CAAC;AACrD,OAAO,EAAC,iBAAiB,IAAI,kBAAkB,EAAC,CAAC;AACjD,OAAO,EAAC,iBAAiB,IAAI,kBAAkB,EAAC,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,qBACa,UAAW,SAAQ,OAAO;IAErC,SAAS,EAAE,iBAAiB,CAA6B;IAGzD,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAG3C,eAAe,UAAS;cAEL,cAAc;;;;;;cAId,gBAAgB;IAwBnC,OAAgB,MAAM,4BAAkB;CACzC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,UAAU,CAAC;KAC5B;CACF"}
1
+ {"version":3,"file":"poi-data.d.ts","sourceRoot":"","sources":["../../../src/ar/poi/poi-data.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,OAAO,EAAC,MAAM,eAAe,CAAC;AACtC,OAAO,kCAAkC,CAAC;AAC1C,OAAO,mDAAmD,CAAC;AAC3D,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAC,YAAY,IAAI,YAAY,EAAC,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAC,2BAA2B,EAAC,MAAM,UAAU,CAAC;AACrD,OAAO,EAAC,iBAAiB,IAAI,kBAAkB,EAAC,CAAC;AACjD,OAAO,EAAC,iBAAiB,IAAI,kBAAkB,EAAC,CAAC;AAEjD;;;;;;;;;;;GAWG;AACH,qBACa,UAAW,SAAQ,OAAO;IAErC,SAAS,EAAE,iBAAiB,CAA6B;IAGzD,SAAS,EAAE,iBAAiB,GAAG,IAAI,CAAQ;IAG3C,eAAe,UAAS;cAEL,cAAc;;;;;;cAId,gBAAgB;IAyBnC,OAAgB,MAAM,4BAAkB;CACzC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,cAAc,EAAE,UAAU,CAAC;KAC5B;CACF"}
@@ -38,6 +38,7 @@ var ObcPoiData = class ObcPoiData extends PoiBase {
38
38
  <slot
39
39
  ><obi-vessel-generic-default-filled></obi-vessel-generic-default-filled
40
40
  ></slot>
41
+ <slot name="header" slot="header"></slot>
41
42
  </obc-poi-button-data>
42
43
  `;
43
44
  }