Skip to content

feat: add automation transmitter - #1020

Open
jon-daeh wants to merge 9 commits into
developfrom
feat/add-automation-transmitter
Open

feat: add automation transmitter#1020
jon-daeh wants to merge 9 commits into
developfrom
feat/add-automation-transmitter

Conversation

@jon-daeh

@jon-daeh jon-daeh commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features
    • Introduced new transmitter and transmitter-button web components, supporting multiple sizes/variants and optional value segments (icon, advice, setpoint) plus tag-style rendering.
    • Enhanced transmitter value display with hinted zeros and zero-padding controls, and added optional alert framing.
    • Updated Storybook coverage with additional transmitter/transmitter-button scenarios (including setpoint/advice, tag, and zero-padded variants).
    • Added filled rendering support to indicator graphs for a richer, area-under-the-line visual style.

@jon-daeh
jon-daeh requested review from tibnor and ulrik-jo as code owners June 29, 2026 13:32
@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds obc-transmitter-button and obc-transmitter web components with matching Storybook stories, and extends obc-indicator-graph with optional filled-series rendering plus a new story.

Changes

Transmitter button

Layer / File(s) Summary
Component implementation and styles
packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts, packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.css
Defines button variant/size enums, Lit rendering for value/tag modes, advice and setpoint segments, DOM registration, and CSS for layout, sizing, tag styling, and label treatment.
Storybook stories
packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.stories.ts
Adds Storybook meta, a render helper, and stories covering icon, advice, setpoint, size, tag, and zero-padding variants.

Transmitter

Layer / File(s) Summary
Component implementation and styles
packages/openbridge-webcomponents/src/automation/transmitter/transmitter.ts, packages/openbridge-webcomponents/src/automation/transmitter/transmitter.css
Defines orientation/type enums, renders the transmitter button and optional indicator graph, wraps alert state, and adds CSS for orientation, connector line, graph layout, and id-tag styling.
Storybook stories
packages/openbridge-webcomponents/src/automation/transmitter/transmitter.stories.ts
Adds Storybook meta, default data, a render helper, and stories for value, indicator, graph, alert, zero-padded, and pipe usage states.

Indicator graph fill support

Layer / File(s) Summary
Fill implementation and story
packages/openbridge-webcomponents/src/navigation-instruments/indicator-graph/indicator-graph.ts, packages/openbridge-webcomponents/src/navigation-instruments/indicator-graph/indicator-graph.stories.ts
Adds fill to the layout contract, applies filled-series configuration in the component, and adds a WithFill story.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: Instrument Component

Suggested reviewers: tibnor, ulrik-jo

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately reflects the main change: adding the automation transmitter component and related UI pieces.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/add-automation-transmitter
⚔️ Resolve merge conflicts
  • Resolve merge conflict in branch feat/add-automation-transmitter

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
packages/openbridge-webcomponents/src/automation/transmitter/transmitter.stories.ts (1)

112-120: 📐 Maintainability & Code Quality | 🔵 Trivial

Refresh the graph baselines for these stories.

CI is red on HorizontalGraph and VerticalGraph; if the new visual output is intentional, the matching Storybook snapshots need to be updated in this PR.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/openbridge-webcomponents/src/automation/transmitter/transmitter.stories.ts`
around lines 112 - 120, The HorizontalGraph and VerticalGraph stories in
transmitter.stories.ts have intentional visual changes, so their Storybook
baselines need to be refreshed. Update the matching snapshots for the two Story
exports so CI reflects the new graph rendering, using the HorizontalGraph,
VerticalGraph, and renderComponent/ObcTransmitter story definitions to locate
the affected snapshots.

Source: Pipeline failures

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts`:
- Around line 66-70: The formattedValue getter in transmitter-button currently
passes fractionDigits straight into toFixed(), so invalid public values can
throw during render. Clamp or normalize fractionDigits inside formattedValue
before formatting, ensuring non-integer, negative, or overly large values fall
back to a safe range. Keep the existing undefined/NaN guard and apply the
bounded digit count only when calling toFixed().

