@oicl/openbridge-webcomponents 2.0.0-next.101 → 2.0.0-next.103

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 (77) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +580 -143
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +629 -407
  4. package/dist/bars-graphs/donut-chart/donut-chart.d.ts +18 -16
  5. package/dist/bars-graphs/donut-chart/donut-chart.d.ts.map +1 -1
  6. package/dist/bars-graphs/donut-chart/donut-chart.js.map +1 -1
  7. package/dist/bars-graphs/pie-chart/pie-chart.d.ts +14 -12
  8. package/dist/bars-graphs/pie-chart/pie-chart.d.ts.map +1 -1
  9. package/dist/bars-graphs/pie-chart/pie-chart.js.map +1 -1
  10. package/dist/bars-graphs/polar-chart/polar-chart.d.ts +19 -16
  11. package/dist/bars-graphs/polar-chart/polar-chart.d.ts.map +1 -1
  12. package/dist/bars-graphs/polar-chart/polar-chart.js.map +1 -1
  13. package/dist/bars-graphs/radial-bar-chart/radial-bar-chart.d.ts +8 -8
  14. package/dist/bars-graphs/radial-bar-chart/radial-bar-chart.d.ts.map +1 -1
  15. package/dist/bars-graphs/radial-bar-chart/radial-bar-chart.js.map +1 -1
  16. package/dist/building-blocks/chart-line/chart-line-base.d.ts +8 -25
  17. package/dist/building-blocks/chart-line/chart-line-base.d.ts.map +1 -1
  18. package/dist/building-blocks/chart-line/chart-line-base.js.map +1 -1
  19. package/dist/building-blocks/instrument-radial/instrument-radial.d.ts +22 -2
  20. package/dist/building-blocks/instrument-radial/instrument-radial.d.ts.map +1 -1
  21. package/dist/building-blocks/instrument-radial/instrument-radial.js +61 -37
  22. package/dist/building-blocks/instrument-radial/instrument-radial.js.map +1 -1
  23. package/dist/integration-systems/integration-bar/integration-bar.d.ts +20 -24
  24. package/dist/integration-systems/integration-bar/integration-bar.d.ts.map +1 -1
  25. package/dist/integration-systems/integration-bar/integration-bar.js.map +1 -1
  26. package/dist/integration-systems/integration-button/integration-button.d.ts +15 -13
  27. package/dist/integration-systems/integration-button/integration-button.d.ts.map +1 -1
  28. package/dist/integration-systems/integration-button/integration-button.js.map +1 -1
  29. package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.d.ts +14 -0
  30. package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.d.ts.map +1 -1
  31. package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.js +30 -11
  32. package/dist/navigation-instruments/azimuth-thruster/azimuth-thruster.js.map +1 -1
  33. package/dist/navigation-instruments/compass/compass.d.ts +68 -31
  34. package/dist/navigation-instruments/compass/compass.d.ts.map +1 -1
  35. package/dist/navigation-instruments/compass/compass.js +36 -16
  36. package/dist/navigation-instruments/compass/compass.js.map +1 -1
  37. package/dist/navigation-instruments/compass-flat/compass-flat.d.ts +8 -9
  38. package/dist/navigation-instruments/compass-flat/compass-flat.d.ts.map +1 -1
  39. package/dist/navigation-instruments/compass-flat/compass-flat.js.map +1 -1
  40. package/dist/navigation-instruments/compass-sector/compass-sector.d.ts.map +1 -1
  41. package/dist/navigation-instruments/compass-sector/compass-sector.js.map +1 -1
  42. package/dist/navigation-instruments/gauge-radial/gauge-radial.css.js +34 -2
  43. package/dist/navigation-instruments/gauge-radial/gauge-radial.css.js.map +1 -1
  44. package/dist/navigation-instruments/gauge-radial/gauge-radial.d.ts +15 -0
  45. package/dist/navigation-instruments/gauge-radial/gauge-radial.d.ts.map +1 -1
  46. package/dist/navigation-instruments/gauge-radial/gauge-radial.js +35 -1
  47. package/dist/navigation-instruments/gauge-radial/gauge-radial.js.map +1 -1
  48. package/dist/navigation-instruments/gauge-trend/gauge-trend.d.ts +0 -5
  49. package/dist/navigation-instruments/gauge-trend/gauge-trend.d.ts.map +1 -1
  50. package/dist/navigation-instruments/gauge-trend/gauge-trend.js.map +1 -1
  51. package/dist/navigation-instruments/graph-mini/graph-mini.d.ts +1 -1
  52. package/dist/navigation-instruments/graph-mini/graph-mini.d.ts.map +1 -1
  53. package/dist/navigation-instruments/graph-mini/graph-mini.js.map +1 -1
  54. package/dist/navigation-instruments/heading/heading.d.ts +19 -1
  55. package/dist/navigation-instruments/heading/heading.d.ts.map +1 -1
  56. package/dist/navigation-instruments/heading/heading.js +34 -16
  57. package/dist/navigation-instruments/heading/heading.js.map +1 -1
  58. package/dist/navigation-instruments/indicator-graph/indicator-graph.d.ts +1 -1
  59. package/dist/navigation-instruments/indicator-graph/indicator-graph.d.ts.map +1 -1
  60. package/dist/navigation-instruments/indicator-graph/indicator-graph.js.map +1 -1
  61. package/dist/navigation-instruments/rudder/rudder.d.ts +15 -2
  62. package/dist/navigation-instruments/rudder/rudder.d.ts.map +1 -1
  63. package/dist/navigation-instruments/rudder/rudder.js +36 -26
  64. package/dist/navigation-instruments/rudder/rudder.js.map +1 -1
  65. package/dist/navigation-instruments/speed-gauge/speed-gauge.d.ts +15 -1
  66. package/dist/navigation-instruments/speed-gauge/speed-gauge.d.ts.map +1 -1
  67. package/dist/navigation-instruments/speed-gauge/speed-gauge.js +31 -3
  68. package/dist/navigation-instruments/speed-gauge/speed-gauge.js.map +1 -1
  69. package/dist/navigation-instruments/watch/watch.d.ts +45 -17
  70. package/dist/navigation-instruments/watch/watch.d.ts.map +1 -1
  71. package/dist/navigation-instruments/watch/watch.js +53 -38
  72. package/dist/navigation-instruments/watch/watch.js.map +1 -1
  73. package/dist/svghelpers/radial-frame.d.ts +122 -0
  74. package/dist/svghelpers/radial-frame.d.ts.map +1 -0
  75. package/dist/svghelpers/radial-frame.js +259 -0
  76. package/dist/svghelpers/radial-frame.js.map +1 -0
  77. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"integration-button.js","sources":["../../../src/integration-systems/integration-button/integration-button.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {customElement} from '../../decorator.js';\nimport compentStyle from './integration-button.css?inline';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\n\nexport interface IntegrationButtonReadout {\n label: string;\n value: string;\n unit: string;\n}\n\nexport enum IntegrationButtonVariant {\n normal = 'normal',\n flat = 'flat',\n}\n\nexport enum IntegrationButtonType {\n hug = 'hug',\n regular = 'regular',\n rich = 'rich',\n}\n\n/**\n * `<obc-integration-button>` – A button component for integration systems.\n *\n * @slot leading-icon - Icon before label (shown when `hasLeadingIcon` is true)\n * @slot trailing-icon - Icon after label (shown when `hasTrailingIcon` is true)\n * @slot trailing-icon2 - Icon after label (shown when `hasTrailingIcon2` is true)\n * @slot label - Label text\n * @slot status - Status/description text (shown when `hasStatus` is true)\n * @slot info-label - Info label text\n * @slot info-status - Info status text\n * @slot integration-vessel-menu - Integration vessel menu to be shown when button is in activated state\n *\n * @fires click - Fired when the internal button is activated.\n *\n * @property {boolean} hasTrailingIcon - Shows the `trailing-icon` slot.\n * @property {boolean} hasTrailingIcon2 - Shows the `trailing-icon2` slot.\n * @property {boolean} hasLeadingIcon - Shows the `leading-icon` slot.\n * @property {boolean} hasstatus - Shows the `status` slot.\n * @property {IntegrationButtonReadout[]} readouts - List of readout items shown in the rich type.\n * @property {boolean} disabled - Disables the internal button.\n * @property {boolean} activated - Applies active state styling while a selection is pending.\n * @property {boolean} selected - Applies selected state styling.\n * @property {boolean} dividerBottom - Shows a bottom divider under the button.\n * @property {boolean} dividerRight - Shows a right divider to separate from adjacent buttons.\n * @property {IntegrationButtonVariant} variant - Visual variant (`normal` or `flat`).\n * @property {IntegrationButtonType} type - Layout type (`hug`, `regular`, or `rich`).\n * @experimental\n */\n@customElement('obc-integration-button')\nexport class ObcIntegrationButton extends LitElement {\n @property({type: Boolean}) hasTrailingIcon = false;\n /** @availableWhen hasTrailingIcon==true */\n @property({type: Boolean}) hasTrailingIcon2 = false;\n @property({type: Boolean}) hasLeadingIcon = false;\n @property({type: Boolean}) hasStatus = false;\n @property({type: Array, attribute: false})\n readouts: IntegrationButtonReadout[] = [];\n @property({type: Boolean}) disabled = false;\n @property({type: Boolean}) activated = false;\n @property({type: Boolean}) selected = false;\n @property({type: Boolean}) dividerBottom = false;\n @property({type: Boolean}) dividerRight = false;\n @property({type: String}) variant: IntegrationButtonVariant =\n IntegrationButtonVariant.normal;\n @property({type: String}) type: IntegrationButtonType =\n IntegrationButtonType.regular;\n\n private getButtonClasses() {\n return {\n 'touch-target': true,\n selected: this.selected,\n activated: this.activated,\n disabled: this.disabled,\n 'has-description': this.hasStatus,\n ['variant-' + this.variant]: true,\n ['type-' + this.type]: true,\n };\n }\n\n private onIntegrationVesselMenuClick(event: Event) {\n event.stopPropagation();\n }\n\n renderRich() {\n return html`\n <div class=\"button-horizontal-divider-container\">\n <div class=\"button-vertical-divider-container\">\n <button\n class=${classMap(this.getButtonClasses())}\n ?disabled=${this.disabled}\n >\n <div class=\"content-container\">\n <div class=\"main-container\">\n ${this.hasLeadingIcon\n ? html`<div class=\"icon leading\">\n <slot name=\"leading-icon\"></slot>\n </div>`\n : nothing}\n <div class=\"text-container\">\n <div class=\"label\"><slot name=\"label\"></slot></div>\n ${this.hasStatus\n ? html`<div class=\"status\">\n <slot name=\"status\"></slot>\n </div>`\n : nothing}\n </div>\n ${this.hasTrailingIcon\n ? html`<div class=\"icon-container\">\n ${this.hasTrailingIcon2\n ? html`<slot\n name=\"trailing-icon2\"\n class=\"icon trailing\"\n ></slot>`\n : nothing}\n <slot name=\"trailing-icon\" class=\"icon trailing\"></slot>\n </div>`\n : nothing}\n </div>\n <div class=\"info-container\">\n <div class=\"info-item\">\n <slot class=\"info-label\" name=\"info-label\"></slot>\n <slot class=\"info-status\" name=\"info-status\"></slot>\n </div>\n ${this.readouts.map(\n (readout) => html`\n <div class=\"info-readout-item\">\n <div class=\"info-item-label\">${readout.label}</div>\n <div class=\"info-item-value\">${readout.value}</div>\n <div class=\"info-item-unit\">${readout.unit}</div>\n </div>\n `\n )}\n </div>\n </div>\n </button>\n ${this.dividerRight\n ? html`<div class=\"divider-right\"></div>`\n : html`<div\n class=\"divider-right\"\n style=\"visibility: hidden;\"\n ></div>`}\n </div>\n ${this.dividerBottom\n ? html`<div class=\"divider-bottom\"></div>`\n : nothing}\n </div>\n <div\n class=${classMap({\n 'integration-vessel-menu-container': true,\n show: this.activated,\n })}\n @click=${this.onIntegrationVesselMenuClick}\n >\n <slot name=\"integration-vessel-menu\"></slot>\n </div>\n `;\n }\n\n renderRegular() {\n return html`\n <div class=\"button-vertical-divider-container\">\n <button\n class=${classMap(this.getButtonClasses())}\n ?disabled=${this.disabled}\n >\n <div class=\"content-container\">\n ${this.hasLeadingIcon\n ? html`<div class=\"icon leading\">\n <slot name=\"leading-icon\"></slot>\n </div>`\n : nothing}\n <div class=\"text-container\">\n <div class=\"label\"><slot name=\"label\"></slot></div>\n ${this.hasStatus\n ? html`<div class=\"status\"><slot name=\"status\"></slot></div>`\n : nothing}\n </div>\n ${this.hasTrailingIcon\n ? html`<div class=\"icon-container\">\n ${this.hasTrailingIcon2\n ? html`<slot\n name=\"trailing-icon2\"\n class=\"icon trailing\"\n ></slot>`\n : nothing}\n <slot name=\"trailing-icon\" class=\"icon trailing\"></slot>\n </div>`\n : nothing}\n </div>\n </button>\n ${this.dividerRight\n ? html`<div class=\"divider-right\"></div>`\n : html`<div class=\"divider-right\" style=\"visibility: hidden;\"></div>`}\n </div>\n <div\n class=${classMap({\n 'integration-vessel-menu-container': true,\n show: this.activated,\n })}\n @click=${this.onIntegrationVesselMenuClick}\n >\n <slot name=\"integration-vessel-menu\"></slot>\n </div>\n `;\n }\n\n renderHug() {\n return html`\n <div class=\"button-vertical-divider-container\">\n <button\n class=${classMap(this.getButtonClasses())}\n ?disabled=${this.disabled}\n >\n <div class=\"content-container\">\n ${this.hasLeadingIcon\n ? html`<div class=\"icon leading\">\n <slot name=\"leading-icon\"></slot>\n </div>`\n : nothing}\n <div class=\"text-container\">\n <div class=\"label\"><slot name=\"label\"></slot></div>\n ${this.hasStatus\n ? html`<div class=\"status\"><slot name=\"status\"></slot></div>`\n : nothing}\n </div>\n ${this.hasTrailingIcon\n ? html`<div class=\"icon-container\">\n ${this.hasTrailingIcon2\n ? html`<slot\n name=\"trailing-icon2\"\n class=\"icon trailing\"\n ></slot>`\n : nothing}\n <slot name=\"trailing-icon\" class=\"icon trailing\"></slot>\n </div>`\n : nothing}\n </div>\n </button>\n ${this.dividerRight\n ? html`<div class=\"divider-right\"></div>`\n : html`<div class=\"divider-right\" style=\"visibility: hidden;\"></div>`}\n </div>\n <div\n class=${classMap({\n 'integration-vessel-menu-container': true,\n show: this.activated,\n })}\n @click=${this.onIntegrationVesselMenuClick}\n >\n <slot name=\"integration-vessel-menu\"></slot>\n </div>\n `;\n }\n\n override render() {\n switch (this.type) {\n case IntegrationButtonType.hug: {\n return this.renderHug();\n }\n case IntegrationButtonType.rich: {\n return this.renderRich();\n }\n case IntegrationButtonType.regular:\n default: {\n return this.renderRegular();\n }\n }\n }\n\n static override styles = unsafeCSS(compentStyle);\n\n override updated() {\n let dividerHeight = 40;\n if (this.type === IntegrationButtonType.hug) {\n dividerHeight = 32;\n }\n if (this.type === IntegrationButtonType.rich) {\n dividerHeight = 64;\n }\n this.style.setProperty(\n '--integration-button-divider-height',\n `${dividerHeight}px`\n );\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-integration-button': ObcIntegrationButton;\n }\n}\n"],"names":["IntegrationButtonVariant","IntegrationButtonType"],"mappings":"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"}
1
+ {"version":3,"file":"integration-button.js","sources":["../../../src/integration-systems/integration-button/integration-button.ts"],"sourcesContent":["import {LitElement, html, nothing, unsafeCSS} from 'lit';\nimport {customElement} from '../../decorator.js';\nimport compentStyle from './integration-button.css?inline';\nimport {property} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\n\nexport interface IntegrationButtonReadout {\n label: string;\n value: string;\n unit: string;\n}\n\nexport enum IntegrationButtonVariant {\n normal = 'normal',\n flat = 'flat',\n}\n\nexport enum IntegrationButtonType {\n hug = 'hug',\n regular = 'regular',\n rich = 'rich',\n}\n\n/**\n * `<obc-integration-button>` – A button component for integration systems.\n *\n * @slot leading-icon - Icon before label (shown when `hasLeadingIcon` is true)\n * @slot trailing-icon - Icon after label (shown when `hasTrailingIcon` is true)\n * @slot trailing-icon2 - Icon after label (shown when `hasTrailingIcon2` is true)\n * @slot label - Label text\n * @slot status - Status/description text (shown when `hasStatus` is true)\n * @slot info-label - Info label text\n * @slot info-status - Info status text\n * @slot integration-vessel-menu - Integration vessel menu to be shown when button is in activated state\n *\n * @fires click - Fired when the internal button is activated.\n *\n * @experimental\n */\n@customElement('obc-integration-button')\nexport class ObcIntegrationButton extends LitElement {\n /** Shows the `trailing-icon` slot. */\n @property({type: Boolean}) hasTrailingIcon = false;\n /**\n * Shows the `trailing-icon2` slot.\n * @availableWhen hasTrailingIcon==true\n */\n @property({type: Boolean}) hasTrailingIcon2 = false;\n /** Shows the `leading-icon` slot. */\n @property({type: Boolean}) hasLeadingIcon = false;\n /** Shows the `status` slot. */\n @property({type: Boolean}) hasStatus = false;\n /** List of readout items shown in the rich type. */\n @property({type: Array, attribute: false})\n readouts: IntegrationButtonReadout[] = [];\n /** Disables the internal button. */\n @property({type: Boolean}) disabled = false;\n /** Applies active state styling while a selection is pending. */\n @property({type: Boolean}) activated = false;\n /** Applies selected state styling. */\n @property({type: Boolean}) selected = false;\n /** Shows a bottom divider under the button. */\n @property({type: Boolean}) dividerBottom = false;\n /** Shows a right divider to separate from adjacent buttons. */\n @property({type: Boolean}) dividerRight = false;\n /** Visual variant (`normal` or `flat`). */\n @property({type: String}) variant: IntegrationButtonVariant =\n IntegrationButtonVariant.normal;\n /** Layout type (`hug`, `regular`, or `rich`). */\n @property({type: String}) type: IntegrationButtonType =\n IntegrationButtonType.regular;\n\n private getButtonClasses() {\n return {\n 'touch-target': true,\n selected: this.selected,\n activated: this.activated,\n disabled: this.disabled,\n 'has-description': this.hasStatus,\n ['variant-' + this.variant]: true,\n ['type-' + this.type]: true,\n };\n }\n\n private onIntegrationVesselMenuClick(event: Event) {\n event.stopPropagation();\n }\n\n renderRich() {\n return html`\n <div class=\"button-horizontal-divider-container\">\n <div class=\"button-vertical-divider-container\">\n <button\n class=${classMap(this.getButtonClasses())}\n ?disabled=${this.disabled}\n >\n <div class=\"content-container\">\n <div class=\"main-container\">\n ${this.hasLeadingIcon\n ? html`<div class=\"icon leading\">\n <slot name=\"leading-icon\"></slot>\n </div>`\n : nothing}\n <div class=\"text-container\">\n <div class=\"label\"><slot name=\"label\"></slot></div>\n ${this.hasStatus\n ? html`<div class=\"status\">\n <slot name=\"status\"></slot>\n </div>`\n : nothing}\n </div>\n ${this.hasTrailingIcon\n ? html`<div class=\"icon-container\">\n ${this.hasTrailingIcon2\n ? html`<slot\n name=\"trailing-icon2\"\n class=\"icon trailing\"\n ></slot>`\n : nothing}\n <slot name=\"trailing-icon\" class=\"icon trailing\"></slot>\n </div>`\n : nothing}\n </div>\n <div class=\"info-container\">\n <div class=\"info-item\">\n <slot class=\"info-label\" name=\"info-label\"></slot>\n <slot class=\"info-status\" name=\"info-status\"></slot>\n </div>\n ${this.readouts.map(\n (readout) => html`\n <div class=\"info-readout-item\">\n <div class=\"info-item-label\">${readout.label}</div>\n <div class=\"info-item-value\">${readout.value}</div>\n <div class=\"info-item-unit\">${readout.unit}</div>\n </div>\n `\n )}\n </div>\n </div>\n </button>\n ${this.dividerRight\n ? html`<div class=\"divider-right\"></div>`\n : html`<div\n class=\"divider-right\"\n style=\"visibility: hidden;\"\n ></div>`}\n </div>\n ${this.dividerBottom\n ? html`<div class=\"divider-bottom\"></div>`\n : nothing}\n </div>\n <div\n class=${classMap({\n 'integration-vessel-menu-container': true,\n show: this.activated,\n })}\n @click=${this.onIntegrationVesselMenuClick}\n >\n <slot name=\"integration-vessel-menu\"></slot>\n </div>\n `;\n }\n\n renderRegular() {\n return html`\n <div class=\"button-vertical-divider-container\">\n <button\n class=${classMap(this.getButtonClasses())}\n ?disabled=${this.disabled}\n >\n <div class=\"content-container\">\n ${this.hasLeadingIcon\n ? html`<div class=\"icon leading\">\n <slot name=\"leading-icon\"></slot>\n </div>`\n : nothing}\n <div class=\"text-container\">\n <div class=\"label\"><slot name=\"label\"></slot></div>\n ${this.hasStatus\n ? html`<div class=\"status\"><slot name=\"status\"></slot></div>`\n : nothing}\n </div>\n ${this.hasTrailingIcon\n ? html`<div class=\"icon-container\">\n ${this.hasTrailingIcon2\n ? html`<slot\n name=\"trailing-icon2\"\n class=\"icon trailing\"\n ></slot>`\n : nothing}\n <slot name=\"trailing-icon\" class=\"icon trailing\"></slot>\n </div>`\n : nothing}\n </div>\n </button>\n ${this.dividerRight\n ? html`<div class=\"divider-right\"></div>`\n : html`<div class=\"divider-right\" style=\"visibility: hidden;\"></div>`}\n </div>\n <div\n class=${classMap({\n 'integration-vessel-menu-container': true,\n show: this.activated,\n })}\n @click=${this.onIntegrationVesselMenuClick}\n >\n <slot name=\"integration-vessel-menu\"></slot>\n </div>\n `;\n }\n\n renderHug() {\n return html`\n <div class=\"button-vertical-divider-container\">\n <button\n class=${classMap(this.getButtonClasses())}\n ?disabled=${this.disabled}\n >\n <div class=\"content-container\">\n ${this.hasLeadingIcon\n ? html`<div class=\"icon leading\">\n <slot name=\"leading-icon\"></slot>\n </div>`\n : nothing}\n <div class=\"text-container\">\n <div class=\"label\"><slot name=\"label\"></slot></div>\n ${this.hasStatus\n ? html`<div class=\"status\"><slot name=\"status\"></slot></div>`\n : nothing}\n </div>\n ${this.hasTrailingIcon\n ? html`<div class=\"icon-container\">\n ${this.hasTrailingIcon2\n ? html`<slot\n name=\"trailing-icon2\"\n class=\"icon trailing\"\n ></slot>`\n : nothing}\n <slot name=\"trailing-icon\" class=\"icon trailing\"></slot>\n </div>`\n : nothing}\n </div>\n </button>\n ${this.dividerRight\n ? html`<div class=\"divider-right\"></div>`\n : html`<div class=\"divider-right\" style=\"visibility: hidden;\"></div>`}\n </div>\n <div\n class=${classMap({\n 'integration-vessel-menu-container': true,\n show: this.activated,\n })}\n @click=${this.onIntegrationVesselMenuClick}\n >\n <slot name=\"integration-vessel-menu\"></slot>\n </div>\n `;\n }\n\n override render() {\n switch (this.type) {\n case IntegrationButtonType.hug: {\n return this.renderHug();\n }\n case IntegrationButtonType.rich: {\n return this.renderRich();\n }\n case IntegrationButtonType.regular:\n default: {\n return this.renderRegular();\n }\n }\n }\n\n static override styles = unsafeCSS(compentStyle);\n\n override updated() {\n let dividerHeight = 40;\n if (this.type === IntegrationButtonType.hug) {\n dividerHeight = 32;\n }\n if (this.type === IntegrationButtonType.rich) {\n dividerHeight = 64;\n }\n this.style.setProperty(\n '--integration-button-divider-height',\n `${dividerHeight}px`\n );\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-integration-button': ObcIntegrationButton;\n }\n}\n"],"names":["IntegrationButtonVariant","IntegrationButtonType"],"mappings":"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"}
@@ -74,6 +74,20 @@ export declare class ObcAzimuthThruster extends LitElement {
74
74
  bottomPropeller: PropellerType;
75
75
  tickmarkStyle: TickmarkStyle;
76
76
  starboardPortIndicator: boolean;
77
+ /**
78
+ * Outer-ring diameter in CSS pixels. When set, the instrument renders at a
79
+ * fixed intrinsic size derived from the ring, arc shape and label reserve —
80
+ * so instruments sharing the same value have identical ring circumference
81
+ * regardless of label width or arc extent (like obc-donut-chart's
82
+ * fixedHeight). When unset (default), the instrument fills its container.
83
+ */
84
+ faceDiameter: number | undefined;
85
+ private _frame;
86
+ /** Whether the host size styles were set by applyPinnedHostSize. */
87
+ private _hostSizePinned;
88
+ private _resizeController;
89
+ firstUpdated(changed: PropertyValues): void;
90
+ updated(changed: PropertyValues): void;
77
91
  private get angleAdviceRaw();
78
92
  private getTickmarks;
79
93
  render(): import('lit-html').TemplateResult<1>;
@@ -1 +1 @@
1
- {"version":3,"file":"azimuth-thruster.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/azimuth-thruster/azimuth-thruster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,UAAU,EAAY,MAAM,KAAK,CAAC;AAEhD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,KAAK,CAAC;AACxC,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAC;AAGtD,OAAO,mBAAmB,CAAC;AAG3B,OAAO,EAAc,WAAW,EAAiB,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAW,aAAa,EAAe,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAYvD;;GAEG;AACH,qBACa,kBAAmB,SAAQ,UAAU;IAChD,OAAO,CAAC,iBAAiB,CAAiE;IAEhE,KAAK,SAAK;IACV,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5D,8CAA8C;IACpB,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/D,4EAA4E;IAE5E,eAAe,EAAE,OAAO,CAAS;IACjC,8CAA8C;IACpB,2BAA2B,EAAE,MAAM,CAAO;IACpE,8CAA8C;IACnB,qBAAqB,EAAE,OAAO,CAAS;IAClE,2EAA2E;IAChD,QAAQ,EAAE,OAAO,CAAS;IACrD,8CAA8C;IACD,mBAAmB,EAAE,OAAO,CAClE;IACP,2EAA2E;IACjD,2BAA2B,EAAE,MAAM,CAAK;IAClE,2EAA2E;IAChD,eAAe,EAAE,OAAO,CAAS;IAC5D;;;;OAIG;IACuB,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAM;IAC3E;;;OAGG;IACuB,yBAAyB,EAAE,MAAM,GAAG,SAAS,CAC3D;IACZ;;;OAGG;IACuB,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAC1D;IACe,UAAU,EAAE,OAAO,CAAS;IAC5B,eAAe,EAAE,OAAO,CAAS;IAClC,MAAM,SAAK;IACX,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7D,+CAA+C;IACrB,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IAChE,8EAA8E;IAE9E,gBAAgB,EAAE,OAAO,CAAS;IAClC,+CAA+C;IACrB,4BAA4B,EAAE,MAAM,CAAO;IACrE,+CAA+C;IACpB,sBAAsB,EAAE,OAAO,CAAS;IACnE,+CAA+C;IACF,oBAAoB,EAAE,OAAO,CACnE;IACP,6EAA6E;IACnD,4BAA4B,EAAE,MAAM,CAAK;IACzC,KAAK,EAAE,eAAe,CAA0B;IAChD,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,OAAO,CAAC,QAAQ,CAGb;IACH,OAAO,CAAC,SAAS,CAId;IAEM,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IA0BxB,OAAO,EAAE,MAAM,CAAK;IACD,cAAc,EAAE,OAAO,CAAQ;IACjC,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC,aAAa,EAAE,YAAY,EAAE,CAAM;IACnD,eAAe,EAAE,OAAO,CAAS;IAClC,YAAY,EAAE,aAAa,CAAsB;IACjD,eAAe,EAAE,aAAa,CAAsB;IACpD,aAAa,EAAE,aAAa,CAC9B;IACG,sBAAsB,EAAE,OAAO,CAAS;IAEnE,OAAO,KAAK,cAAc,GAqBzB;IAED,OAAO,CAAC,YAAY;IAyEX,MAAM;IAmEf,OAAgB,MAAM,0BAA6B;IAE1C,oBAAoB,IAAI,IAAI;CAKtC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,sBAAsB,EAAE,kBAAkB,CAAC;KAC5C;CACF"}
1
+ {"version":3,"file":"azimuth-thruster.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/azimuth-thruster/azimuth-thruster.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,UAAU,EAAY,MAAM,KAAK,CAAC;AAEhD,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,KAAK,CAAC;AAUxC,OAAO,EAAC,eAAe,EAAE,QAAQ,EAAC,MAAM,aAAa,CAAC;AAGtD,OAAO,mBAAmB,CAAC;AAE3B,OAAO,EAAc,WAAW,EAAiB,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAW,aAAa,EAAe,MAAM,sBAAsB,CAAC;AAC3E,OAAO,EAAC,YAAY,EAAC,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAC,aAAa,EAAC,MAAM,0BAA0B,CAAC;AAYvD;;GAEG;AACH,qBACa,kBAAmB,SAAQ,UAAU;IAChD,OAAO,CAAC,iBAAiB,CAAiE;IAEhE,KAAK,SAAK;IACV,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5D,8CAA8C;IACpB,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/D,4EAA4E;IAE5E,eAAe,EAAE,OAAO,CAAS;IACjC,8CAA8C;IACpB,2BAA2B,EAAE,MAAM,CAAO;IACpE,8CAA8C;IACnB,qBAAqB,EAAE,OAAO,CAAS;IAClE,2EAA2E;IAChD,QAAQ,EAAE,OAAO,CAAS;IACrD,8CAA8C;IACD,mBAAmB,EAAE,OAAO,CAClE;IACP,2EAA2E;IACjD,2BAA2B,EAAE,MAAM,CAAK;IAClE,2EAA2E;IAChD,eAAe,EAAE,OAAO,CAAS;IAC5D;;;;OAIG;IACuB,uBAAuB,EAAE,MAAM,GAAG,SAAS,CAAM;IAC3E;;;OAGG;IACuB,yBAAyB,EAAE,MAAM,GAAG,SAAS,CAC3D;IACZ;;;OAGG;IACuB,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAC1D;IACe,UAAU,EAAE,OAAO,CAAS;IAC5B,eAAe,EAAE,OAAO,CAAS;IAClC,MAAM,SAAK;IACX,cAAc,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7D,+CAA+C;IACrB,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IAChE,8EAA8E;IAE9E,gBAAgB,EAAE,OAAO,CAAS;IAClC,+CAA+C;IACrB,4BAA4B,EAAE,MAAM,CAAO;IACrE,+CAA+C;IACpB,sBAAsB,EAAE,OAAO,CAAS;IACnE,+CAA+C;IACF,oBAAoB,EAAE,OAAO,CACnE;IACP,6EAA6E;IACnD,4BAA4B,EAAE,MAAM,CAAK;IACzC,KAAK,EAAE,eAAe,CAA0B;IAChD,QAAQ,EAAE,QAAQ,CAAoB;IAEhE,OAAO,CAAC,QAAQ,CAGb;IACH,OAAO,CAAC,SAAS,CAId;IAEM,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IA0BxB,OAAO,EAAE,MAAM,CAAK;IACD,cAAc,EAAE,OAAO,CAAQ;IACjC,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC,aAAa,EAAE,YAAY,EAAE,CAAM;IACnD,eAAe,EAAE,OAAO,CAAS;IAClC,YAAY,EAAE,aAAa,CAAsB;IACjD,eAAe,EAAE,aAAa,CAAsB;IACpD,aAAa,EAAE,aAAa,CAC9B;IACG,sBAAsB,EAAE,OAAO,CAAS;IACnE;;;;;;OAMG;IAEH,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IAEjC,OAAO,CAAC,MAAM,CAA0B;IAExC,oEAAoE;IACpE,OAAO,CAAC,eAAe,CAAS;IAEhC,OAAO,CAAC,iBAAiB,CAAkC;IAElD,YAAY,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAK3C,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAS/C,OAAO,KAAK,cAAc,GAqBzB;IAED,OAAO,CAAC,YAAY;IAyEX,MAAM;IAyEf,OAAgB,MAAM,0BAA6B;IAE1C,oBAAoB,IAAI,IAAI;CAKtC;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,sBAAsB,EAAE,kBAAkB,CAAC;KAC5C;CACF"}
@@ -1,11 +1,12 @@
1
1
  import { unsafeCSS, LitElement, html } from "lit";
2
2
  import { property } from "lit/decorators.js";
3
+ import { ResizeController } from "@lit-labs/observers/resize-controller.js";
4
+ import { observeInnerBox, applyPinnedHostSize, computeRadialFrame, measureContainerPx, estimateLabelWidthPx } from "../../svghelpers/radial-frame.js";
3
5
  import { InstrumentState, Priority } from "../types.js";
4
6
  import { SetpointBundle } from "../../svghelpers/setpoint-bundle.js";
5
7
  import { thruster } from "../thruster/thruster.js";
6
8
  import "../watch/watch.js";
7
9
  import componentStyle from "./azimuth-thruster.css.js";
8
- import { ifDefined } from "lit/directives/if-defined.js";
9
10
  import { AdviceState } from "../watch/advice.js";
10
11
  import { TickmarkStyle, TickmarkType } from "../watch/tickmark.js";
11
12
  import { PropellerType } from "../thruster/propeller.js";
@@ -71,6 +72,8 @@ let ObcAzimuthThruster = class extends LitElement {
71
72
  this.bottomPropeller = PropellerType.none;
72
73
  this.tickmarkStyle = TickmarkStyle.regular;
73
74
  this.starboardPortIndicator = false;
75
+ this._hostSizePinned = false;
76
+ this._resizeController = new ResizeController(this, {});
74
77
  }
75
78
  willUpdate(changed) {
76
79
  super.willUpdate(changed);
@@ -97,6 +100,18 @@ let ObcAzimuthThruster = class extends LitElement {
97
100
  animateSetpoint: this.animateSetpoint
98
101
  });
99
102
  }