In
`@packages/openbridge-webcomponents/src/automation/transmitter/transmitter.stories.ts`:
- Around line 8-10: The transmitter story renderer is exposing hasAdvice in args
but never renders any advice content, so the advice state is not actually
exercised. Update the story’s render/template logic in transmitter.stories.ts
(including the renderer used by the affected stories) to conditionally pass real
content into the advice slot when hasAdvice is enabled, and keep the slot empty
only when it is disabled. Use the existing args handling and the transmitter
component’s advice slot to wire this up consistently across the affected
stories.

In
`@packages/openbridge-webcomponents/src/navigation-instruments/indicator-graph/indicator-graph.ts`:
- Around line 19-23: Remove the inline comment from ObcIndicatorGraphLayout
since the default for fill is already clear from the type and the repo forbids
unnecessary code comments. Update the interface in indicator-graph.ts so fill
remains documented only through type/JSDoc if needed, and keep the definition of
ObcIndicatorGraphLayout clean without the inline note.
- Line 75: The fill callback in indicator-graph’s update path is only set when
_effectiveFill is truthy, so uPlot keeps the previous series.fill when
layout.fill is later disabled. Update the series configuration in the
indicator-graph component’s fill handling logic to explicitly clear series.fill
(set it to undefined/null) in the false branch, alongside the existing
_getFillColor-based assignment, so toggling fill off removes the callback.

---

Nitpick comments:
In
`@packages/openbridge-webcomponents/src/automation/transmitter/transmitter.stories.ts`:
- Around line 112-120: The HorizontalGraph and VerticalGraph stories in
transmitter.stories.ts have intentional visual changes, so their Storybook
baselines need to be refreshed. Update the matching snapshots for the two Story
exports so CI reflects the new graph rendering, using the HorizontalGraph,
VerticalGraph, and renderComponent/ObcTransmitter story definitions to locate
the affected snapshots.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: cea115ea-94f3-406d-aaf0-188b7bac1171

📥 Commits

Reviewing files that changed from the base of the PR and between 1c3262c and 82a5f8e.

⛔ Files ignored due to path filters (14)
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter-button/transmitter-button.stories.ts/default-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter-button/transmitter-button.stories.ts/large-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter-button/transmitter-button.stories.ts/medium-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter-button/transmitter-button.stories.ts/regular-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter-button/transmitter-button.stories.ts/small-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter-button/transmitter-button.stories.ts/tag-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter-button/transmitter-button.stories.ts/with-advice-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter-button/transmitter-button.stories.ts/with-icon-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter/transmitter.stories.ts/horizontal-graph-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter/transmitter.stories.ts/indicator-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter/transmitter.stories.ts/usage-with-pipe-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter/transmitter.stories.ts/value-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter/transmitter.stories.ts/vertical-graph-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/navigation-instruments/indicator-graph/indicator-graph.stories.ts/with-fill-auto.png is excluded by !**/*.png
📒 Files selected for processing (8)
  • packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.css
  • packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.stories.ts
  • packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts
  • packages/openbridge-webcomponents/src/automation/transmitter/transmitter.css
  • packages/openbridge-webcomponents/src/automation/transmitter/transmitter.stories.ts
  • packages/openbridge-webcomponents/src/automation/transmitter/transmitter.ts
  • packages/openbridge-webcomponents/src/navigation-instruments/indicator-graph/indicator-graph.stories.ts
  • packages/openbridge-webcomponents/src/navigation-instruments/indicator-graph/indicator-graph.ts

Comment on lines +66 to +70
private get formattedValue() {
if (this.value === undefined || Number.isNaN(this.value)) {
return '--';
}
return this.value.toFixed(this.fractionDigits);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Clamp fractionDigits before calling toFixed().

fractionDigits is a public property here and is also forwarded unchanged by <obc-transmitter>, so values like -1, 1.5, or 101 will throw a RangeError during render instead of falling back gracefully.

Suggested fix
   private get formattedValue() {
     if (this.value === undefined || Number.isNaN(this.value)) {
       return '--';
     }
-    return this.value.toFixed(this.fractionDigits);
+    const digits =
+      Number.isFinite(this.fractionDigits) &&
+      this.fractionDigits >= 0 &&
+      this.fractionDigits <= 100
+        ? Math.trunc(this.fractionDigits)
+        : 1;
+    return this.value.toFixed(digits);
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private get formattedValue() {
if (this.value === undefined || Number.isNaN(this.value)) {
return '--';
}
return this.value.toFixed(this.fractionDigits);
private get formattedValue() {
if (this.value === undefined || Number.isNaN(this.value)) {
return '--';
}
const digits =
Number.isFinite(this.fractionDigits) &&
this.fractionDigits >= 0 &&
this.fractionDigits <= 100
? Math.trunc(this.fractionDigits)
: 1;
return this.value.toFixed(digits);
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts`
around lines 66 - 70, The formattedValue getter in transmitter-button currently
passes fractionDigits straight into toFixed(), so invalid public values can
throw during render. Clamp or normalize fractionDigits inside formattedValue
before formatting, ensuring non-integer, negative, or overly large values fall
back to a safe range. Keep the existing undefined/NaN guard and apply the
bounded digit count only when calling toFixed().

Comment on lines +8 to +10
import '../../icons/icon-temperature-air.js';
import '../horizontal-line/horizontal-line.js';
import {LineMedium, LineType} from '../index.js';

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Wire the advice slot in the story renderer.

hasAdvice is exposed in args, but this renderer never supplies advice content, so toggling that control documents an empty spacer instead of the actual advice state.

Suggested fix
 import '../../icons/icon-temperature-air.js';
+import '../../icons/icon-placeholder.js';
 import '../horizontal-line/horizontal-line.js';
 import {LineMedium, LineType} from '../index.js';
@@
       ${args.hasIcon
         ? html`<obi-temperature-air slot="icon"></obi-temperature-air>`
         : ''}
+      ${args.hasAdvice
+        ? html`<obi-placeholder slot="advice"></obi-placeholder>`
+        : ''}
     </obc-transmitter>
   `;
 }

Also applies to: 80-100

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/openbridge-webcomponents/src/automation/transmitter/transmitter.stories.ts`
around lines 8 - 10, The transmitter story renderer is exposing hasAdvice in
args but never renders any advice content, so the advice state is not actually
exercised. Update the story’s render/template logic in transmitter.stories.ts
(including the renderer used by the affected stories) to conditionally pass real
content into the advice slot when hasAdvice is enabled, and keep the slot empty
only when it is disabled. Use the existing args handling and the transmitter
component’s advice slot to wire this up consistently across the affected
stories.

{
stroke: this._getStrokeColor(),
width: this._getStrokeWidth(),
fill: this._effectiveFill ? () => this._getFillColor() : undefined,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Clear series.fill when layout.fill turns off.

Line 171 only assigns series.fill in the truthy branch, so after a component has rendered once with fill: true, changing layout.fill to false leaves the previous uPlot fill callback in place and the graph stays filled.

Suggested fix
     const series = this.uplot.series[1];
     series.stroke = () => this._getStrokeColor();
     series.width = this._getStrokeWidth();
-    if (this._effectiveFill) {
-      series.fill = () => this._getFillColor();
-    }
+    series.fill = this._effectiveFill ? () => this._getFillColor() : undefined;
     this.uplot.redraw();

Also applies to: 171-173

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/openbridge-webcomponents/src/navigation-instruments/indicator-graph/indicator-graph.ts`
at line 75, The fill callback in indicator-graph’s update path is only set when
_effectiveFill is truthy, so uPlot keeps the previous series.fill when
layout.fill is later disabled. Update the series configuration in the
indicator-graph component’s fill handling logic to explicitly clear series.fill
(set it to undefined/null) in the false branch, alongside the existing
_getFillColor-based assignment, so toggling fill off removes the callback.

@jon-daeh
jon-daeh marked this pull request as draft June 30, 2026 08:46
@jon-daeh jon-daeh self-assigned this Jul 3, 2026
@jon-daeh
jon-daeh marked this pull request as ready for review July 3, 2026 20:18

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts (1)

198-212: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add a live region to the transmitter readout. The changing value/advice/setpoint is only rendered inside the button, so updates aren’t announced to assistive tech. Add aria-live="polite" and aria-atomic="true" on the root control.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts`
around lines 198 - 212, The transmitter-button root control in render() does not
expose dynamic readout updates to assistive tech. Update the main button element
in transmitter-button to include aria-live="polite" and aria-atomic="true" so
changing value/advice/setpoint content announced by renderContent() is read
correctly. Use the existing render() and renderContent() symbols to place the
live region attributes on the root control.

Sources: Coding guidelines, Learnings

♻️ Duplicate comments (1)
packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts (1)

106-143: 🩺 Stability & Availability | 🟠 Major

Unvalidated fractionDigits can still throw via the shared formatters.

numericFormatOptions forwards the raw fractionDigits public property straight into getHintZeros/formatNumericValue, which ultimately call value.toFixed(options.fractionDigits). Negative, non-integer, or >100 values will throw a RangeError during render. This is the same risk previously flagged on the old formattedValue getter, just relocated behind the new shared-formatter architecture instead of fixed.

🩺 Suggested clamp
   private get numericFormatOptions(): ReadoutNumericFormatOptions {
+    const digits =
+      Number.isFinite(this.fractionDigits) &&
+      this.fractionDigits >= 0 &&
+      this.fractionDigits <= 100
+        ? Math.trunc(this.fractionDigits)
+        : 1;
     return {
       showZeroPadding: this.showZeroPadding,
       minValueLength: this.minValueLength,
-      fractionDigits: this.fractionDigits,
+      fractionDigits: digits,
     };
   }

Note the underlying .toFixed() call itself lives in readout-formatters.ts (not in this diff), so the more durable fix may belong there for all consumers (obc-readout-setpoint has the identical exposure).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts`
around lines 106 - 143, The new render path in transmitter-button.ts still
passes the raw fractionDigits value through numericFormatOptions into
getHintZeros and formatNumericValue, so invalid values can still trigger a
RangeError via the shared formatter pipeline. Clamp or sanitize fractionDigits
before it reaches numericFormatOptions, preferably by normalizing it in the
shared readout-formatters utilities used by formatNumericValue/getHintZeros so
transmitter-button and other consumers like the setpoint component are protected
consistently.
🧹 Nitpick comments (4)
packages/openbridge-webcomponents/src/automation/transmitter/transmitter.ts (3)

170-182: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Alert wrapping hardcodes type and skips established forwarding contract.

hasAlert only toggles a boolean, and the wrapper hardcodes ObcAlertFrameType.Regular without forwarding thickness, status, mode, showIcon, or showAlertCategoryIcon. Per a prior learning, wrapWithAlertFrame() in alert-frame.ts is the established forwarding contract for alert-frame consumers in this repo. Manually re-implementing the wrapper here duplicates logic and limits the component to a single alert type/severity, which may not match future needs (e.g. critical vs. regular alerts).

Consider using the shared wrapWithAlertFrame() helper (or exposing status/mode as properties) for consistency with other automation-family components.

Based on learnings, "Treat packages/openbridge-webcomponents/src/components/alert-frame/alert-frame.ts (wrapWithAlertFrame()) as the source-of-truth forwarding contract for alert-frame consumers."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/openbridge-webcomponents/src/automation/transmitter/transmitter.ts`
around lines 170 - 182, The alert wrapping in transmitter render currently
hardcodes ObcAlertFrameType.Regular and bypasses the shared forwarding contract.
Update transmitter.render() in transmitter.ts to use wrapWithAlertFrame() from
alert-frame.ts, or otherwise forward the existing alert-frame inputs instead of
duplicating the wrapper logic. Make sure the transmitter component preserves and
passes through thickness, status, mode, showIcon, and showAlertCategoryIcon so
the wrapper behavior stays consistent with other consumers.

Source: Learnings


83-95: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use @availableWhen for conditional property docs.

adviceValue, setpointValue, and tag are all conditional on another property/state (hasAdvice, hasSetPoint, type === 'indicator'), but are documented with free-form prose ("when hasAdvice") rather than the @availableWhen JSDoc tag mandated for dependent properties.

📝 Example fix
-  /** Advisory value shown in the leading advice segment when `hasAdvice`. */
+  /**
+   * Advisory value shown in the leading advice segment.
+   * `@availableWhen` hasAdvice
+   */
   `@property`({type: Number}) adviceValue?: number;