103
+ firstUpdated(changed) {
104
+ super.firstUpdated(changed);
105
+ observeInnerBox(this._resizeController, this.renderRoot);
106
+ }
107
+ updated(changed) {
108
+ super.updated(changed);
109
+ this._hostSizePinned = applyPinnedHostSize(
110
+ this,
111
+ this._frame,
112
+ this._hostSizePinned
113
+ );
114
+ }
100
115
  get angleAdviceRaw() {
101
116
  return this.angleAdvices.map((advice) => {
102
117
  const triggered = this.angleSetpoint !== void 0 && mapAngle0to360(this.angleSetpoint - advice.minAngle) < 180 && mapAngle0to360(this.angleSetpoint - advice.maxAngle) > 180;
@@ -168,19 +183,21 @@ let ObcAzimuthThruster = class extends LitElement {
168
183
  render() {
169
184
  const rotateAngle = this.angle;
170
185
  const tickmarks = this.getTickmarks();
171
- let viewBox;
172
- if (!this.hasLabelSpacer) {
173
- viewBox = "-192 -192 384 384";
174
- } else if (this.showLabels && !this.tickmarksInside) {
175
- viewBox = "-236 -236 472 472";
176
- } else {
177
- viewBox = "-200 -200 400 400";
178
- }
186
+ const frame = computeRadialFrame({
187
+ basePadding: this.hasLabelSpacer ? 24 : 16,
188
+ labelWidthPx: this.hasLabelSpacer && !this.tickmarksInside ? estimateLabelWidthPx(tickmarks.map((t) => t.text)) : 0,
189
+ containerPx: measureContainerPx(this),
190
+ faceDiameter: this.faceDiameter
191
+ });
192
+ this._frame = frame;
193
+ const shownTickmarks = frame.labelsHidden ? tickmarks.map((t) => ({ ...t, text: void 0 })) : tickmarks;
194
+ const viewBox = frame.viewBox;
179
195
  return html`
180
196
  <div class="container">
181
197
  <obc-watch
182
198
  .touching=${this.touching}
183
- .tickmarks=${tickmarks}
199
+ .arcFrame=${frame}
200
+ .tickmarks=${shownTickmarks}
184
201
  .state=${this.state}
185
202
  .priority=${this.priority}
186
203
  .angleSetpoint=${this.angleSetpoint}
@@ -191,7 +208,6 @@ let ObcAzimuthThruster = class extends LitElement {
191
208
  .animateSetpoint=${this.animateSetpoint}
192
209
  .tickmarksInside=${this.tickmarksInside}
193
210
  .tickmarkStyle=${this.tickmarkStyle}
194
- padding=${ifDefined(!this.hasLabelSpacer ? 16 : void 0)}
195
211
  .advices=${this.angleAdviceRaw}
196
212
  .starboardPortIndicator=${this.starboardPortIndicator}
197
213
  ></obc-watch>
@@ -337,6 +353,9 @@ __decorateClass([
337
353
  __decorateClass([
338
354
  property({ type: Boolean })
339
355
  ], ObcAzimuthThruster.prototype, "starboardPortIndicator", 2);
356
+ __decorateClass([
357
+ property({ type: Number, attribute: "face-diameter" })
358
+ ], ObcAzimuthThruster.prototype, "faceDiameter", 2);
340
359
  ObcAzimuthThruster = __decorateClass([
341
360
  customElement("obc-azimuth-thruster")
342
361
  ], ObcAzimuthThruster);
@@ -1 +1 @@
1
- {"version":3,"file":"azimuth-thruster.js","sources":["../../../src/navigation-instruments/azimuth-thruster/azimuth-thruster.ts"],"sourcesContent":["import {html, LitElement, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport type {PropertyValues} from 'lit';\nimport {InstrumentState, Priority} from '../types.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {thruster} from '../thruster/thruster.js';\nimport '../watch/watch.js';\nimport componentStyle from './azimuth-thruster.css?inline';\nimport {ifDefined} from 'lit/directives/if-defined.js';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {Tickmark, TickmarkStyle, TickmarkType} from '../watch/tickmark.js';\nimport {LinearAdvice} from '../thruster/advice.js';\nimport {PropellerType} from '../thruster/propeller.js';\nimport {customElement} from '../../decorator.js';\n\nfunction mapAngle0to360(angle: number): number {\n const a = angle % 360;\n if (a >= 0) {\n return a;\n } else {\n return a + 360;\n }\n}\n\n/**\n * @stable\n */\n@customElement('obc-azimuth-thruster')\nexport class ObcAzimuthThruster extends LitElement {\n private _thrustSetpointId = `azimuth-thrust-sp-${Math.random().toString(36).slice(2, 9)}`;\n\n @property({type: Number}) angle = 0;\n @property({type: Number}) angleSetpoint: number | undefined;\n /** @availableWhen angleSetpoint!=undefined */\n @property({type: Number}) newAngleSetpoint: number | undefined;\n /** @availableWhen angleSetpoint!=undefined && autoAtAngleSetpoint==false */\n @property({type: Boolean})\n atAngleSetpoint: boolean = false;\n /** @availableWhen angleSetpoint!=undefined */\n @property({type: Number}) angleSetpointAtZeroDeadband: number = 0.5;\n /** @availableWhen angleSetpoint!=undefined */\n @property({type: Boolean}) angleSetpointOverride: boolean = false;\n /** @availableWhen angleSetpoint!=undefined || thrustSetpoint!=undefined */\n @property({type: Boolean}) touching: boolean = false;\n /** @availableWhen angleSetpoint!=undefined */\n @property({type: Boolean, attribute: false}) autoAtAngleSetpoint: boolean =\n true;\n /** @availableWhen angleSetpoint!=undefined && autoAtAngleSetpoint==true */\n @property({type: Number}) autoAtAngleSetpointDeadband: number = 2;\n /** @availableWhen angleSetpoint!=undefined || thrustSetpoint!=undefined */\n @property({type: Boolean}) animateSetpoint: boolean = false;\n /**\n * Interval (in degrees) for primary tickmarks.\n * When undefined or <= 0, no primary tickmarks are shown (only the zero line).\n * Default 90 gives ticks at 0°, 90°, 180°, 270°.\n */\n @property({type: Number}) primaryTickmarkInterval: number | undefined = 90;\n /**\n * Interval (in degrees) for secondary tickmarks.\n * When undefined or <= 0, no secondary tickmarks are shown.\n */\n @property({type: Number}) secondaryTickmarkInterval: number | undefined =\n undefined;\n /**\n * Interval (in degrees) for tertiary tickmarks.\n * When undefined or <= 0, no tertiary tickmarks are shown.\n */\n @property({type: Number}) tertiaryTickmarkInterval: number | undefined =\n undefined;\n @property({type: Boolean}) showLabels: boolean = false;\n @property({type: Boolean}) tickmarksInside: boolean = false;\n @property({type: Number}) thrust = 0;\n @property({type: Number}) thrustSetpoint: number | undefined;\n /** @availableWhen thrustSetpoint!=undefined */\n @property({type: Number}) newThrustSetpoint: number | undefined;\n /** @availableWhen thrustSetpoint!=undefined && autoAtThrustSetpoint==false */\n @property({type: Boolean})\n atThrustSetpoint: boolean = false;\n /** @availableWhen thrustSetpoint!=undefined */\n @property({type: Number}) thrustSetpointAtZeroDeadband: number = 0.1;\n /** @availableWhen thrustSetpoint!=undefined */\n @property({type: Boolean}) thrustSetpointOverride: boolean = false;\n /** @availableWhen thrustSetpoint!=undefined */\n @property({type: Boolean, attribute: false}) autoAtThrustSetpoint: boolean =\n true;\n /** @availableWhen thrustSetpoint!=undefined && autoAtThrustSetpoint==true */\n @property({type: Number}) autoAtThrustSetpointDeadband: number = 1;\n @property({type: String}) state: InstrumentState = InstrumentState.active;\n @property({type: String}) priority: Priority = Priority.regular;\n\n private _angleSp = new SetpointBundle({\n angularWraparound: true,\n onAnimationEnd: () => this.requestUpdate(),\n });\n private _thrustSp = new SetpointBundle({\n defaultDeadband: 1,\n defaultZeroDeadband: 0.1,\n onAnimationEnd: () => this.requestUpdate(),\n });\n\n override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n // Sync public prefixed props → bundles\n this._angleSp.sync({\n setpoint: this.angleSetpoint,\n newSetpoint: this.newAngleSetpoint,\n atSetpoint: this.atAngleSetpoint,\n touching: this.touching,\n autoAtSetpoint: this.autoAtAngleSetpoint,\n autoAtSetpointDeadband: this.autoAtAngleSetpointDeadband,\n setpointAtZeroDeadband: this.angleSetpointAtZeroDeadband,\n setpointOverride: this.angleSetpointOverride,\n animateSetpoint: this.animateSetpoint,\n });\n this._thrustSp.sync({\n setpoint: this.thrustSetpoint,\n newSetpoint: this.newThrustSetpoint,\n touching: this.touching,\n atSetpoint: this.atThrustSetpoint,\n autoAtSetpoint: this.autoAtThrustSetpoint,\n autoAtSetpointDeadband: this.autoAtThrustSetpointDeadband,\n setpointAtZeroDeadband: this.thrustSetpointAtZeroDeadband,\n setpointOverride: this.thrustSetpointOverride,\n animateSetpoint: this.animateSetpoint,\n });\n }\n @property({type: Number}) loading: number = 0;\n @property({type: Boolean, attribute: false}) hasLabelSpacer: boolean = true;\n @property({type: Array, attribute: false}) angleAdvices: AngleAdvice[] = [];\n @property({type: Array, attribute: false}) thrustAdvices: LinearAdvice[] = [];\n @property({type: Boolean}) singleDirection: boolean = false;\n @property({type: String}) topPropeller: PropellerType = PropellerType.none;\n @property({type: String}) bottomPropeller: PropellerType = PropellerType.none;\n @property({type: String}) tickmarkStyle: TickmarkStyle =\n TickmarkStyle.regular;\n @property({type: Boolean}) starboardPortIndicator: boolean = false;\n\n private get angleAdviceRaw(): AngleAdviceRaw[] {\n return this.angleAdvices.map((advice) => {\n const triggered =\n this.angleSetpoint !== undefined &&\n mapAngle0to360(this.angleSetpoint - advice.minAngle) < 180 &&\n mapAngle0to360(this.angleSetpoint - advice.maxAngle) > 180;\n let state: AdviceState;\n if (triggered) {\n state = AdviceState.triggered;\n } else if (advice.hinted) {\n state = AdviceState.hinted;\n } else {\n state = AdviceState.regular;\n }\n return {\n minAngle: advice.minAngle,\n maxAngle: advice.maxAngle,\n type: advice.type,\n state,\n };\n });\n }\n\n private getTickmarks(): Tickmark[] {\n const tickmarks: Tickmark[] = [];\n const skipAngles: number[] = [];\n\n // Helper for signed label text (0-180 positive, 181-359 negative)\n const labelText = (angle: number): string | undefined => {\n if (!this.showLabels) return undefined;\n return angle <= 180 ? `${angle}` : `${angle - 360}`;\n };\n\n // Always add the zero line\n tickmarks.push({\n angle: 0,\n type: TickmarkType.zeroLine,\n text: this.showLabels ? '0' : undefined,\n });\n skipAngles.push(0);\n\n // Primary tickmarks — skip when undefined or <= 0 to prevent infinite loops\n const primaryInterval = this.primaryTickmarkInterval;\n if (\n primaryInterval !== undefined &&\n primaryInterval > 0 &&\n Number.isFinite(primaryInterval)\n ) {\n for (let i = primaryInterval; i < 360; i += primaryInterval) {\n if (skipAngles.includes(i)) continue;\n tickmarks.push({\n angle: i,\n type: TickmarkType.primary,\n text: labelText(i),\n });\n skipAngles.push(i);\n }\n }\n\n // Secondary tickmarks — skip when undefined or <= 0\n const secondaryInterval = this.secondaryTickmarkInterval;\n if (\n secondaryInterval !== undefined &&\n secondaryInterval > 0 &&\n Number.isFinite(secondaryInterval)\n ) {\n for (let i = 0; i < 360; i += secondaryInterval) {\n if (skipAngles.includes(i)) continue;\n tickmarks.push({\n angle: i,\n type: TickmarkType.secondary,\n });\n skipAngles.push(i);\n }\n }\n\n // Tertiary tickmarks — skip when undefined or <= 0\n const tertiaryInterval = this.tertiaryTickmarkInterval;\n if (\n tertiaryInterval !== undefined &&\n tertiaryInterval > 0 &&\n Number.isFinite(tertiaryInterval)\n ) {\n for (let i = 0; i < 360; i += tertiaryInterval) {\n if (skipAngles.includes(i)) continue;\n tickmarks.push({\n angle: i,\n type: TickmarkType.tertiary,\n });\n skipAngles.push(i);\n }\n }\n\n return tickmarks;\n }\n\n override render() {\n const rotateAngle = this.angle;\n\n const tickmarks = this.getTickmarks();\n\n let viewBox: string;\n if (!this.hasLabelSpacer) {\n viewBox = '-192 -192 384 384';\n } else if (this.showLabels && !this.tickmarksInside) {\n viewBox = '-236 -236 472 472';\n } else {\n viewBox = '-200 -200 400 400';\n }\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .tickmarks=${tickmarks}\n .state=${this.state}\n .priority=${this.priority}\n .angleSetpoint=${this.angleSetpoint}\n .newAngleSetpoint=${this.newAngleSetpoint}\n .atAngleSetpoint=${this._angleSp.computeAtSetpoint(this.angle)}\n .angleSetpointAtZeroDeadband=${this.angleSetpointAtZeroDeadband}\n .setpointOverride=${this.angleSetpointOverride}\n .animateSetpoint=${this.animateSetpoint}\n .tickmarksInside=${this.tickmarksInside}\n .tickmarkStyle=${this.tickmarkStyle}\n padding=${ifDefined(!this.hasLabelSpacer ? 16 : undefined)}\n .advices=${this.angleAdviceRaw}\n .starboardPortIndicator=${this.starboardPortIndicator}\n ></obc-watch>\n <svg viewBox=${viewBox} xmlns=\"http://www.w3.org/2000/svg\">\n <g transform=\"rotate(${rotateAngle})\">\n ${thruster(\n this.thrust,\n this.thrustSetpoint,\n this.state,\n this.priority,\n {\n atSetpoint: this.atThrustSetpoint,\n singleSided: true,\n singleDirection: false,\n singleDirectionHalfSize: this.singleDirection,\n tunnel: false,\n autoAtSetpoint: this.autoAtThrustSetpoint,\n autoAtSetpointDeadband: this.autoAtThrustSetpointDeadband,\n setpointAtZeroDeadband: this.thrustSetpointAtZeroDeadband,\n touching: this.touching,\n advices: this.thrustAdvices,\n topPropeller: this.topPropeller,\n bottomPropeller: this.bottomPropeller,\n narrow: true,\n newSetpoint: this.newThrustSetpoint,\n setpointId: this._thrustSetpointId,\n animateSetpoint: this.animateSetpoint,\n departingNewSetpoint: this._thrustSp.departingNewSetpoint,\n setpointOverride: this.thrustSetpointOverride,\n }\n )}\n </g>\n </svg>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._angleSp.dispose();\n this._thrustSp.dispose();\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-azimuth-thruster': ObcAzimuthThruster;\n }\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"azimuth-thruster.js","sources":["../../../src/navigation-instruments/azimuth-thruster/azimuth-thruster.ts"],"sourcesContent":["import {html, LitElement, unsafeCSS} from 'lit';\nimport {property} from 'lit/decorators.js';\nimport type {PropertyValues} from 'lit';\nimport {ResizeController} from '@lit-labs/observers/resize-controller.js';\nimport {\n applyPinnedHostSize,\n computeRadialFrame,\n estimateLabelWidthPx,\n measureContainerPx,\n observeInnerBox,\n type RadialFrame,\n} from '../../svghelpers/radial-frame.js';\nimport {InstrumentState, Priority} from '../types.js';\nimport {SetpointBundle} from '../../svghelpers/setpoint-bundle.js';\nimport {thruster} from '../thruster/thruster.js';\nimport '../watch/watch.js';\nimport componentStyle from './azimuth-thruster.css?inline';\nimport {AdviceState, AngleAdvice, AngleAdviceRaw} from '../watch/advice.js';\nimport {Tickmark, TickmarkStyle, TickmarkType} from '../watch/tickmark.js';\nimport {LinearAdvice} from '../thruster/advice.js';\nimport {PropellerType} from '../thruster/propeller.js';\nimport {customElement} from '../../decorator.js';\n\nfunction mapAngle0to360(angle: number): number {\n const a = angle % 360;\n if (a >= 0) {\n return a;\n } else {\n return a + 360;\n }\n}\n\n/**\n * @stable\n */\n@customElement('obc-azimuth-thruster')\nexport class ObcAzimuthThruster extends LitElement {\n private _thrustSetpointId = `azimuth-thrust-sp-${Math.random().toString(36).slice(2, 9)}`;\n\n @property({type: Number}) angle = 0;\n @property({type: Number}) angleSetpoint: number | undefined;\n /** @availableWhen angleSetpoint!=undefined */\n @property({type: Number}) newAngleSetpoint: number | undefined;\n /** @availableWhen angleSetpoint!=undefined && autoAtAngleSetpoint==false */\n @property({type: Boolean})\n atAngleSetpoint: boolean = false;\n /** @availableWhen angleSetpoint!=undefined */\n @property({type: Number}) angleSetpointAtZeroDeadband: number = 0.5;\n /** @availableWhen angleSetpoint!=undefined */\n @property({type: Boolean}) angleSetpointOverride: boolean = false;\n /** @availableWhen angleSetpoint!=undefined || thrustSetpoint!=undefined */\n @property({type: Boolean}) touching: boolean = false;\n /** @availableWhen angleSetpoint!=undefined */\n @property({type: Boolean, attribute: false}) autoAtAngleSetpoint: boolean =\n true;\n /** @availableWhen angleSetpoint!=undefined && autoAtAngleSetpoint==true */\n @property({type: Number}) autoAtAngleSetpointDeadband: number = 2;\n /** @availableWhen angleSetpoint!=undefined || thrustSetpoint!=undefined */\n @property({type: Boolean}) animateSetpoint: boolean = false;\n /**\n * Interval (in degrees) for primary tickmarks.\n * When undefined or <= 0, no primary tickmarks are shown (only the zero line).\n * Default 90 gives ticks at 0°, 90°, 180°, 270°.\n */\n @property({type: Number}) primaryTickmarkInterval: number | undefined = 90;\n /**\n * Interval (in degrees) for secondary tickmarks.\n * When undefined or <= 0, no secondary tickmarks are shown.\n */\n @property({type: Number}) secondaryTickmarkInterval: number | undefined =\n undefined;\n /**\n * Interval (in degrees) for tertiary tickmarks.\n * When undefined or <= 0, no tertiary tickmarks are shown.\n */\n @property({type: Number}) tertiaryTickmarkInterval: number | undefined =\n undefined;\n @property({type: Boolean}) showLabels: boolean = false;\n @property({type: Boolean}) tickmarksInside: boolean = false;\n @property({type: Number}) thrust = 0;\n @property({type: Number}) thrustSetpoint: number | undefined;\n /** @availableWhen thrustSetpoint!=undefined */\n @property({type: Number}) newThrustSetpoint: number | undefined;\n /** @availableWhen thrustSetpoint!=undefined && autoAtThrustSetpoint==false */\n @property({type: Boolean})\n atThrustSetpoint: boolean = false;\n /** @availableWhen thrustSetpoint!=undefined */\n @property({type: Number}) thrustSetpointAtZeroDeadband: number = 0.1;\n /** @availableWhen thrustSetpoint!=undefined */\n @property({type: Boolean}) thrustSetpointOverride: boolean = false;\n /** @availableWhen thrustSetpoint!=undefined */\n @property({type: Boolean, attribute: false}) autoAtThrustSetpoint: boolean =\n true;\n /** @availableWhen thrustSetpoint!=undefined && autoAtThrustSetpoint==true */\n @property({type: Number}) autoAtThrustSetpointDeadband: number = 1;\n @property({type: String}) state: InstrumentState = InstrumentState.active;\n @property({type: String}) priority: Priority = Priority.regular;\n\n private _angleSp = new SetpointBundle({\n angularWraparound: true,\n onAnimationEnd: () => this.requestUpdate(),\n });\n private _thrustSp = new SetpointBundle({\n defaultDeadband: 1,\n defaultZeroDeadband: 0.1,\n onAnimationEnd: () => this.requestUpdate(),\n });\n\n override willUpdate(changed: PropertyValues): void {\n super.willUpdate(changed);\n // Sync public prefixed props → bundles\n this._angleSp.sync({\n setpoint: this.angleSetpoint,\n newSetpoint: this.newAngleSetpoint,\n atSetpoint: this.atAngleSetpoint,\n touching: this.touching,\n autoAtSetpoint: this.autoAtAngleSetpoint,\n autoAtSetpointDeadband: this.autoAtAngleSetpointDeadband,\n setpointAtZeroDeadband: this.angleSetpointAtZeroDeadband,\n setpointOverride: this.angleSetpointOverride,\n animateSetpoint: this.animateSetpoint,\n });\n this._thrustSp.sync({\n setpoint: this.thrustSetpoint,\n newSetpoint: this.newThrustSetpoint,\n touching: this.touching,\n atSetpoint: this.atThrustSetpoint,\n autoAtSetpoint: this.autoAtThrustSetpoint,\n autoAtSetpointDeadband: this.autoAtThrustSetpointDeadband,\n setpointAtZeroDeadband: this.thrustSetpointAtZeroDeadband,\n setpointOverride: this.thrustSetpointOverride,\n animateSetpoint: this.animateSetpoint,\n });\n }\n @property({type: Number}) loading: number = 0;\n @property({type: Boolean, attribute: false}) hasLabelSpacer: boolean = true;\n @property({type: Array, attribute: false}) angleAdvices: AngleAdvice[] = [];\n @property({type: Array, attribute: false}) thrustAdvices: LinearAdvice[] = [];\n @property({type: Boolean}) singleDirection: boolean = false;\n @property({type: String}) topPropeller: PropellerType = PropellerType.none;\n @property({type: String}) bottomPropeller: PropellerType = PropellerType.none;\n @property({type: String}) tickmarkStyle: TickmarkStyle =\n TickmarkStyle.regular;\n @property({type: Boolean}) starboardPortIndicator: boolean = false;\n /**\n * Outer-ring diameter in CSS pixels. When set, the instrument renders at a\n * fixed intrinsic size derived from the ring, arc shape and label reserve —\n * so instruments sharing the same value have identical ring circumference\n * regardless of label width or arc extent (like obc-donut-chart's\n * fixedHeight). When unset (default), the instrument fills its container.\n */\n @property({type: Number, attribute: 'face-diameter'})\n faceDiameter: number | undefined;\n\n private _frame: RadialFrame | undefined;\n\n /** Whether the host size styles were set by applyPinnedHostSize. */\n private _hostSizePinned = false;\n\n private _resizeController = new ResizeController(this, {});\n\n override firstUpdated(changed: PropertyValues): void {\n super.firstUpdated(changed);\n observeInnerBox(this._resizeController, this.renderRoot);\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n this._hostSizePinned = applyPinnedHostSize(\n this,\n this._frame,\n this._hostSizePinned\n );\n }\n\n private get angleAdviceRaw(): AngleAdviceRaw[] {\n return this.angleAdvices.map((advice) => {\n const triggered =\n this.angleSetpoint !== undefined &&\n mapAngle0to360(this.angleSetpoint - advice.minAngle) < 180 &&\n mapAngle0to360(this.angleSetpoint - advice.maxAngle) > 180;\n let state: AdviceState;\n if (triggered) {\n state = AdviceState.triggered;\n } else if (advice.hinted) {\n state = AdviceState.hinted;\n } else {\n state = AdviceState.regular;\n }\n return {\n minAngle: advice.minAngle,\n maxAngle: advice.maxAngle,\n type: advice.type,\n state,\n };\n });\n }\n\n private getTickmarks(): Tickmark[] {\n const tickmarks: Tickmark[] = [];\n const skipAngles: number[] = [];\n\n // Helper for signed label text (0-180 positive, 181-359 negative)\n const labelText = (angle: number): string | undefined => {\n if (!this.showLabels) return undefined;\n return angle <= 180 ? `${angle}` : `${angle - 360}`;\n };\n\n // Always add the zero line\n tickmarks.push({\n angle: 0,\n type: TickmarkType.zeroLine,\n text: this.showLabels ? '0' : undefined,\n });\n skipAngles.push(0);\n\n // Primary tickmarks — skip when undefined or <= 0 to prevent infinite loops\n const primaryInterval = this.primaryTickmarkInterval;\n if (\n primaryInterval !== undefined &&\n primaryInterval > 0 &&\n Number.isFinite(primaryInterval)\n ) {\n for (let i = primaryInterval; i < 360; i += primaryInterval) {\n if (skipAngles.includes(i)) continue;\n tickmarks.push({\n angle: i,\n type: TickmarkType.primary,\n text: labelText(i),\n });\n skipAngles.push(i);\n }\n }\n\n // Secondary tickmarks — skip when undefined or <= 0\n const secondaryInterval = this.secondaryTickmarkInterval;\n if (\n secondaryInterval !== undefined &&\n secondaryInterval > 0 &&\n Number.isFinite(secondaryInterval)\n ) {\n for (let i = 0; i < 360; i += secondaryInterval) {\n if (skipAngles.includes(i)) continue;\n tickmarks.push({\n angle: i,\n type: TickmarkType.secondary,\n });\n skipAngles.push(i);\n }\n }\n\n // Tertiary tickmarks — skip when undefined or <= 0\n const tertiaryInterval = this.tertiaryTickmarkInterval;\n if (\n tertiaryInterval !== undefined &&\n tertiaryInterval > 0 &&\n Number.isFinite(tertiaryInterval)\n ) {\n for (let i = 0; i < 360; i += tertiaryInterval) {\n if (skipAngles.includes(i)) continue;\n tickmarks.push({\n angle: i,\n type: TickmarkType.tertiary,\n });\n skipAngles.push(i);\n }\n }\n\n return tickmarks;\n }\n\n override render() {\n const rotateAngle = this.angle;\n\n const tickmarks = this.getTickmarks();\n\n const frame = computeRadialFrame({\n basePadding: this.hasLabelSpacer ? 24 : 16,\n labelWidthPx:\n this.hasLabelSpacer && !this.tickmarksInside\n ? estimateLabelWidthPx(tickmarks.map((t) => t.text))\n : 0,\n containerPx: measureContainerPx(this),\n faceDiameter: this.faceDiameter,\n });\n this._frame = frame;\n const shownTickmarks = frame.labelsHidden\n ? tickmarks.map((t) => ({...t, text: undefined}))\n : tickmarks;\n const viewBox = frame.viewBox;\n\n return html`\n <div class=\"container\">\n <obc-watch\n .touching=${this.touching}\n .arcFrame=${frame}\n .tickmarks=${shownTickmarks}\n .state=${this.state}\n .priority=${this.priority}\n .angleSetpoint=${this.angleSetpoint}\n .newAngleSetpoint=${this.newAngleSetpoint}\n .atAngleSetpoint=${this._angleSp.computeAtSetpoint(this.angle)}\n .angleSetpointAtZeroDeadband=${this.angleSetpointAtZeroDeadband}\n .setpointOverride=${this.angleSetpointOverride}\n .animateSetpoint=${this.animateSetpoint}\n .tickmarksInside=${this.tickmarksInside}\n .tickmarkStyle=${this.tickmarkStyle}\n .advices=${this.angleAdviceRaw}\n .starboardPortIndicator=${this.starboardPortIndicator}\n ></obc-watch>\n <svg viewBox=${viewBox} xmlns=\"http://www.w3.org/2000/svg\">\n <g transform=\"rotate(${rotateAngle})\">\n ${thruster(\n this.thrust,\n this.thrustSetpoint,\n this.state,\n this.priority,\n {\n atSetpoint: this.atThrustSetpoint,\n singleSided: true,\n singleDirection: false,\n singleDirectionHalfSize: this.singleDirection,\n tunnel: false,\n autoAtSetpoint: this.autoAtThrustSetpoint,\n autoAtSetpointDeadband: this.autoAtThrustSetpointDeadband,\n setpointAtZeroDeadband: this.thrustSetpointAtZeroDeadband,\n touching: this.touching,\n advices: this.thrustAdvices,\n topPropeller: this.topPropeller,\n bottomPropeller: this.bottomPropeller,\n narrow: true,\n newSetpoint: this.newThrustSetpoint,\n setpointId: this._thrustSetpointId,\n animateSetpoint: this.animateSetpoint,\n departingNewSetpoint: this._thrustSp.departingNewSetpoint,\n setpointOverride: this.thrustSetpointOverride,\n }\n )}\n </g>\n </svg>\n </div>\n `;\n }\n\n static override styles = unsafeCSS(componentStyle);\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this._angleSp.dispose();\n this._thrustSp.dispose();\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'obc-azimuth-thruster': ObcAzimuthThruster;\n }\n}\n"],"names":[],"mappings":"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"}
@@ -43,9 +43,9 @@ export declare enum CompassPriorityElement {
43
43
  * Supports spinning dots (`rotType="dots"`) — the dot animation is
44
44
  * amplified by `rotDotAnimationFactor` so small physical values still
45
45
  * read at a glance — and a banana-shaped arc bar (`rotType="bar"`)
46
- * showing the HDG→COG span. Bar extent is driven by the physical value
47
- * only (gain is not applied). Position on the outer scale ring or inner
48
- * circle via `rotPosition`.
46
+ * showing the rate of turn as an arc anchored at the current heading.
47
+ * Bar extent is driven by the physical value only (gain is not applied).
48
+ * Position on the outer scale ring or inner circle via `rotPosition`.
49
49
  * - **Environmental overlays**: Wind speed/direction and current
50
50
  * speed/direction indicators on the watch face.
51
51
  * - **Vessel image**: Configurable vessel silhouette centered on the
@@ -78,59 +78,69 @@ export declare enum CompassPriorityElement {
78
78
  * ></obc-compass>
79
79
  * ```
80
80
  *
81
- * @property {number} heading - The current heading of the vessel in degrees.
82
- * @property {number} courseOverGround - The current course over ground in degrees.
83
- * @property {number | null} headingSetpoint - The set point for the heading in degrees.
84
- * @property {boolean} atHeadingSetpoint - Indicates if the vessel is at the heading set point.
85
- * @property {boolean} autoAtHeadingSetpoint - Enables automatic at heading set point calculation.
86
- * @property {number} autoAtHeadingSetpointDeadband - The deadband for the heading set point in degrees.
87
- * @property {boolean} touching - Indicates if the compass is being touched.
88
- * @property {Array<AngleAdvice>} headingAdvices - An array of angle advices for the compass.
89
- * @property {number | null} currentWindSpeedKnots - The wind speed in knots.
90
- * @property {number | null} windFromDirection - The direction the wind is coming from in degrees.
91
- * @property {number | null} currentSpeed - The current speed, number of arrows.
92
- * @property {number | null} currentFromDirection - The direction the current is coming from in degrees.
93
- * @property {VesselImage} vesselImage - The image of the vessel.
94
- * @property {number|undefined} rateOfTurnDegreesPerMinute - Measured rate of turn in degrees per minute (the AIS / ITU-R M.1371 convention). Sign controls direction (positive = starboard / clockwise). Drives both the bar extent and the dot animation.
95
- * @property {number} rotDotAnimationFactor - Visual amplification for the dot animation only. Default `18` (≈1 rpm at 20°/min).
96
- * @property {number} rotationsPerMinute - **Deprecated.** Use `rateOfTurnDegreesPerMinute` instead. Kept as a backward-compatible fallback when `rateOfTurnDegreesPerMinute` is `undefined`.
97
- * @property {RotType} rotType - ROT display mode: `'dots'` (spinning dots, default) or `'bar'` (arc bar from HDG to COG).
98
- * @property {RotPosition} rotPosition - ROT track position: `'innerCircle'` (default) or `'scale'` (on the outer ring).
99
- * @property {Priority} priority - Color priority: `Priority.enhanced` uses the blue/enhanced color palette, `Priority.regular` (default) uses the standard palette.
100
81
  *
101
82
  * @ignition-base-height: 512px
102
83
  * @ignition-base-width: 512px
103
84
  * @stable
104
85
  */
105
86
  export declare class ObcCompass extends LitElement {
87
+ /** The current heading of the vessel in degrees. */
106
88
  heading: number;
89
+ /** The current course over ground in degrees. */
107
90
  courseOverGround: number;
91
+ /** The set point for the heading in degrees. */
108
92
  headingSetpoint: number | null;
109
93
  /** @availableWhen headingSetpoint!=null */
110
94
  newHeadingSetpoint: number | undefined;
111
- /** @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==false */
95
+ /**
96
+ * Indicates if the vessel is at the heading set point.
97
+ * @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==false
98
+ */
112
99
  atHeadingSetpoint: boolean;
113
100
  /** @availableWhen headingSetpoint!=null */
114
101
  headingSetpointAtZeroDeadband: number;
115
102
  /** @availableWhen headingSetpoint!=null */
116
103
  headingSetpointOverride: boolean;
117
- /** @availableWhen headingSetpoint!=null */
104
+ /**
105
+ * Enables automatic at heading set point calculation.
106
+ * @availableWhen headingSetpoint!=null
107
+ */
118
108
  autoAtHeadingSetpoint: boolean;
119
- /** @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==true */
109
+ /**
110
+ * The deadband for the heading set point in degrees.
111
+ * @availableWhen headingSetpoint!=null && autoAtHeadingSetpoint==true
112
+ */
120
113
  autoAtHeadingSetpointDeadband: number;
121
114
  /** @availableWhen headingSetpoint!=null */
122
115
  animateSetpoint: boolean;
123
- /** @availableWhen headingSetpoint!=null */
116
+ /**
117
+ * Indicates if the compass is being touched.
118
+ * @availableWhen headingSetpoint!=null
119
+ */
124
120
  touching: boolean;
121
+ /** An array of angle advices for the compass. */
125
122
  headingAdvices: AngleAdvice[];
126
- /** @availableWhen windFromDirection!=null */
123
+ /**
124
+ * The wind speed in knots.
125
+ * @availableWhen windFromDirection!=null
126
+ */
127
127
  currentWindSpeedKnots: number | null;
128
- /** @availableWhen currentWindSpeedKnots!=null */
128
+ /**
129
+ * The direction the wind is coming from in degrees.
130
+ * @availableWhen currentWindSpeedKnots!=null
131
+ */
129
132
  windFromDirection: number | null;
130
- /** @availableWhen currentFromDirection!=null */
133
+ /**
134
+ * The current speed, number of arrows.
135
+ * @availableWhen currentFromDirection!=null
136
+ */
131
137
  currentSpeed: number | null;
132
- /** @availableWhen currentSpeed!=null */
138
+ /**
139
+ * The direction the current is coming from in degrees.
140
+ * @availableWhen currentSpeed!=null
141
+ */
133
142
  currentFromDirection: number | null;
143
+ /** The image of the vessel. */
134
144
  vesselImage: VesselImage;
135
145
  /**
136
146
  * Measured rate of turn in degrees per minute (positive = starboard).
@@ -147,12 +157,18 @@ export declare class ObcCompass extends LitElement {
147
157
  */
148
158
  rotDotAnimationFactor: number;
149
159
  /**
160
+ * Legacy rate-of-turn input, in rotations per minute. When
161
+ * `rateOfTurnDegreesPerMinute` is `undefined`, this value is used
162
+ * (unconverted) as the fallback ROT, driving both the spinning dot ring
163
+ * and the bar extent.
150
164
  * @deprecated Use `rateOfTurnDegreesPerMinute` (and optionally
151
165
  * `rotDotAnimationFactor`) instead. Takes effect only when
152
166
  * `rateOfTurnDegreesPerMinute` is `undefined`.
153
167
  */
154
168
  rotationsPerMinute: number;
169
+ /** ROT display mode: `'dots'` (spinning dots, default) or `'bar'` (a rate-of-turn arc anchored at the current heading, its length proportional to the rate of turn). */
155
170
  rotType: RotType;
171
+ /** ROT track position: `'innerCircle'` (default) or `'scale'` (on the outer ring). */
156
172
  rotPosition: RotPosition;
157
173
  /**
158
174
  * Bar-extent reference value in **degrees per minute**. The bar fills the
@@ -172,6 +188,7 @@ export declare class ObcCompass extends LitElement {
172
188
  rotAtZeroDeadband: number;
173
189
  direction: CompassDirection;
174
190
  state: InstrumentState;
191
+ /** Color priority: `Priority.enhanced` uses the blue/enhanced color palette, `Priority.regular` (default) uses the standard palette. */
175
192
  priority: Priority;
176
193
  /** @availableWhen priority==enhanced */
177
194
  priorityElements: CompassPriorityElement[];
@@ -179,6 +196,14 @@ export declare class ObcCompass extends LitElement {
179
196
  showLabels: boolean;
180
197
  /** When true, labels and north arrow are placed inside the outer ring. */
181
198
  tickmarksInside: boolean;
199
+ /**
200
+ * Outer-ring diameter in CSS pixels. When set, the instrument renders at a
201
+ * fixed intrinsic size derived from the ring, arc shape and label reserve —
202
+ * so instruments sharing the same value have identical ring circumference
203
+ * regardless of label width or arc extent (like obc-donut-chart's
204
+ * fixedHeight). When unset (default), the instrument fills its container.
205
+ */
206
+ faceDiameter: number | undefined;
182
207
  private _headingSp;
183
208
  willUpdate(changed: PropertyValues): void;
184
209
  disconnectedCallback(): void;
@@ -190,7 +215,19 @@ export declare class ObcCompass extends LitElement {
190
215
  * the deprecation window.
191
216
  */
192
217
  private get _effectiveRotDegPerMin();
193
- private getPadding;
218
+ /**
219
+ * Pixel cost of the outside decor: the always-rendered north-arrow glyph
220
+ * plus, only while shown, the NSWE labels (both keep a constant on-screen
221
+ * size via `1/scale` terms). Feeds the frame's width-aware reserve,
222
+ * replacing the former empirical `72 + delta(clientSize)` padding.
223
+ * Wind/current symbols at their default radius are covered by the base
224
+ * padding of 72.
225
+ */
226
+ private getOutsideDecorPx;
227
+ /** Whether the host size styles were set by applyPinnedHostSize. */
228
+ private _hostSizePinned;
229
+ private _frame;
230
+ updated(changed: PropertyValues): void;
194
231
  private get angleAdviceRaw();
195
232
  private priorityFor;
196
233
  private colorFor;
@@ -1 +1 @@
1
- {"version":3,"file":"compass.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass/compass.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compass.d.ts","sourceRoot":"","sources":["../../../src/navigation-instruments/compass/compass.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ import { TickmarkType } from "../watch/tickmark.js";
5
5
  import { arrow, ArrowStyle } from "./arrow.js";
6
6
  import { AdviceState } from "../watch/advice.js";
7
7
  import { ResizeController } from "@lit-labs/observers/resize-controller.js";
8
+ import { NORTH_ARROW_WIDTH_PX, NSWE_LABEL_WIDTH_PX, applyPinnedHostSize, computeRadialFrame, measureContainerPx } from "../../svghelpers/radial-frame.js";
8
9
  import { SetpointBundle } from "../../svghelpers/setpoint-bundle.js";
9
10
  import { RotType, RotPosition, ROT_ZERO_DEADBAND_DEG } from "../rate-of-turn/rot-renderer.js";
10
11
  import { customElement } from "../../decorator.js";
@@ -75,6 +76,7 @@ let ObcCompass = class extends LitElement {
75
76
  onAnimationEnd: () => this.requestUpdate()
76
77
  });
77
78
  this._resizeController = new ResizeController(this, {});
79
+ this._hostSizePinned = false;
78
80
  }
79
81
  willUpdate(changed) {
80
82
  super.willUpdate(changed);
@@ -103,17 +105,27 @@ let ObcCompass = class extends LitElement {
103
105
  get _effectiveRotDegPerMin() {
104
106
  return this.rateOfTurnDegreesPerMinute ?? this.rotationsPerMinute;
105
107
  }
106
- getPadding() {
107
- const size = Math.min(this.clientHeight, this.clientWidth);
108
- const deltaWidth = 512 - size;
109
- const steps = deltaWidth / 128;
110
- let deltaPadding;
111
- if (deltaWidth > 0) {
112
- deltaPadding = steps * 48;
113
- } else {
114
- deltaPadding = steps * 6;
108
+ /**
109
+ * Pixel cost of the outside decor: the always-rendered north-arrow glyph
110
+ * plus, only while shown, the NSWE labels (both keep a constant on-screen
111
+ * size via `1/scale` terms). Feeds the frame's width-aware reserve,
112
+ * replacing the former empirical `72 + delta(clientSize)` padding.
113
+ * Wind/current symbols at their default radius are covered by the base
114
+ * padding of 72.
115
+ */
116
+ getOutsideDecorPx() {
117
+ if (this.tickmarksInside) {
118
+ return 0;
115
119
  }
116
- return 72 + deltaPadding;
120
+ return NORTH_ARROW_WIDTH_PX + (this.showLabels ? NSWE_LABEL_WIDTH_PX : 0);
121
+ }
122
+ updated(changed) {
123
+ super.updated(changed);
124
+ this._hostSizePinned = applyPinnedHostSize(
125
+ this,
126
+ this._frame,
127
+ this._hostSizePinned
128
+ );
117
129
  }
118
130
  get angleAdviceRaw() {
119
131
  return this.headingAdvices.map(({ minAngle, maxAngle, hinted, type }) => {
@@ -145,22 +157,27 @@ let ObcCompass = class extends LitElement {
145
157
  { angle: 180, type: TickmarkType.main },
146
158
  { angle: 270, type: TickmarkType.main }
147
159
  ];
148
- const padding = this.getPadding();
149
- const width = (176 + padding) * 2;
150
- const viewBox = `-${width / 2} -${width / 2} ${width} ${width}`;
160
+ const frame = computeRadialFrame({
161
+ basePadding: 72,
162
+ labelWidthPx: this.getOutsideDecorPx(),
163
+ containerPx: measureContainerPx(this),
164
+ faceDiameter: this.faceDiameter
165
+ });
166
+ this._frame = frame;
167
+ const viewBox = frame.viewBox;
151
168
  return html`
152
169
  <div class="container">
153
170
  <obc-watch
154
171
  .touching=${this.touching}
155
- .padding=${padding}
172
+ .arcFrame=${frame}
156
173
  .advices=${this.angleAdviceRaw}
157
174
  .tickmarks=${tickmarks}
158
175
  .state=${this.state}
159
176
  .watchCircleType=${WatchCircleType.triple}
160
- .showLabels=${this.showLabels}
177
+ .showLabels=${this.showLabels && !frame.labelsHidden}
161
178
  .tickmarksInside=${this.tickmarksInside}
162
179
  .crosshairEnabled=${true}
163
- .northArrow=${true}
180
+ .northArrow=${!frame.labelsHidden}
164
181
  .angleSetpoint=${this.headingSetpoint ?? void 0}
165
182
  .newAngleSetpoint=${this.newHeadingSetpoint}
166
183
  .atAngleSetpoint=${this._headingSp.computeAtSetpoint(this.heading)}
@@ -346,6 +363,9 @@ __decorateClass([
346
363
  __decorateClass([
347
364
  property({ type: Boolean })
348
365
  ], ObcCompass.prototype, "tickmarksInside", 2);
366
+ __decorateClass([
367
+ property({ type: Number, attribute: "face-diameter" })
368
+ ], ObcCompass.prototype, "faceDiameter", 2);
349
369
  ObcCompass = __decorateClass([
350
370
  customElement("obc-compass")
351
371
  ], ObcCompass);