@@
   `@property`({type: Boolean}) hasSetPoint = false;

-  /** Target value shown in the setpoint segment when `hasSetPoint`. */
+  /**
+   * Target value shown in the setpoint segment.
+   * `@availableWhen` hasSetPoint
+   */
   `@property`({type: Number}) setpointValue?: number;

-  /** Tag identifier shown when `type` is `indicator` (e.g. `TT`). */
+  /**
+   * Tag identifier (e.g. `TT`).
+   * `@availableWhen` type === 'indicator'
+   */
   `@property`({type: String}) tag = '';

As per coding guidelines, "Document conditional properties with @availableWhen on the dependent property only, using the actual runtime/behavior condition."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/openbridge-webcomponents/src/automation/transmitter/transmitter.ts`
around lines 83 - 95, The conditional property docs in transmitter.ts use
free-form prose instead of the required `@availableWhen` tag. Update the JSDoc for
adviceValue, setpointValue, and tag in Transmitter to document each dependent
property with `@availableWhen` on the property itself, using the actual runtime
condition (hasAdvice, hasSetPoint, and type === 'indicator') and remove the
plain-language “when ...” wording.

Source: Coding guidelines


63-63: 🧹 Nitpick | 🔵 Trivial

Reminder: keep custom-elements.json in sync.

If obc-transmitter is a newly registered @customElement, remember to run npm run analyze so the manifest stays up to date.

As per coding guidelines, "Run npm run analyze after adding or renaming a @customElement so custom-elements.json stays in sync."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/openbridge-webcomponents/src/automation/transmitter/transmitter.ts`
at line 63, The ObcTransmitter custom element registration may have changed, so
keep custom-elements.json in sync by running npm run analyze after adding or
renaming the `@customElement` for obc-transmitter. Update the manifest based on
the ObcTransmitter definition so the generated metadata matches the current
component registration.

Source: Coding guidelines

packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts (1)

91-100: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing @availableWhen tags on conditional properties.

adviceValue, setpointValue, and label are only meaningful when hasAdvice, hasSetPoint, and variant === 'tag' respectively hold, but their inline docs don't use the @availableWhen convention.

📝 Proposed doc fix
-  /** Advisory value shown in the leading advice segment when `hasAdvice`. */
+  /**
+   * Advisory value shown in the leading advice segment.
+   * `@availableWhen` `hasAdvice` is `true`.
+   */
   `@property`({type: Number}) adviceValue?: number;

   `@property`({type: Boolean}) hasSetPoint = false;

-  /** Target value shown in the setpoint segment when `hasSetPoint`. */
+  /**
+   * Target value shown in the setpoint segment.
+   * `@availableWhen` `hasSetPoint` is `true`.
+   */
   `@property`({type: Number}) setpointValue?: number;

-  /** Short tag identifier shown in the `tag` variant (e.g. `TT`). */
+  /**
+   * Short tag identifier shown in the label (e.g. `TT`).
+   * `@availableWhen` `variant` is `'tag'`.
+   */
   `@property`({type: String}) label = '';

As per coding guidelines, "Document conditional properties with @availableWhen on the dependent property only, using the actual runtime/behavior condition."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts`
around lines 91 - 100, Add the missing conditional documentation tags on the
dependent properties in transmitter-button.ts: update the JSDoc for adviceValue,
setpointValue, and label in TransmitterButton so each includes an `@availableWhen`
note that matches the actual runtime condition (hasAdvice, hasSetPoint, and
variant === 'tag' respectively). Keep the tags on the properties themselves and
align the wording with the existing doc style used in this component.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts`:
- Around line 145-178: The advice and setpoint readouts are bypassing the
NaN/undefined normalization used by renderValue(), so renderAdvice() and
renderSetpoint() can show literal NaN instead of the placeholder state. Update
the transmitter-button component to normalize adviceValue and setpointValue the
same way normalizedValue is used, and pass the normalized result into
obc-readout-advice and obc-readout-setpoint so both segments share the same
formatting behavior.

---

Outside diff comments:
In
`@packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts`:
- Around line 198-212: The transmitter-button root control in render() does not
expose dynamic readout updates to assistive tech. Update the main button element
in transmitter-button to include aria-live="polite" and aria-atomic="true" so
changing value/advice/setpoint content announced by renderContent() is read
correctly. Use the existing render() and renderContent() symbols to place the
live region attributes on the root control.

---

Duplicate comments:
In
`@packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts`:
- Around line 106-143: The new render path in transmitter-button.ts still passes
the raw fractionDigits value through numericFormatOptions into getHintZeros and
formatNumericValue, so invalid values can still trigger a RangeError via the
shared formatter pipeline. Clamp or sanitize fractionDigits before it reaches
numericFormatOptions, preferably by normalizing it in the shared
readout-formatters utilities used by formatNumericValue/getHintZeros so
transmitter-button and other consumers like the setpoint component are protected
consistently.

---

Nitpick comments:
In
`@packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts`:
- Around line 91-100: Add the missing conditional documentation tags on the
dependent properties in transmitter-button.ts: update the JSDoc for adviceValue,
setpointValue, and label in TransmitterButton so each includes an `@availableWhen`
note that matches the actual runtime condition (hasAdvice, hasSetPoint, and
variant === 'tag' respectively). Keep the tags on the properties themselves and
align the wording with the existing doc style used in this component.

In `@packages/openbridge-webcomponents/src/automation/transmitter/transmitter.ts`:
- Around line 170-182: The alert wrapping in transmitter render currently
hardcodes ObcAlertFrameType.Regular and bypasses the shared forwarding contract.
Update transmitter.render() in transmitter.ts to use wrapWithAlertFrame() from
alert-frame.ts, or otherwise forward the existing alert-frame inputs instead of
duplicating the wrapper logic. Make sure the transmitter component preserves and
passes through thickness, status, mode, showIcon, and showAlertCategoryIcon so
the wrapper behavior stays consistent with other consumers.
- Around line 83-95: The conditional property docs in transmitter.ts use
free-form prose instead of the required `@availableWhen` tag. Update the JSDoc for
adviceValue, setpointValue, and tag in Transmitter to document each dependent
property with `@availableWhen` on the property itself, using the actual runtime
condition (hasAdvice, hasSetPoint, and type === 'indicator') and remove the
plain-language “when ...” wording.
- Line 63: The ObcTransmitter custom element registration may have changed, so
keep custom-elements.json in sync by running npm run analyze after adding or
renaming the `@customElement` for obc-transmitter. Update the manifest based on
the ObcTransmitter definition so the generated metadata matches the current
component registration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7af4f193-2dec-4548-8168-06672eeea498

📥 Commits

Reviewing files that changed from the base of the PR and between 82a5f8e and fa3ce31.

⛔ Files ignored due to path filters (10)
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter-button/transmitter-button.stories.ts/zero-padded-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/automation/transmitter/transmitter.stories.ts/zero-padded-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/navigation-instruments/indicator-graph/indicator-graph.stories.ts/below-zero-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/navigation-instruments/indicator-graph/indicator-graph.stories.ts/enhanced-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/navigation-instruments/indicator-graph/indicator-graph.stories.ts/large-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/navigation-instruments/indicator-graph/indicator-graph.stories.ts/medium-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/navigation-instruments/indicator-graph/indicator-graph.stories.ts/no-zero-line-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/navigation-instruments/indicator-graph/indicator-graph.stories.ts/primary-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/navigation-instruments/indicator-graph/indicator-graph.stories.ts/small-auto.png is excluded by !**/*.png
  • packages/openbridge-webcomponents/__vis__/linux/__baselines__/navigation-instruments/indicator-graph/indicator-graph.stories.ts/with-range-auto.png is excluded by !**/*.png
📒 Files selected for processing (7)
  • packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.css
  • packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.stories.ts
  • packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts
  • packages/openbridge-webcomponents/src/automation/transmitter/transmitter.css
  • packages/openbridge-webcomponents/src/automation/transmitter/transmitter.stories.ts
  • packages/openbridge-webcomponents/src/automation/transmitter/transmitter.ts
  • packages/openbridge-webcomponents/src/navigation-instruments/indicator-graph/indicator-graph.ts
💤 Files with no reviewable changes (1)
  • packages/openbridge-webcomponents/src/navigation-instruments/indicator-graph/indicator-graph.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/openbridge-webcomponents/src/automation/transmitter/transmitter.css

Comment on lines +145 to +178
private renderAdvice() {
if (!this.hasAdvice) {
return nothing;
}
return html`
<obc-readout-advice
class="advice"
.size=${readoutSizeBySize[this.size]}
.value=${this.adviceValue}
.fractionDigits=${this.fractionDigits}
.minValueLength=${this.minValueLength}
.hasHintedZeros=${this.hasHintedZeros}
></obc-readout-advice>
`;
}

private renderSetpoint() {
if (!this.hasSetPoint) {
return nothing;
}
return html`
<obc-readout-setpoint
class="setpoint"
.variant=${ReadoutSetpointVariant.setpoint}
.mode=${ReadoutSetpointMode.display}
.size=${readoutSizeBySize[this.size]}
.value=${this.setpointValue}
.fractionDigits=${this.fractionDigits}
.minValueLength=${this.minValueLength}
.hasHintedZeros=${this.hasHintedZeros}
>
<obi-input-right slot="icon"></obi-input-right>
</obc-readout-setpoint>
`;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

adviceValue/setpointValue skip the NaN normalization applied to value.

renderValue() uses this.normalizedValue to coerce NaN/undefined to undefined before formatting, but renderAdvice()/renderSetpoint() pass this.adviceValue/this.setpointValue directly. A NaN input here will render the literal text "NaN" instead of the intended dashed placeholder, unlike the main value segment.

♻️ Suggested fix
   private renderAdvice() {
     if (!this.hasAdvice) {
       return nothing;
     }
+    const value =
+      this.adviceValue === undefined || Number.isNaN(this.adviceValue)
+        ? undefined
+        : this.adviceValue;
     return html`
       <obc-readout-advice
         class="advice"
         .size=${readoutSizeBySize[this.size]}
-        .value=${this.adviceValue}
+        .value=${value}
Apply the same treatment to `setpointValue` in `renderSetpoint()`.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/openbridge-webcomponents/src/automation/transmitter-button/transmitter-button.ts`
around lines 145 - 178, The advice and setpoint readouts are bypassing the
NaN/undefined normalization used by renderValue(), so renderAdvice() and
renderSetpoint() can show literal NaN instead of the placeholder state. Update
the transmitter-button component to normalize adviceValue and setpointValue the
same way normalizedValue is used, and pass the normalized result into
obc-readout-advice and obc-readout-setpoint so both segments share the same
formatting behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant