@oicl/openbridge-webcomponents 2.0.0-next.83 → 2.0.0-next.85

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 (26) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +1223 -493
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +642 -196
  4. package/dist/components/tab-item/tab-item.css.js +8 -1
  5. package/dist/components/tab-item/tab-item.css.js.map +1 -1
  6. package/dist/components/tab-item/tab-item.d.ts +44 -0
  7. package/dist/components/tab-item/tab-item.d.ts.map +1 -1
  8. package/dist/components/tab-item/tab-item.js +44 -25
  9. package/dist/components/tab-item/tab-item.js.map +1 -1
  10. package/dist/components/tab-row/tab-row.d.ts +23 -9
  11. package/dist/components/tab-row/tab-row.d.ts.map +1 -1
  12. package/dist/components/tab-row/tab-row.js +24 -7
  13. package/dist/components/tab-row/tab-row.js.map +1 -1
  14. package/dist/components/textbox/textbox.css.js +29 -5
  15. package/dist/components/textbox/textbox.css.js.map +1 -1
  16. package/dist/components/textbox/textbox.d.ts +5 -0
  17. package/dist/components/textbox/textbox.d.ts.map +1 -1
  18. package/dist/components/textbox/textbox.js +6 -1
  19. package/dist/components/textbox/textbox.js.map +1 -1
  20. package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js +611 -230
  21. package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js.map +1 -1
  22. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts +280 -61
  23. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
  24. package/dist/navigation-instruments/readout-list-item/readout-list-item.js +529 -247
  25. package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
  26. package/package.json +1 -1
@@ -61711,12 +61711,6 @@ var ReadoutSetpointMode = /* @__PURE__ */ ((ReadoutSetpointMode2) => {
61711
61711
  ReadoutSetpointMode2["setpointTemporary"] = "setpoint-temporary";
61712
61712
  return ReadoutSetpointMode2;
61713
61713
  })(ReadoutSetpointMode || {});
61714
- var ReadoutSetpointValueTypography = /* @__PURE__ */ ((ReadoutSetpointValueTypography2) => {
61715
- ReadoutSetpointValueTypography2["regular"] = "regular";
61716
- ReadoutSetpointValueTypography2["medium"] = "medium";
61717
- ReadoutSetpointValueTypography2["large"] = "large";
61718
- return ReadoutSetpointValueTypography2;
61719
- })(ReadoutSetpointValueTypography || {});
61720
61714
  let ObcReadoutSetpoint = class extends i$4 {
61721
61715
  constructor() {
61722
61716
  super(...arguments);
@@ -104498,11 +104492,18 @@ const compentStyle$n = i$7`* {
104498
104492
  color: var(--on-flat-disabled-color);
104499
104493
  }
104500
104494
 
104495
+ .wrapper .badges {
104496
+ display: flex;
104497
+ align-items: center;
104498
+ gap: 4px;
104499
+ position: relative;
104500
+ }
104501
+
104501
104502
  .wrapper .badge {
104502
104503
  position: relative;
104503
104504
  }
104504
104505
 
104505
- .wrapper:not(.hug) .badge {
104506
+ .wrapper:not(.hug) .badges {
104506
104507
  right: 0;
104507
104508
  }
104508
104509
 
@@ -104629,6 +104630,7 @@ let ObcTabItem = class extends i$4 {
104629
104630
  this.hasLeadingIcon = false;
104630
104631
  this.hasTitle = false;
104631
104632
  this.hasDivider = false;
104633
+ this.badges = [];
104632
104634
  this.hasBadge = false;
104633
104635
  this.icon = "placeholder";
104634
104636
  this.title = "Tab title";
@@ -104668,7 +104670,40 @@ let ObcTabItem = class extends i$4 {
104668
104670
  this.handleClick(event);
104669
104671
  }
104670
104672
  }
104673
+ get effectiveBadges() {
104674
+ if (this.badges.length > 0) {
104675
+ return this.badges;
104676
+ }
104677
+ if (!this.hasBadge) {
104678
+ return [];
104679
+ }
104680
+ return [
104681
+ {
104682
+ type: this.badgeType || BadgeType.regular,
104683
+ size: this.badgeSize || BadgeSize.regular,
104684
+ count: this.badgeShowNumber ? this.badgeCount : void 0,
104685
+ showIcon: this.showLeadingBadgeIcon,
104686
+ iconSlotName: this.showLeadingBadgeIcon ? "badge-icon" : void 0
104687
+ }
104688
+ ];
104689
+ }
104690
+ renderBadge(badge) {
104691
+ return b`
104692
+ <obc-badge
104693
+ class="badge"
104694
+ .number=${badge.count ?? 0}
104695
+ .type=${badge.type || BadgeType.regular}
104696
+ .size=${badge.size || BadgeSize.regular}
104697
+ .showNumber=${badge.count !== void 0}
104698
+ .showIcon=${badge.showIcon ?? false}
104699
+ >
104700
+ ${badge.iconSlotName ? b`<slot name=${badge.iconSlotName} slot="badge-icon"></slot>` : A}
104701
+ </obc-badge>
104702
+ `;
104703
+ }
104671
104704
  render() {
104705
+ const badges = this.effectiveBadges;
104706
+ const hasBadge = badges.length > 0;
104672
104707
  const wrapperClasses = {
104673
104708
  wrapper: true,
104674
104709
  hug: this.hug,
@@ -104676,7 +104711,7 @@ let ObcTabItem = class extends i$4 {
104676
104711
  "has-leading-icon": this.hasLeadingIcon,
104677
104712
  "has-title": this.hasTitle,
104678
104713
  "has-divider": this.hasDivider && !this.checked,
104679
- "has-badge": this.hasBadge,
104714
+ "has-badge": hasBadge,
104680
104715
  "has-subtitle": this.showSubtitle,
104681
104716
  disabled: this.disabled,
104682
104717
  "center-content": this.centerContent
@@ -104703,31 +104738,13 @@ let ObcTabItem = class extends i$4 {
104703
104738
  ${this.showSubtitle && this.subtitle ? b`<div class="subtitle">${this.subtitle}</div>` : A}
104704
104739
  </div>
104705
104740
  ` : A}
104706
- ${this.centerContent && this.hasBadge ? b`
104707
- <obc-badge
104708
- class="badge"
104709
- .number=${this.badgeCount}
104710
- .type=${this.badgeType || BadgeType.regular}
104711
- .size=${this.badgeSize || BadgeSize.regular}
104712
- .showNumber=${this.badgeShowNumber}
104713
- .showIcon=${this.showLeadingBadgeIcon}
104714
- >
104715
- ${this.showLeadingBadgeIcon ? b`<slot name="badge-icon" slot="badge-icon"></slot>` : A}
104716
- </obc-badge>
104717
- ` : A}
104741
+ ${this.centerContent && hasBadge ? b`<div class="badges">
104742
+ ${badges.map((badge) => this.renderBadge(badge))}
104743
+ </div>` : A}
104718
104744
  </div>
104719
- ${!this.centerContent && this.hasBadge ? b`
104720
- <obc-badge
104721
- class="badge"
104722
- .number=${this.badgeCount}
104723
- .type=${this.badgeType || BadgeType.regular}
104724
- .size=${this.badgeSize || BadgeSize.regular}
104725
- .showNumber=${this.badgeShowNumber}
104726
- .showIcon=${this.showLeadingBadgeIcon}
104727
- >
104728
- ${this.showLeadingBadgeIcon ? b`<slot name="badge-icon" slot="badge-icon"></slot>` : A}
104729
- </obc-badge>
104730
- ` : A}
104745
+ ${!this.centerContent && hasBadge ? b`<div class="badges">
104746
+ ${badges.map((badge) => this.renderBadge(badge))}
104747
+ </div>` : A}
104731
104748
  ${this.hasClose ? b`
104732
104749
  <obc-icon-button
104733
104750
  class="close-button"
@@ -104764,6 +104781,9 @@ __decorateClass$t1([
104764
104781
  __decorateClass$t1([
104765
104782
  n$3({ type: Boolean, attribute: "has-divider" })
104766
104783
  ], ObcTabItem.prototype, "hasDivider", 2);
104784
+ __decorateClass$t1([
104785
+ n$3({ type: Array, attribute: false })
104786
+ ], ObcTabItem.prototype, "badges", 2);
104767
104787
  __decorateClass$t1([
104768
104788
  n$3({ type: Boolean, attribute: "has-badge" })
104769
104789
  ], ObcTabItem.prototype, "hasBadge", 2);
@@ -104849,6 +104869,7 @@ let ObcTabRow = class extends i$4 {
104849
104869
  this.tabs = [];
104850
104870
  this.selectedTabId = "";
104851
104871
  this.hasClose = false;
104872
+ this.centerContent = false;
104852
104873
  this.hug = false;
104853
104874
  this.showSubtitle = false;
104854
104875
  this.hasAddNewTab = false;
@@ -104893,8 +104914,17 @@ let ObcTabRow = class extends i$4 {
104893
104914
  }
104894
104915
  renderTab(tab, index2) {
104895
104916
  const isFirst = index2 === 0;
104917
+ const previousTabSelected = this.selectedTabId === this.tabs[index2 - 1]?.id;
104896
104918
  const isChecked = tab.id === this.selectedTabId;
104897
104919
  const showSubtitle = tab.showSubtitle ?? this.showSubtitle;
104920
+ const badgeIconSlots = [
104921
+ ...new Set(
104922
+ (tab.badges ?? []).map((badge) => badge.iconSlotName).filter((slotName) => slotName !== void 0)
104923
+ )
104924
+ ];
104925
+ if ((tab.showLeadingBadgeIcon ?? false) && !badgeIconSlots.includes("badge-icon")) {
104926
+ badgeIconSlots.push("badge-icon");
104927
+ }
104898
104928
  return b`
104899
104929
  <obc-tab-item
104900
104930
  .title=${tab.title}
@@ -104904,10 +104934,12 @@ let ObcTabRow = class extends i$4 {
104904
104934
  .hasClose=${this.hasClose}
104905
104935
  .hasLeadingIcon=${tab.hasLeadingIcon ?? true}
104906
104936
  .hasTitle=${true}
104907
- .hasDivider=${!isFirst}
104937
+ .hasDivider=${!isFirst && !previousTabSelected}
104908
104938
  .hug=${this.hug}
104939
+ .centerContent=${this.centerContent}
104909
104940
  .disabled=${tab.disabled || false}
104910
- .hasBadge=${tab.hasBadge || tab.badgeCount !== void 0 && tab.badgeCount > 0}
104941
+ .badges=${tab.badges ?? []}
104942
+ .hasBadge=${tab.hasBadge || false}
104911
104943
  .badgeCount=${tab.badgeCount || 0}
104912
104944
  .badgeType=${tab.badgeType ?? BadgeType.regular}
104913
104945
  .badgeSize=${tab.badgeSize ?? BadgeSize.regular}
@@ -104922,11 +104954,13 @@ let ObcTabRow = class extends i$4 {
104922
104954
  </slot>
104923
104955
  ` : ""}
104924
104956
  <span slot="title">${tab.title}</span>
104925
- ${tab.showLeadingBadgeIcon ? b`
104926
- <slot name="tab-${tab.id}-badge-icon" slot="badge-icon">
104927
- <obi-placeholder></obi-placeholder>
104928
- </slot>
104929
- ` : ""}
104957
+ ${badgeIconSlots.map(
104958
+ (slotName) => b`
104959
+ <slot name="tab-${tab.id}-${slotName}" slot=${slotName}>
104960
+ <obi-placeholder></obi-placeholder>
104961
+ </slot>
104962
+ `
104963
+ )}
104930
104964
  </obc-tab-item>
104931
104965
  `;
104932
104966
  }
@@ -104962,6 +104996,9 @@ __decorateClass$t0([
104962
104996
  __decorateClass$t0([
104963
104997
  n$3({ type: Boolean, attribute: "has-close" })
104964
104998
  ], ObcTabRow.prototype, "hasClose", 2);
104999
+ __decorateClass$t0([
105000
+ n$3({ type: Boolean })
105001
+ ], ObcTabRow.prototype, "centerContent", 2);
104965
105002
  __decorateClass$t0([
104966
105003
  n$3({ type: Boolean })
104967
105004
  ], ObcTabRow.prototype, "hug", 2);
@@ -106197,6 +106234,11 @@ const componentStyle$o = i$7`* {
106197
106234
  justify-content: var(--alignment-justify, flex-end);
106198
106235
  height: var(--height);
106199
106236
  overflow: hidden;
106237
+ /* Opt-in: animate a \`size\` change (height + font-size below). Defaults to 0s
106238
+ (instant, current behavior) so existing usages and snapshots are unchanged;
106239
+ a consumer sets \`--obc-textbox-size-transition\` (e.g. 300ms) to animate the
106240
+ swap — used by readout-list-item's setpoint flip-flop. */
106241
+ transition: height var(--obc-textbox-size-transition, 0s) ease;
106200
106242
  }
106201
106243
 
106202
106244
  /* The spacer must share the content's exact font metrics so the width it
@@ -106208,6 +106250,8 @@ const componentStyle$o = i$7`* {
106208
106250
  font-size: calc(var(--height) - 2 * var(--padding));
106209
106251
  font-size-adjust: cap-height 1;
106210
106252
  white-space: nowrap;
106253
+ /* Opt-in size animation — see \`.inner-wrapper\`. */
106254
+ transition: font-size var(--obc-textbox-size-transition, 0s) ease;
106211
106255
  }
106212
106256
 
106213
106257
  .content {
@@ -106215,23 +106259,40 @@ const componentStyle$o = i$7`* {
106215
106259
  text-box-edge: cap alphabetic;
106216
106260
  }
106217
106261
 
106218
- .wrapper.size-xs .inner-wrapper {
106262
+ /* Opt-in numeric mode: fixed-width lining numerals so values stay
106263
+ column-aligned and width-stable. Applied to the spacer too so the reserved
106264
+ width matches the rendered digits exactly. */
106265
+
106266
+ .wrapper.tabular-nums .content,
106267
+ .wrapper.tabular-nums .length-spacer {
106268
+ font-variant-numeric: tabular-nums lining-nums;
106269
+ font-feature-settings:
106270
+ "ss04" on,
106271
+ "tnum" on,
106272
+ "lnum" on;
106273
+ }
106274
+
106275
+ /* Size override is set on \`.wrapper\` (not \`.inner-wrapper\`) so it reaches BOTH
106276
+ the visible \`.content\` AND the sibling \`.length-spacer\`; otherwise the spacer
106277
+ keeps the default (m) \`--height\` and reserves width at the wrong font size. */
106278
+
106279
+ .wrapper.size-xs {
106219
106280
  --height: 16px;
106220
106281
  }
106221
106282
 
106222
- .wrapper.size-s .inner-wrapper {
106283
+ .wrapper.size-s {
106223
106284
  --height: 20px;
106224
106285
  }
106225
106286
 
106226
- .wrapper.size-m .inner-wrapper {
106287
+ .wrapper.size-m {
106227
106288
  --height: 24px;
106228
106289
  }
106229
106290
 
106230
- .wrapper.size-l .inner-wrapper {
106291
+ .wrapper.size-l {
106231
106292
  --height: 32px;
106232
106293
  }
106233
106294
 
106234
- .wrapper.size-xl .inner-wrapper {
106295
+ .wrapper.size-xl {
106235
106296
  --height: 40px;
106236
106297
  }
106237
106298
 
@@ -106280,12 +106341,27 @@ var __decorateClass$sW = (decorators, target, key, kind) => {
106280
106341
  if (kind && result) __defProp$sU(target, key, result);
106281
106342
  return result;
106282
106343
  };
106344
+ var ObcTextboxSize = /* @__PURE__ */ ((ObcTextboxSize2) => {
106345
+ ObcTextboxSize2["xs"] = "xs";
106346
+ ObcTextboxSize2["s"] = "s";
106347
+ ObcTextboxSize2["m"] = "m";
106348
+ ObcTextboxSize2["l"] = "l";
106349
+ ObcTextboxSize2["xl"] = "xl";
106350
+ return ObcTextboxSize2;
106351
+ })(ObcTextboxSize || {});
106352
+ var ObcTextboxFontWeight = /* @__PURE__ */ ((ObcTextboxFontWeight2) => {
106353
+ ObcTextboxFontWeight2["regular"] = "regular";
106354
+ ObcTextboxFontWeight2["semibold"] = "semibold";
106355
+ ObcTextboxFontWeight2["bold"] = "bold";
106356
+ return ObcTextboxFontWeight2;
106357
+ })(ObcTextboxFontWeight || {});
106283
106358
  let ObcTextbox = class extends i$4 {
106284
106359
  constructor() {
106285
106360
  super(...arguments);
106286
106361
  this.alignment = "right";
106287
106362
  this.size = "m";
106288
106363
  this.fontWeight = "regular";
106364
+ this.tabularNums = false;
106289
106365
  }
106290
106366
  render() {
106291
106367
  return b`
@@ -106294,7 +106370,8 @@ let ObcTextbox = class extends i$4 {
106294
106370
  wrapper: true,
106295
106371
  [`alignment-${this.alignment}`]: true,
106296
106372
  [`size-${this.size}`]: true,
106297
- [`font-weight-${this.fontWeight}`]: true
106373
+ [`font-weight-${this.fontWeight}`]: true,
106374
+ "tabular-nums": this.tabularNums
106298
106375
  })}
106299
106376
  >
106300
106377
  <div class="inner-wrapper">
@@ -106319,6 +106396,9 @@ __decorateClass$sW([
106319
106396
  __decorateClass$sW([
106320
106397
  n$3({ type: String })
106321
106398
  ], ObcTextbox.prototype, "fontWeight", 2);
106399
+ __decorateClass$sW([
106400
+ n$3({ type: Boolean })
106401
+ ], ObcTextbox.prototype, "tabularNums", 2);
106322
106402
  ObcTextbox = __decorateClass$sW([
106323
106403
  customElement("obc-textbox")
106324
106404
  ], ObcTextbox);
@@ -222126,264 +222206,645 @@ const componentStyle$4 = i$7`* {
222126
222206
  width: 100%;
222127
222207
  }
222128
222208
 
222209
+ /* ---------- Root / surface ----------
222210
+ * \`.root\` is the touch target (a <button> when clickable, otherwise a <div>).
222211
+ * \`.surface\` is the visible box that carries padding, corner radius, the
222212
+ * data-quality background/border, and — when clickable — the flat interaction
222213
+ * states. */
222214
+
222129
222215
  .root {
222216
+ display: block;
222217
+ inline-size: 100%;
222218
+ margin: 0;
222219
+ /* Neutralise the native <button> chrome (default padding + appearance) when
222220
+ \`.root\` is the clickable touch target, so clickable rows don't inset their
222221
+ \`.surface\` and misalign with non-clickable \`<div>\` rows. */
222222
+ padding: 0;
222223
+ border: none;
222224
+ background: none;
222225
+ appearance: none;
222226
+ font: inherit;
222227
+ color: inherit;
222228
+ text-align: inherit;
222229
+ }
222230
+
222231
+ .root.clickable {
222232
+ cursor: pointer;
222233
+ /* prettier-ignore */
222234
+ }
222235
+
222236
+ .root.clickable {
222237
+ cursor: pointer;
222238
+ }
222239
+
222240
+ .root.clickable:focus {
222241
+ outline: none;
222242
+ }
222243
+
222244
+ .root.clickable .surface {
222245
+ border-color: var(--flat-enabled-border-color);
222246
+ background-color: var(--flat-enabled-background-color);
222247
+ border-width: 1px;
222248
+ border-style: solid;
222249
+ cursor: pointer;
222250
+ --base-border-color: var(--flat-enabled-border-color);
222251
+ --base-background-color: var(--flat-enabled-background-color);
222252
+ }
222253
+
222254
+ .root.clickable.activated .surface {
222255
+ border-color: var(--flat-activated-border-color);
222256
+ background-color: var(--flat-activated-background-color);
222257
+ --base-border-color: var(--flat-activated-border-color);
222258
+ --base-background-color: var(--flat-activated-background-color);
222259
+ }
222260
+
222261
+ @media (hover:hover) {
222262
+
222263
+ .root.clickable:hover .surface {
222264
+ border-color: color-mix(in srgb, var(--flat-hover-border-color) calc(var(--obc-can-hover) * 100%), var(--base-border-color));
222265
+ background-color: color-mix(in srgb, var(--flat-hover-background-color) calc(var(--obc-can-hover) * 100%), var(--base-background-color));
222266
+ }
222267
+ }
222268
+
222269
+ .root.clickable:active .surface {
222270
+ border-color: var(--flat-pressed-border-color);
222271
+ background-color: var(--flat-pressed-background-color);
222272
+ }
222273
+
222274
+ .root.clickable:focus-visible .surface {
222275
+ outline-color: var(--border-focus-color);
222276
+ outline-width: var(--global-size-spacing-border-weight-focusframe);
222277
+ outline-style: solid;
222278
+ border-color: var(--container-global-color);
222279
+ z-index: 1;
222280
+ }
222281
+
222282
+ .root.clickable:disabled .surface {
222283
+ border-color: var(--flat-disabled-border-color);
222284
+ background-color: var(--flat-disabled-background-color);
222285
+ cursor: not-allowed;
222286
+ color: var(--on-flat-disabled-color) !important;
222287
+ }
222288
+
222289
+ .root.clickable.disabled .surface {
222290
+ border-color: var(--flat-disabled-border-color);
222291
+ background-color: var(--flat-disabled-background-color);
222292
+ cursor: not-allowed;
222293
+ color: var(--on-flat-disabled-color) !important;
222294
+ }
222295
+
222296
+ .root.clickable:disabled {
222297
+ cursor: not-allowed;
222298
+ }
222299
+
222300
+ .root.clickable.disabled {
222301
+ cursor: not-allowed;
222302
+ }
222303
+
222304
+ .root.clickable:focus {
222305
+ outline: none;
222306
+ }
222307
+
222308
+ /* Flip-flop: animate the value↔setpoint cap-height swap by forwarding obc-textbox's
222309
+ opt-in size-transition var. 300ms matches the instrument setpoint marker
222310
+ (svghelpers/setpoint.ts). Override via \`--obc-readout-list-item-flip-flop-duration\`. */
222311
+
222312
+ .root.flip-flop {
222313
+ --obc-textbox-size-transition: var(
222314
+ --obc-readout-list-item-flip-flop-duration,
222315
+ 300ms
222316
+ );
222317
+ }
222318
+
222319
+ .surface {
222320
+ display: block;
222321
+ inline-size: 100%;
222322
+ border-radius: var(--global-border-radius-border-radius-base);
222323
+ }
222324
+
222325
+ /* Clickable corner variants. The \`.clickable\` qualifier is redundant for
222326
+ matching (a \`border-*\` class is only ever set alongside \`.clickable\`) but
222327
+ raises specificity to (0,4,0) so the interactive corner shape wins over the
222328
+ data-quality rules below — which also target \`.surface\` at (0,3,0) — when a
222329
+ row is both clickable and low-integrity/invalid. Standalone data-quality rows
222330
+ keep their own radius. */
222331
+
222332
+ .root.clickable.border-squared .surface {
222333
+ border-radius: 0;
222334
+ }
222335
+
222336
+ .root.clickable.border-round-corners .surface {
222337
+ border-radius: var(--global-border-radius-border-radius-floating);
222338
+ }
222339
+
222340
+ .root.clickable.border-round .surface {
222341
+ border-radius: var(--global-border-radius-border-radius-round);
222342
+ }
222343
+
222344
+ /* ---------- Content row ----------
222345
+ * Label on the left, value/unit cluster on the right, optional source after a
222346
+ * trailing divider. All segments bottom-align so cap heights sit on a shared
222347
+ * baseline. */
222348
+
222349
+ .content {
222350
+ display: flex;
222351
+ align-items: flex-end;
222352
+ justify-content: space-between;
222353
+ inline-size: 100%;
222354
+ min-inline-size: 0;
222355
+ }
222356
+
222357
+ /* Reserve the value cap-height per tier so the row height and the bottom
222358
+ baseline stay constant regardless of which parts (label / value / unit / src /
222359
+ setpoint / advice / icons) are present. */
222360
+
222361
+ .size-small .content {
222362
+ min-block-size: var(
222363
+ --global-typography-instrument-value-regular-container-height
222364
+ );
222365
+ }
222366
+
222367
+ .size-medium .content {
222368
+ min-block-size: var(
222369
+ --global-typography-instrument-value-medium-container-height
222370
+ );
222371
+ }
222372
+
222373
+ .size-large .content {
222374
+ min-block-size: var(
222375
+ --global-typography-instrument-value-large-container-height
222376
+ );
222377
+ }
222378
+
222379
+ /* The value is the primary data, so under width pressure the label side yields
222380
+ first: the label-container shrinks (and clips a too-long label) while
222381
+ \`.value-area\` keeps its intrinsic width. */
222382
+
222383
+ .label-container {
222130
222384
  display: inline-flex;
222131
222385
  align-items: flex-end;
222132
- border-radius: var(--global-border-radius-border-radius-base);
222133
- width: 100%;
222386
+ gap: var(--global-size-spacing-target-padding);
222387
+ flex: 1 1 auto;
222388
+ min-inline-size: 0;
222389
+ overflow: hidden;
222134
222390
  }
222135
222391
 
222136
- .root .content {
222137
- display: inline-flex;
222138
- align-items: flex-end;
222139
- justify-content: space-between;
222140
- flex: 1 1 auto;
222141
- min-width: 0;
222142
- max-width: none;
222143
- width: 100%;
222144
- }
222392
+ .label-stack {
222393
+ display: inline-flex;
222394
+ flex-direction: column;
222395
+ align-items: flex-start;
222396
+ justify-content: flex-end;
222397
+ min-inline-size: 0;
222398
+ }
222145
222399
 
222146
- .root .label-container {
222147
- display: inline-flex;
222148
- align-items: flex-end;
222149
- gap: var(--global-size-spacing-target-padding);
222150
- flex: none;
222151
- }
222400
+ .value-area {
222401
+ display: inline-flex;
222402
+ align-items: flex-end;
222403
+ justify-content: flex-end;
222404
+ flex: 0 0 auto;
222405
+ min-inline-size: 0;
222406
+ }
222152
222407
 
222153
- .root .leading-icon {
222154
- display: inline-flex;
222155
- align-items: center;
222156
- justify-content: center;
222157
- color: var(--element-neutral-color);
222158
- }
222408
+ .value-cluster {
222409
+ display: inline-flex;
222410
+ align-items: flex-end;
222411
+ justify-content: flex-end;
222412
+ }
222159
222413
 
222160
- .root .label-stack {
222161
- display: inline-flex;
222162
- flex-direction: column;
222163
- align-items: flex-start;
222164
- justify-content: flex-end;
222165
- }
222414
+ .unit-area {
222415
+ display: inline-flex;
222416
+ align-items: flex-end;
222417
+ }
222166
222418
 
222167
- .root .label-inline {
222168
- display: inline-flex;
222169
- align-items: center;
222170
- gap: var(--global-size-spacing-target-padding);
222171
- }
222419
+ /* ---------- Readout building block (advice / setpoint / value) ---------- */
222172
222420
 
222173
- .root .label {
222174
- font-family: var(--global-typography-font-family);
222175
- font-size: var(--global-typography-instrument-label-font-size);
222176
- line-height: var(--global-typography-instrument-label-line-height);
222177
- font-feature-settings:
222178
- "liga" off,
222179
- "clig" off,
222180
- "ss04" on;
222181
- display: flex;
222182
- align-items: flex-end;
222183
- block-size: var(--global-typography-instrument-label-container-height);
222184
- max-block-size: var(--global-typography-instrument-label-container-height);
222185
- padding-bottom: var(--global-typography-instrument-label-padding-bottom);
222186
- overflow: hidden;
222187
- font-size: var(--global-typography-instrument-label-font-size);
222188
- line-height: var(--global-typography-instrument-label-line-height);
222189
- color: var(--element-inactive-color);
222190
- }
222421
+ .block {
222422
+ display: inline-flex;
222423
+ align-items: flex-end;
222424
+ }
222191
222425
 
222192
- .root .unit,.root .source {
222193
- font-family: var(--global-typography-font-family);
222194
- font-size: var(--global-typography-instrument-unit-font-size);
222195
- line-height: var(--global-typography-instrument-unit-line-height);
222196
- font-feature-settings:
222197
- "liga" off,
222198
- "clig" off,
222199
- "ss04" on;
222200
- display: flex;
222201
- align-items: flex-end;
222202
- block-size: var(--global-typography-instrument-unit-container-height);
222203
- max-block-size: var(--global-typography-instrument-unit-container-height);
222204
- padding-bottom: var(--global-typography-instrument-unit-padding-bottom);
222205
- overflow: hidden;
222206
- font-size: var(--global-typography-instrument-unit-font-size);
222207
- line-height: var(--global-typography-instrument-unit-line-height);
222208
- }
222426
+ /* Number + its (setpoint/advice) degree glyph, hugging with no gap — the
222427
+ \`.block\` gap only separates the icon from this group. */
222209
222428
 
222210
- .root .unit {
222211
- color: var(--element-inactive-color);
222212
- }
222429
+ .block-content {
222430
+ display: inline-flex;
222431
+ align-items: flex-end;
222432
+ }
222213
222433
 
222214
- .root .source {
222215
- color: var(--element-neutral-color);
222216
- }
222434
+ .block-icon {
222435
+ display: inline-flex;
222436
+ align-items: center;
222437
+ justify-content: center;
222438
+ flex: none;
222439
+ color: inherit;
222440
+ /* Centre the icon against the block's text rather than bottom-aligning it (the
222441
+ block is flex-end). Matters for the value block, whose text is taller than
222442
+ the icon, so the value icon lines up with the number like the smaller
222443
+ setpoint/advice icons do. */
222444
+ align-self: center;
222445
+ }
222217
222446
 
222218
- .root .value-container {
222219
- display: inline-flex;
222220
- align-items: flex-end;
222221
- justify-content: flex-end;
222222
- flex: 1 1 auto;
222223
- min-width: 0;
222224
- }
222447
+ .block-icon obi-input-right,
222448
+ .block-icon obi-notification-advice,
222449
+ .block-icon ::slotted(*) {
222450
+ display: block;
222451
+ inline-size: 100%;
222452
+ block-size: 100%;
222453
+ }
222225
222454
 
222226
- .root .value-wrap {
222227
- display: inline-flex;
222228
- align-items: flex-end;
222229
- justify-content: flex-end;
222230
- }
222455
+ .hinted-zero {
222456
+ color: var(
222457
+ --obc-readout-list-item-hinted-color,
222458
+ var(--element-inactive-color)
222459
+ );
222460
+ }
222231
222461
 
222232
- .root .value-cluster {
222233
- display: inline-flex;
222234
- align-items: flex-end;
222235
- justify-content: flex-end;
222236
- gap: var(
222237
- --instrument-components-readout-new-list-item-medium-value-container-gap
222238
- );
222239
- }
222462
+ /* ---------- Text colours (overridable via custom properties) ----------
222463
+ * obc-textbox does not set its own colour, so it inherits these. */
222240
222464
 
222241
- .root .value-icon {
222242
- display: inline-flex;
222243
- align-items: center;
222244
- justify-content: center;
222245
- color: inherit;
222246
- }
222465
+ .block-value {
222466
+ color: var(--obc-readout-list-item-value-color, var(--element-neutral-color));
222467
+ }
222247
222468
 
222248
- .root .divider {
222249
- flex: none;
222250
- inline-size: 1px;
222251
- background-color: var(--border-outline-color);
222252
- align-self: stretch;
222253
- }
222469
+ .block-value.tone-enhanced {
222470
+ color: var(
222471
+ --obc-readout-list-item-value-enhanced-color,
222472
+ var(--element-neutral-enhanced-color)
222473
+ );
222474
+ }
222254
222475
 
222255
- .root .unit-trailing {
222256
- display: inline-flex;
222257
- align-items: flex-end;
222258
- }
222476
+ /* The setpoint shares the value's colour state: neutral by default, enhanced
222477
+ (blue) only when the row is enhanced — never a blue setpoint next to a grey
222478
+ value. \`--instrument-enhanced-secondary-color\` is the same #2d548b as the
222479
+ value's \`--element-neutral-enhanced-color\`. */
222259
222480
 
222260
- .root .source-trailing {
222261
- display: inline-flex;
222262
- align-items: center;
222263
- justify-content: flex-end;
222264
- padding-inline: calc(var(--global-size-spacing-target-padding) / 2);
222265
- }
222481
+ .block-setpoint {
222482
+ color: var(
222483
+ --obc-readout-list-item-setpoint-color,
222484
+ var(--element-neutral-color)
222485
+ );
222486
+ /* Flip-flop emphasis + pop-up fade animate at 100ms. */
222487
+ transition:
222488
+ opacity 100ms ease,
222489
+ color 100ms ease;
222490
+ }
222266
222491
 
222267
- .root.size-base {
222268
- padding-inline: var(
222269
- --instrument-components-readout-new-list-item-regular-container-padding-horizontal
222270
- );
222271
- padding-block: 0;
222272
- }
222492
+ .block-setpoint.tone-enhanced {
222493
+ color: var(
222494
+ --obc-readout-list-item-setpoint-enhanced-color,
222495
+ var(--instrument-enhanced-secondary-color)
222496
+ );
222497
+ }
222273
222498
 
222274
- .root.size-base .content {
222275
- gap: var(
222276
- --instrument-components-readout-new-list-item-regular-content-container-gap
222277
- );
222278
- }
222499
+ /* Pop-up: fade the setpoint out once value === setpoint, keeping its space so
222500
+ the value stays column-aligned. */
222279
222501
 
222280
- .root.size-base .value-cluster {
222281
- gap: var(
222282
- --instrument-components-readout-new-list-item-regular-value-container-gap
222283
- );
222284
- }
222502
+ .block-setpoint.is-hiding {
222503
+ opacity: 0;
222504
+ }
222285
222505
 
222286
- .root.size-base.stacking-leading-src .content {
222287
- gap: var(--global-size-spacing-target-padding);
222288
- }
222506
+ .block-setpoint.is-hidden {
222507
+ opacity: 0;
222508
+ visibility: hidden;
222509
+ }
222289
222510
 
222290
- .root.size-base .divider {
222291
- block-size: var(
222292
- --global-typography-instrument-value-regular-container-height
222293
- );
222294
- }
222511
+ /* Touching / focus state: the setpoint triangle takes the marker's focus look — a
222512
+ pale fill (--base-blue-100) with a dark 1px edge (--element-neutral-enhanced),
222513
+ mirroring \`svghelpers/setpoint.ts\` focus (fill base-blue-100 + 2px stroke).
222514
+ The glyph icon is \`fill: currentColor\` and can't take a CSS \`stroke\`, so the
222515
+ edge is layered drop-shadows. The setpoint number keeps its normal, readable
222516
+ colour. */
222295
222517
 
222296
- .root.size-priority {
222297
- padding-inline: var(
222298
- --instrument-components-readout-new-list-item-medium-container-padding-horizontal
222299
- );
222300
- padding-block: var(
222301
- --instrument-components-readout-new-list-item-medium-container-padding-vertical
222302
- );
222303
- }
222518
+ .block-setpoint.touching {
222519
+ --_touching-outline: var(
222520
+ --obc-readout-list-item-setpoint-touching-outline-color,
222521
+ var(--element-neutral-enhanced-color)
222522
+ );
222523
+ }
222304
222524
 
222305
- .root.size-priority .content {
222306
- gap: var(
222307
- --instrument-components-readout-new-list-item-medium-content-container-gap
222308
- );
222309
- }
222525
+ .block-setpoint.touching .block-icon {
222526
+ color: var(
222527
+ --obc-readout-list-item-setpoint-touching-color,
222528
+ var(--base-blue-100)
222529
+ );
222530
+ filter: drop-shadow(1px 0 0 var(--_touching-outline))
222531
+ drop-shadow(-1px 0 0 var(--_touching-outline))
222532
+ drop-shadow(0 1px 0 var(--_touching-outline))
222533
+ drop-shadow(0 -1px 0 var(--_touching-outline));
222534
+ }
222310
222535
 
222311
- .root.size-priority .divider {
222312
- block-size: var(
222313
- --global-typography-instrument-value-medium-container-height
222314
- );
222315
- }
222536
+ .block-advice {
222537
+ color: var(
222538
+ --obc-readout-list-item-advice-color,
222539
+ var(--element-neutral-color)
222540
+ );
222541
+ }
222316
222542
 
222317
- .root.size-enhanced {
222318
- padding-inline: var(
222319
- --instrument-components-readout-new-list-item-large-container-padding-horizontal
222320
- );
222321
- padding-block: var(
222322
- --instrument-components-readout-new-list-item-large-container-padding-vertical
222323
- );
222324
- }
222543
+ .label {
222544
+ color: var(
222545
+ --obc-readout-list-item-label-color,
222546
+ var(--element-inactive-color)
222547
+ );
222548
+ }
222325
222549
 
222326
- .root.size-enhanced .content {
222327
- gap: var(--instrument-components-readout-new-list-item-large-content-gap);
222328
- }
222550
+ .unit {
222551
+ color: var(--obc-readout-list-item-unit-color, var(--element-inactive-color));
222552
+ }
222329
222553
 
222330
- .root.size-enhanced .value-cluster {
222331
- gap: var(--instrument-components-readout-new-list-item-large-value-gap);
222332
- }
222554
+ .source {
222555
+ color: var(
222556
+ --obc-readout-list-item-source-color,
222557
+ var(--element-neutral-color)
222558
+ );
222559
+ }
222333
222560
 
222334
- .root.size-enhanced .divider {
222335
- block-size: var(
222336
- --global-typography-instrument-value-large-container-height
222337
- );
222338
- }
222561
+ /* ---------- Per-block data quality ----------
222562
+ * Independent of (and nests inside) the row-level data-quality frame. Uses
222563
+ * \`outline\` (not \`border\`) so the chip never shifts the block's width — the
222564
+ * value stays column-aligned across rows. */
222339
222565
 
222340
- .root.size-enhanced.stacking-leading-unit .label-container {
222341
- align-items: center;
222342
- }
222566
+ .block.data-low-integrity,
222567
+ .block.data-invalid,
222568
+ .source.data-low-integrity,
222569
+ .source.data-invalid {
222570
+ outline: 1px solid;
222571
+ border-radius: var(--global-border-radius-border-radius-check);
222572
+ }
222343
222573
 
222344
- .root.size-enhanced.stacking-leading-unit .label-stack {
222345
- justify-content: flex-end;
222346
- }
222574
+ .block.data-low-integrity,
222575
+ .source.data-low-integrity {
222576
+ background: var(--alert-low-integrity-background-color);
222577
+ outline-color: var(--alert-low-integrity-border-color);
222578
+ }
222347
222579
 
222348
- .root.size-enhanced.stacking-leading-unit .unit-leading {
222349
- margin-top: 0;
222350
- }
222580
+ .block.data-invalid,
222581
+ .source.data-invalid {
222582
+ background: var(--alert-invalid-background-color);
222583
+ outline-color: var(--alert-invalid-border-color);
222584
+ }
222351
222585
 
222352
- .root.stacking-leading-unit .unit-trailing {
222353
- display: none;
222354
- }
222586
+ .leading-icon {
222587
+ display: inline-flex;
222588
+ align-items: center;
222589
+ justify-content: center;
222590
+ flex: none;
222591
+ color: var(--element-neutral-color);
222592
+ }
222355
222593
 
222356
- .root.stacking-leading-src .source-inline {
222357
- display: inline-flex;
222358
- align-items: center;
222359
- justify-content: flex-end;
222360
- }
222594
+ .leading-icon ::slotted(*) {
222595
+ display: block;
222596
+ inline-size: 100%;
222597
+ block-size: 100%;
222598
+ }
222361
222599
 
222362
- .root.stacking-leading-src :is(.divider,.source-trailing) {
222363
- display: none;
222364
- }
222600
+ .divider {
222601
+ flex: none;
222602
+ inline-size: 1px;
222603
+ background-color: var(--border-outline-color);
222604
+ align-self: stretch;
222605
+ }
222365
222606
 
222366
- .root:is(.data-low-integrity,.data-invalid) {
222367
- background: var(--_obc-readout-list-item-data-background);
222368
- border: 1px solid var(--_obc-readout-list-item-data-border);
222369
- border-radius: 4px;
222370
- }
222607
+ /* ---------- Value↔unit gap & degree column ----------
222608
+ * Default 2px between the value digits and the unit. A degree (or a
222609
+ * hasDegreeSpacer reserve) replaces the 2px with a cap-height degree column
222610
+ * whose width scales with the value size, so value digits + units align across
222611
+ * degree / no-degree rows of the same value size. */
222612
+
222613
+ .value-unit-gap {
222614
+ flex: none;
222615
+ inline-size: var(
222616
+ --instrument-components-readout-new-general-horizontal-trim-padding
222617
+ );
222618
+ }
222619
+
222620
+ .degree-column {
222621
+ flex: none;
222622
+ display: inline-flex;
222623
+ align-items: flex-end;
222624
+ justify-content: center;
222625
+ inline-size: var(--_obc-readout-list-item-degree-width, 0);
222626
+ overflow: clip;
222627
+ color: var(--obc-readout-list-item-value-color, var(--element-neutral-color));
222628
+ }
222629
+
222630
+ .degree-column.tone-enhanced {
222631
+ color: var(
222632
+ --obc-readout-list-item-value-enhanced-color,
222633
+ var(--element-neutral-enhanced-color)
222634
+ );
222635
+ }
222636
+
222637
+ /* Setpoint/advice degree glyphs inherit their block's colour. */
222638
+
222639
+ .degree-column.degree-inherit {
222640
+ color: inherit;
222641
+ }
222642
+
222643
+ .degree-column.degree-xs {
222644
+ --_obc-readout-list-item-degree-width: var(
222645
+ --global-typography-instrument-value-small-degree-unit-width
222646
+ );
222647
+ }
222648
+
222649
+ .degree-column.degree-s {
222650
+ --_obc-readout-list-item-degree-width: var(
222651
+ --global-typography-instrument-value-regular-degree-unit-width
222652
+ );
222653
+ }
222654
+
222655
+ .degree-column.degree-m {
222656
+ --_obc-readout-list-item-degree-width: var(
222657
+ --global-typography-instrument-value-medium-degree-unit-width
222658
+ );
222659
+ }
222660
+
222661
+ .degree-column.degree-l,
222662
+ .degree-column.degree-xl {
222663
+ --_obc-readout-list-item-degree-width: var(
222664
+ --global-typography-instrument-value-large-degree-unit-width
222665
+ );
222666
+ }
222667
+
222668
+ /* Degree spacer: rendered AFTER the unit on a non-degree row that sets
222669
+ hasDegreeSpacer. Its width (degree-compensation-padding = degree-column width
222670
+ minus the 2px value↔unit gap) shifts the unit left so the row's value digits
222671
+ stay aligned with degree rows in the same column. */
222672
+
222673
+ .degree-spacer {
222674
+ flex: none;
222675
+ align-self: stretch;
222676
+ inline-size: var(--_obc-readout-list-item-degree-spacer-width, 0);
222677
+ }
222678
+
222679
+ .size-small .degree-spacer {
222680
+ --_obc-readout-list-item-degree-spacer-width: var(
222681
+ --instrument-components-readout-new-list-item-regular-degree-compensation-padding
222682
+ );
222683
+ }
222684
+
222685
+ .size-medium .degree-spacer {
222686
+ --_obc-readout-list-item-degree-spacer-width: var(
222687
+ --instrument-components-readout-new-list-item-medium-degree-compensation-padding
222688
+ );
222689
+ }
222690
+
222691
+ .size-large .degree-spacer {
222692
+ --_obc-readout-list-item-degree-spacer-width: var(
222693
+ --instrument-components-readout-new-list-item-large-degree-compensation-padding
222694
+ );
222695
+ }
222696
+
222697
+ /* ---------- Size tiers ----------
222698
+ * Public small/medium/large map to the design token regular/medium/large
222699
+ * tiers. */
222700
+
222701
+ .size-small .surface {
222702
+ padding-inline: var(
222703
+ --instrument-components-readout-new-list-item-regular-container-padding-horizontal
222704
+ );
222705
+ padding-block: var(
222706
+ --instrument-components-readout-new-list-item-regular-container-padding-vertical
222707
+ );
222708
+ }
222709
+
222710
+ .size-small .content {
222711
+ gap: var(
222712
+ --instrument-components-readout-new-list-item-regular-content-container-gap
222713
+ );
222714
+ }
222715
+
222716
+ .size-small .value-cluster {
222717
+ gap: var(
222718
+ --instrument-components-readout-new-list-item-regular-value-container-gap
222719
+ );
222720
+ }
222721
+
222722
+ .size-small .block {
222723
+ gap: var(--instrument-components-readout-new-general-regular-icon-gap);
222724
+ }
222725
+
222726
+ .size-small .block-icon,
222727
+ .size-small .leading-icon {
222728
+ inline-size: var(
222729
+ --instrument-components-readout-new-general-regular-icon-size
222730
+ );
222731
+ block-size: var(
222732
+ --instrument-components-readout-new-general-regular-icon-size
222733
+ );
222734
+ }
222735
+
222736
+ .size-small .divider {
222737
+ block-size: var(
222738
+ --global-typography-instrument-value-regular-container-height
222739
+ );
222740
+ }
222741
+
222742
+ .size-medium .surface {
222743
+ padding-inline: var(
222744
+ --instrument-components-readout-new-list-item-medium-container-padding-horizontal
222745
+ );
222746
+ padding-block: var(
222747
+ --instrument-components-readout-new-list-item-medium-container-padding-vertical
222748
+ );
222749
+ }
222750
+
222751
+ .size-medium .content {
222752
+ gap: var(
222753
+ --instrument-components-readout-new-list-item-medium-content-container-gap
222754
+ );
222755
+ }
222756
+
222757
+ .size-medium .value-cluster {
222758
+ gap: var(
222759
+ --instrument-components-readout-new-list-item-medium-value-container-gap
222760
+ );
222761
+ }
222762
+
222763
+ .size-medium .block {
222764
+ gap: var(--instrument-components-readout-new-general-medium-icon-gap);
222765
+ }
222766
+
222767
+ .size-medium .block-icon,
222768
+ .size-medium .leading-icon {
222769
+ inline-size: var(
222770
+ --instrument-components-readout-new-general-medium-icon-size
222771
+ );
222772
+ block-size: var(--instrument-components-readout-new-general-medium-icon-size);
222773
+ }
222774
+
222775
+ .size-medium .divider {
222776
+ block-size: var(--global-typography-instrument-value-medium-container-height);
222777
+ }
222778
+
222779
+ .size-large .surface {
222780
+ padding-inline: var(
222781
+ --instrument-components-readout-new-list-item-large-container-padding-horizontal
222782
+ );
222783
+ padding-block: var(
222784
+ --instrument-components-readout-new-list-item-large-container-padding-vertical
222785
+ );
222786
+ min-block-size: var(
222787
+ --instrument-components-readout-new-list-item-large-min-height
222788
+ );
222789
+ }
222790
+
222791
+ .size-large .content {
222792
+ gap: var(--instrument-components-readout-new-list-item-large-content-gap);
222793
+ }
222794
+
222795
+ .size-large .value-cluster {
222796
+ gap: var(--instrument-components-readout-new-list-item-large-value-gap);
222797
+ }
222798
+
222799
+ .size-large .block {
222800
+ gap: var(--instrument-components-readout-new-general-large-icon-gap);
222801
+ }
222802
+
222803
+ .size-large .block-icon,
222804
+ .size-large .leading-icon {
222805
+ inline-size: var(--instrument-components-readout-new-general-large-icon-size);
222806
+ block-size: var(--instrument-components-readout-new-general-large-icon-size);
222807
+ }
222808
+
222809
+ .size-large .divider {
222810
+ block-size: var(--global-typography-instrument-value-large-container-height);
222811
+ }
222812
+
222813
+ /* ---------- Stacking ----------
222814
+ * leading-unit / leading-src move the unit / source up beside the label and
222815
+ * suppress the trailing variant. (Handled in markup; these rules tighten the
222816
+ * label-stack gap.) */
222817
+
222818
+ .stacking-leading-src .content {
222819
+ gap: var(--global-size-spacing-target-padding);
222820
+ }
222821
+
222822
+ /* ---------- Data quality ----------
222823
+ * Orthogonal to the alert frame — both can apply at once. */
222824
+
222825
+ .root.data-low-integrity .surface,
222826
+ .root.data-invalid .surface {
222827
+ /* \`outline\` (not \`border\`) so the data-quality frame does not inset the
222828
+ content by 1px — keeps the row's value column-aligned with unframed rows.
222829
+ Matches the per-block data-quality rules. */
222830
+ outline: 1px solid var(--_obc-readout-list-item-data-border);
222831
+ background: var(--_obc-readout-list-item-data-background);
222832
+ border-radius: var(--global-border-radius-border-radius-check);
222833
+ }
222371
222834
 
222372
222835
  .root.data-low-integrity {
222373
- --_obc-readout-list-item-data-background: var(
222374
- --alert-low-integrity-background-color
222375
- );
222376
- --_obc-readout-list-item-data-border: var(
222377
- --alert-low-integrity-border-color
222378
- );
222379
- }
222836
+ --_obc-readout-list-item-data-background: var(
222837
+ --alert-low-integrity-background-color
222838
+ );
222839
+ --_obc-readout-list-item-data-border: var(--alert-low-integrity-border-color);
222840
+ }
222380
222841
 
222381
222842
  .root.data-invalid {
222382
- --_obc-readout-list-item-data-background: var(
222383
- --alert-invalid-background-color
222384
- );
222385
- --_obc-readout-list-item-data-border: var(--alert-invalid-border-color);
222386
- }
222843
+ --_obc-readout-list-item-data-background: var(
222844
+ --alert-invalid-background-color
222845
+ );
222846
+ --_obc-readout-list-item-data-border: var(--alert-invalid-border-color);
222847
+ }
222387
222848
  `;
222388
222849
  var __defProp$f = Object.defineProperty;
222389
222850
  var __getOwnPropDesc$f = Object.getOwnPropertyDescriptor;
@@ -222398,278 +222859,517 @@ var __decorateClass$f = (decorators, target, key, kind) => {
222398
222859
  let ObcReadoutListItem = class extends i$4 {
222399
222860
  constructor() {
222400
222861
  super(...arguments);
222401
- this.size = "base";
222402
- this.stacking = "trailing-unit";
222403
- this.priority = "regular";
222404
- this.dataState = "none";
222405
- this.alert = false;
222406
- this.label = "";
222407
- this.unit = "";
222408
- this.src = "";
222409
- this.value = void 0;
222410
- this.setpointValue = void 0;
222862
+ this.hasValue = true;
222863
+ this.value = null;
222864
+ this.off = false;
222411
222865
  this.hasSetpoint = false;
222412
- this.hasDegree = false;
222413
- this.hasUnit = false;
222414
- this.hasLabel = false;
222415
- this.hasSource = false;
222866
+ this.hasAdvice = false;
222867
+ this.clickable = false;
222416
222868
  this.hasLeadingIcon = false;
222417
- this.hasValueIcon = false;
222869
+ this.hasDegree = false;
222870
+ this.hasDegreeSpacer = false;
222418
222871
  this.fractionDigits = 0;
222419
- this.showZeroPadding = false;
222420
- this.minValueLength = 0;
222421
- this.hasHintedZeros = false;
222422
- this.labelOnly = false;
222872
+ this.maxDigits = 0;
222873
+ this.alert = false;
222874
+ this.deferredSetpointHidePhase = "none";
222875
+ this.hasCompletedFirstUpdate = false;
222423
222876
  }
222424
- get resolvedMainValueSize() {
222425
- return this.size === "enhanced" ? ReadoutSetpointSize.large : this.size === "priority" ? ReadoutSetpointSize.medium : ReadoutSetpointSize.regular;
222877
+ get resolvedSize() {
222878
+ return this.size ?? "small";
222426
222879
  }
222427
- get resolvedValueSize() {
222428
- if (this.priority === "setpoint-flip-flop") {
222429
- if (this.size === "priority") {
222430
- return ReadoutSetpointSize.small;
222431
- }
222432
- if (this.size === "enhanced") {
222433
- return ReadoutSetpointSize.regular;
222434
- }
222435
- }
222436
- if (this.size === "enhanced") {
222437
- return ReadoutSetpointSize.large;
222438
- }
222439
- return ReadoutSetpointSize.regular;
222880
+ get resolvedStacking() {
222881
+ return this.stacking ?? "trailing-unit";
222440
222882
  }
222441
- get resolvedValueTypography() {
222442
- if (this.priority === "setpoint-flip-flop" && this.resolvedValueSize === ReadoutSetpointSize.small) {
222443
- return void 0;
222883
+ get resolvedPriority() {
222884
+ return this.priority ?? "regular";
222885
+ }
222886
+ get resolvedFractionDigits() {
222887
+ return this.fractionDigits ?? 0;
222888
+ }
222889
+ get resolvedMaxDigits() {
222890
+ return this.maxDigits ?? 0;
222891
+ }
222892
+ get resolvedClickable() {
222893
+ const clickable = this.clickable;
222894
+ if (!clickable) {
222895
+ return false;
222444
222896
  }
222445
- if (this.priority === "setpoint-flip-flop" && this.size === "enhanced") {
222446
- return ReadoutSetpointValueTypography.regular;
222897
+ if (clickable === true) {
222898
+ return {
222899
+ border: "squared"
222900
+ /* squared */
222901
+ };
222447
222902
  }
222448
- switch (this.size) {
222449
- case "enhanced":
222450
- return ReadoutSetpointValueTypography.large;
222451
- case "priority":
222452
- return ReadoutSetpointValueTypography.medium;
222453
- case "base":
222454
- default:
222455
- return ReadoutSetpointValueTypography.regular;
222903
+ return {
222904
+ border: clickable.border ?? "squared"
222905
+ /* squared */
222906
+ };
222907
+ }
222908
+ get isAtSetpoint() {
222909
+ if (!this.hasSetpoint || this.value === null || this.setpoint === void 0) {
222910
+ return false;
222456
222911
  }
222912
+ const formatOptions = this.numericFormatOptions(this.resolvedMaxDigits);
222913
+ return formatNumericValue(this.value, formatOptions) === formatNumericValue(this.setpoint, formatOptions);
222457
222914
  }
222458
- get resolvedSetpointSize() {
222915
+ get resolvedSetpointInteraction() {
222916
+ return this.setpointOptions?.interaction ?? "always-visible";
222917
+ }
222918
+ get isFlipFlop() {
222919
+ return this.resolvedSetpointInteraction === "flip-flop";
222920
+ }
222921
+ get isPopUp() {
222922
+ return this.resolvedSetpointInteraction === "pop-up";
222923
+ }
222924
+ get setpointTouching() {
222925
+ return this.setpointOptions?.touching ?? false;
222926
+ }
222927
+ /**
222928
+ * The setpoint is rendered "emphasised" (primary size + SemiBold weight) when
222929
+ * it is the focus of attention: while actively adjusting (`touching`), or while
222930
+ * a flip-flop has the value away from the setpoint. Otherwise it is a secondary
222931
+ * (smaller, regular-weight) reference next to the value.
222932
+ */
222933
+ get isSetpointEmphasized() {
222459
222934
  if (!this.hasSetpoint) {
222460
- return ReadoutSetpointSize.small;
222935
+ return false;
222461
222936
  }
222462
- if (this.priority === "setpoint" || this.priority === "setpoint-flip-flop") {
222463
- return this.resolvedMainValueSize;
222937
+ if (this.setpointTouching) {
222938
+ return true;
222464
222939
  }
222465
- return ReadoutSetpointSize.small;
222940
+ return this.isFlipFlop && !this.isAtSetpoint;
222466
222941
  }
222467
- get resolvedActualPriority() {
222468
- if (this.priority === "enhanced" || this.priority === "setpoint" && !this.hasSetpoint || this.priority === "setpoint-flip-flop") {
222469
- return Priority.enhanced;
222470
- }
222471
- return Priority.regular;
222942
+ /**
222943
+ * The row's enhanced (in-command) colour state, applied uniformly to BOTH the
222944
+ * value and the setpoint — they are always either both neutral or both enhanced
222945
+ * (never a blue setpoint next to a grey value). Driven by `priority` only;
222946
+ * `valueOptions.weight` changes weight, not colour.
222947
+ */
222948
+ get rowEnhanced() {
222949
+ return this.resolvedPriority === "enhanced";
222472
222950
  }
222473
- get resolvedActualMode() {
222474
- return this.priority === "enhanced" ? ReadoutSetpointMode.setpoint : ReadoutSetpointMode.display;
222951
+ /** Primary value-typography size for the current density tier. */
222952
+ get primarySize() {
222953
+ switch (this.resolvedSize) {
222954
+ case "large":
222955
+ return ObcTextboxSize.l;
222956
+ case "medium":
222957
+ return ObcTextboxSize.m;
222958
+ default:
222959
+ return ObcTextboxSize.s;
222960
+ }
222475
222961
  }
222476
- get resolvedSetpointPriority() {
222477
- if (!this.hasSetpoint || this.priority === "regular") {
222478
- return Priority.regular;
222962
+ /** Secondary (de-emphasised) value-typography size for the current density tier. */
222963
+ get secondarySize() {
222964
+ switch (this.resolvedSize) {
222965
+ case "large":
222966
+ return ObcTextboxSize.s;
222967
+ case "medium":
222968
+ return ObcTextboxSize.s;
222969
+ default:
222970
+ return ObcTextboxSize.xs;
222479
222971
  }
222480
- return Priority.enhanced;
222481
222972
  }
222482
- get resolvedSetpointMode() {
222483
- if (this.hasSetpoint && this.priority === "setpoint") {
222484
- return ReadoutSetpointMode.setpoint;
222973
+ get valueSize() {
222974
+ if (this.isSetpointEmphasized) {
222975
+ return this.secondarySize;
222485
222976
  }
222486
- return ReadoutSetpointMode.display;
222977
+ return this.primarySize;
222487
222978
  }
222488
- get showsTrailingSource() {
222489
- return this.hasSource && this.stacking !== "leading-src";
222979
+ get setpointSize() {
222980
+ return this.isSetpointEmphasized ? this.primarySize : this.secondarySize;
222490
222981
  }
222491
- get stacksLeadingUnitVertically() {
222492
- return this.stacking === "leading-unit" && this.size === "enhanced";
222982
+ /** Value font weight passes straight to obc-textbox; regular when unset. Colour is separate. */
222983
+ get valueWeight() {
222984
+ return this.valueOptions?.weight ?? ObcTextboxFontWeight.regular;
222493
222985
  }
222494
- get stacksLeadingSrcVertically() {
222495
- return this.stacking === "leading-src" && this.size === "enhanced";
222986
+ /** Setpoint is SemiBold only while emphasised, otherwise regular weight. */
222987
+ get setpointWeight() {
222988
+ return this.isSetpointEmphasized ? ObcTextboxFontWeight.semibold : ObcTextboxFontWeight.regular;
222496
222989
  }
222497
- renderLabelContainer() {
222498
- if (!this.hasLabel) {
222499
- return A;
222990
+ numericFormatOptions(maxDigits) {
222991
+ return {
222992
+ showZeroPadding: false,
222993
+ minValueLength: maxDigits,
222994
+ fractionDigits: this.resolvedFractionDigits
222995
+ };
222996
+ }
222997
+ /** Widest possible value string for width reservation (e.g. `"000.0"`). */
222998
+ get reserverText() {
222999
+ const maxDigits = this.resolvedMaxDigits;
223000
+ if (maxDigits <= 0) {
223001
+ return "";
222500
223002
  }
222501
- const showsLeadingUnit = this.stacking === "leading-unit" && this.hasUnit;
222502
- const showsLeadingSrc = this.stacking === "leading-src" && this.hasSource;
222503
- if (showsLeadingUnit && !this.stacksLeadingUnitVertically) {
222504
- return b`
222505
- <div class="label-inline" part="label-inline">
222506
- <div class="label" part="label">${this.label}</div>
222507
- <div class="unit unit-leading" part="unit-leading">${this.unit}</div>
222508
- </div>
222509
- `;
223003
+ const fractionDigits = this.resolvedFractionDigits;
223004
+ const integer = "0".repeat(Math.max(maxDigits, 1));
223005
+ return fractionDigits > 0 ? `${integer}.${"0".repeat(fractionDigits)}` : integer;
223006
+ }
223007
+ /**
223008
+ * Effective width reserver for a numeric block: the wider of the explicit
223009
+ * `spaceReserver` and the `maxDigits`/`fractionDigits`-derived reserve, so an
223010
+ * explicit reserver can never reserve *less* than the formatted value needs.
223011
+ * Under tabular-nums the rendered width is proportional to character count, so
223012
+ * "wider" compares string length.
223013
+ */
223014
+ widerReserver(explicit, derived) {
223015
+ if (!explicit) {
223016
+ return derived;
222510
223017
  }
222511
- if (showsLeadingSrc && !this.stacksLeadingSrcVertically) {
222512
- return b`
222513
- <div class="label-inline" part="label-inline">
222514
- <div class="label" part="label">${this.label}</div>
222515
- <div class="source source-inline" part="source-inline">
222516
- ${this.src}
222517
- </div>
222518
- </div>
222519
- `;
223018
+ if (!derived) {
223019
+ return explicit;
222520
223020
  }
222521
- return b`
222522
- <div class="label-stack" part="label-stack">
222523
- <div class="label" part="label">${this.label}</div>
222524
- ${showsLeadingUnit ? b`<div class="unit unit-leading" part="unit-leading">
222525
- ${this.unit}
222526
- </div>` : A}
222527
- ${showsLeadingSrc ? b`<div class="source source-inline" part="source-inline">
222528
- ${this.src}
222529
- </div>` : A}
222530
- </div>
222531
- `;
223021
+ return explicit.length >= derived.length ? explicit : derived;
222532
223022
  }
222533
- renderValueIconSlot() {
222534
- if (!this.hasValueIcon) {
222535
- return A;
223023
+ /** classMap fragment for a block / source carrying per-block data quality. */
223024
+ dataQualityClasses(dataQuality) {
223025
+ return {
223026
+ "data-low-integrity": dataQuality === "low-integrity",
223027
+ "data-invalid": dataQuality === "invalid"
223028
+ /* invalid */
223029
+ };
223030
+ }
223031
+ renderIcon(role) {
223032
+ if (role === "value") {
223033
+ if (!this.valueOptions?.hasIcon) {
223034
+ return A;
223035
+ }
223036
+ return b`<span class="block-icon" aria-hidden="true"
223037
+ ><slot name="value-icon"></slot
223038
+ ></span>`;
223039
+ }
223040
+ if (role === "setpoint") {
223041
+ return b`<span class="block-icon" aria-hidden="true">
223042
+ <slot name="setpoint-icon"><obi-input-right></obi-input-right></slot>
223043
+ </span>`;
222536
223044
  }
222537
- return b`<span class="value-icon" slot="icon" aria-hidden="true">
222538
- <slot name="value-icon"></slot>
223045
+ return b`<span class="block-icon" aria-hidden="true">
223046
+ <slot name="advice-icon"
223047
+ ><obi-notification-advice></obi-notification-advice
223048
+ ></slot>
222539
223049
  </span>`;
222540
223050
  }
222541
- renderSetpoint() {
222542
- if (!this.hasSetpoint) {
222543
- return A;
222544
- }
222545
- return b`
222546
- <obc-readout-setpoint
222547
- .variant=${"setpoint"}
222548
- .readoutStyle=${"regular"}
222549
- .direction=${"horizontal"}
222550
- .size=${this.resolvedSetpointSize}
222551
- .priority=${this.resolvedSetpointPriority}
222552
- .mode=${this.resolvedSetpointMode}
222553
- .hugContent=${true}
222554
- .value=${this.setpointValue}
222555
- .showZeroPadding=${this.showZeroPadding}
222556
- .fractionDigits=${this.fractionDigits}
222557
- .minValueLength=${this.minValueLength}
222558
- .hasHintedZeros=${this.hasHintedZeros}
222559
- .hasDegree=${this.hasDegree}
223051
+ renderBlock(config) {
223052
+ const formatOptions = this.numericFormatOptions(this.resolvedMaxDigits);
223053
+ const valueForFormat = config.value ?? void 0;
223054
+ const text = config.off ? "OFF" : formatNumericValue(valueForFormat, formatOptions);
223055
+ const hinted = config.off || !config.hintedZeros ? "" : getHintZeros(valueForFormat, {
223056
+ ...formatOptions,
223057
+ minValueLength: formatOptions.minValueLength + formatOptions.fractionDigits
223058
+ });
223059
+ const reserver = this.widerReserver(
223060
+ config.spaceReserver,
223061
+ this.reserverText
223062
+ );
223063
+ const block = b`
223064
+ <div
223065
+ class=${e$1({
223066
+ block: true,
223067
+ [`block-${config.role}`]: true,
223068
+ "tone-enhanced": config.enhanced,
223069
+ ...this.dataQualityClasses(config.dataQuality),
223070
+ ...config.extraClasses ?? {}
223071
+ })}
223072
+ part="block block-${config.role}"
222560
223073
  >
222561
- <obi-input-right slot="icon"></obi-input-right>
222562
- </obc-readout-setpoint>
223074
+ ${this.renderIcon(config.role)}
223075
+ <span class="block-content">
223076
+ <obc-textbox
223077
+ class="block-text"
223078
+ .size=${config.size}
223079
+ .fontWeight=${config.weight}
223080
+ .tabularNums=${true}
223081
+ >
223082
+ ${hinted ? b`<span class="hinted-zero" aria-hidden="true"
223083
+ >${hinted}</span
223084
+ >` : A}${text}
223085
+ ${reserver ? b`<span slot="length">${reserver}</span>` : A}
223086
+ </obc-textbox>
223087
+ ${config.hasDegree ? this.renderDegreeGlyph(config.size, { inherit: true }) : A}
223088
+ </span>
223089
+ </div>
222563
223090
  `;
223091
+ return wrapWithAlertFrame(config.alert ?? false, block);
222564
223092
  }
222565
- renderActualValue() {
223093
+ /**
223094
+ * A cap-height `°` column whose width scales with the value size. Used after
223095
+ * the value (as the value↔unit boundary, via {@link renderValueUnitGap}) and
223096
+ * inside the setpoint / advice blocks. `inherit` makes the glyph take the
223097
+ * surrounding block's colour (setpoint/advice); otherwise it uses the value
223098
+ * colour, optionally `enhanced`.
223099
+ */
223100
+ renderDegreeGlyph(size, opts = {}) {
222566
223101
  return b`
222567
- <obc-readout-setpoint
222568
- .variant=${"value"}
222569
- .readoutStyle=${"regular"}
222570
- .direction=${"horizontal"}
222571
- .size=${this.resolvedValueSize}
222572
- .valueTypography=${this.resolvedValueTypography ?? void 0}
222573
- .priority=${this.resolvedActualPriority}
222574
- .mode=${this.resolvedActualMode}
222575
- .hugContent=${true}
222576
- .value=${this.value}
222577
- .showZeroPadding=${this.showZeroPadding}
222578
- .fractionDigits=${this.fractionDigits}
222579
- .minValueLength=${this.minValueLength}
222580
- .hasHintedZeros=${this.hasHintedZeros}
222581
- .hasDegree=${this.hasDegree}
223102
+ <span
223103
+ class=${e$1({
223104
+ "degree-column": true,
223105
+ [`degree-${size}`]: true,
223106
+ "tone-enhanced": !opts.inherit && Boolean(opts.enhanced),
223107
+ "degree-inherit": Boolean(opts.inherit)
223108
+ })}
223109
+ part="degree"
222582
223110
  >
222583
- ${this.renderValueIconSlot()}
222584
- </obc-readout-setpoint>
223111
+ <obc-textbox class="degree-glyph" .size=${size} alignment="center"
223112
+ >°</obc-textbox
223113
+ >
223114
+ </span>
222585
223115
  `;
222586
223116
  }
222587
- renderValue() {
223117
+ /**
223118
+ * The gap rendered between the value digits and the unit.
223119
+ *
223120
+ * - `hasDegree`: a cap-height `°` column whose width scales with the value
223121
+ * size (the `°` replaces the default gap).
223122
+ * - otherwise: the default 2px gap (only when a trailing unit follows).
223123
+ *
223124
+ * `hasDegreeSpacer` deliberately does NOT add anything here — it keeps the 2px
223125
+ * gap and instead widens the unit column via {@link renderDegreeSpacer} (a
223126
+ * spacer AFTER the unit). That way a non-degree row's value digits stay
223127
+ * aligned with degree rows (degree column width = spacer width + 2px gap)
223128
+ * while its unit shifts left. Mirrors Figma `1:2920` (spacer) / `1:2970`
223129
+ * (degree).
223130
+ *
223131
+ * TODO(designer): cross-size alignment is deferred. Degree rows of different
223132
+ * value sizes have different `°` column widths (6/8/12px), so their value digit
223133
+ * edges stagger by `degree-width`. For degree rows of mixed sizes you cannot
223134
+ * align the value digit edges AND keep the unit column aligned — resolving it
223135
+ * needs a design decision (a constant degree reserve, which widens the smaller
223136
+ * rows' `°`, OR pinning the value edge and letting the unit column stagger).
223137
+ */
223138
+ renderValueUnitGap() {
223139
+ if (!this.hasValue) {
223140
+ return A;
223141
+ }
223142
+ const hasTrailingUnit = Boolean(this.unit) && this.resolvedStacking !== "leading-unit";
223143
+ if ((this.hasDegree ?? false) && !this.off) {
223144
+ return this.renderDegreeGlyph(this.valueSize, {
223145
+ enhanced: this.rowEnhanced
223146
+ });
223147
+ }
223148
+ if (hasTrailingUnit) {
223149
+ return b`<span class="value-unit-gap" aria-hidden="true"></span>`;
223150
+ }
223151
+ return A;
223152
+ }
223153
+ /**
223154
+ * A spacer rendered AFTER the unit when `hasDegreeSpacer` is set on a
223155
+ * non-degree row. Its width (`degree-compensation-padding`) = the degree
223156
+ * column width minus the 2px gap, so the row's value digits align with degree
223157
+ * rows in the same column while its unit shifts left. See
223158
+ * {@link renderValueUnitGap}.
223159
+ */
223160
+ renderDegreeSpacer() {
223161
+ const hasDegree = this.hasDegree ?? false;
223162
+ const hasDegreeSpacer = this.hasDegreeSpacer ?? false;
223163
+ if (hasDegree || !hasDegreeSpacer) {
223164
+ return A;
223165
+ }
223166
+ return b`<span
223167
+ class="degree-spacer"
223168
+ part="degree-spacer"
223169
+ aria-hidden="true"
223170
+ ></span>`;
223171
+ }
223172
+ renderTextbox(role, text, reserver, state2) {
223173
+ const weight = role === "label" ? ObcTextboxFontWeight.semibold : ObcTextboxFontWeight.regular;
223174
+ const box = b`
223175
+ <obc-textbox
223176
+ class=${e$1({
223177
+ [role]: true,
223178
+ ...this.dataQualityClasses(state2?.dataQuality)
223179
+ })}
223180
+ part=${role}
223181
+ .size=${ObcTextboxSize.xs}
223182
+ .fontWeight=${weight}
223183
+ alignment="left"
223184
+ >
223185
+ ${text}
223186
+ ${reserver ? b`<span slot="length">${reserver}</span>` : A}
223187
+ </obc-textbox>
223188
+ `;
223189
+ return wrapWithAlertFrame(state2?.alert ?? false, box);
223190
+ }
223191
+ renderValueCluster() {
223192
+ const popUpAtSetpoint = this.isPopUp && this.isAtSetpoint && !this.setpointTouching;
223193
+ const setpointExtraClasses = {
223194
+ "is-hiding": popUpAtSetpoint && this.deferredSetpointHidePhase === "hiding",
223195
+ "is-hidden": popUpAtSetpoint && this.deferredSetpointHidePhase === "hidden",
223196
+ touching: this.setpointTouching
223197
+ };
222588
223198
  return b`
222589
- <div class="value-wrap" part="value-wrap">
222590
- ${this.hasSetpoint ? b`<div class="value-cluster" part="value-cluster">
222591
- ${this.renderSetpoint()} ${this.renderActualValue()}
222592
- </div>` : this.renderActualValue()}
223199
+ <div class="value-cluster" part="value-cluster">
223200
+ ${this.hasAdvice ? this.renderBlock({
223201
+ role: "advice",
223202
+ value: this.advice,
223203
+ size: this.secondarySize,
223204
+ enhanced: false,
223205
+ weight: ObcTextboxFontWeight.regular,
223206
+ hintedZeros: this.adviceOptions?.hintedZeros ?? false,
223207
+ spaceReserver: this.adviceOptions?.spaceReserver,
223208
+ hasDegree: this.hasDegree ?? false,
223209
+ dataQuality: this.adviceOptions?.dataQuality,
223210
+ alert: this.adviceOptions?.alert
223211
+ }) : A}
223212
+ ${this.hasSetpoint ? this.renderBlock({
223213
+ role: "setpoint",
223214
+ value: this.setpoint,
223215
+ size: this.setpointSize,
223216
+ // Value and setpoint share the enhanced colour state (both neutral
223217
+ // or both enhanced); the setpoint is bold only while emphasised.
223218
+ enhanced: this.rowEnhanced,
223219
+ weight: this.setpointWeight,
223220
+ hintedZeros: this.setpointOptions?.hintedZeros ?? false,
223221
+ spaceReserver: this.setpointOptions?.spaceReserver,
223222
+ hasDegree: this.hasDegree ?? false,
223223
+ extraClasses: setpointExtraClasses,
223224
+ dataQuality: this.setpointOptions?.dataQuality,
223225
+ alert: this.setpointOptions?.alert
223226
+ }) : A}
223227
+ ${this.hasValue ? this.renderBlock({
223228
+ role: "value",
223229
+ value: this.value,
223230
+ size: this.valueSize,
223231
+ enhanced: this.rowEnhanced,
223232
+ weight: this.valueWeight,
223233
+ hintedZeros: this.valueOptions?.hintedZeros ?? false,
223234
+ spaceReserver: this.valueOptions?.spaceReserver,
223235
+ off: this.off,
223236
+ dataQuality: this.valueOptions?.dataQuality,
223237
+ alert: this.valueOptions?.alert
223238
+ }) : A}
223239
+ </div>
223240
+ `;
223241
+ }
223242
+ renderLabelContainer() {
223243
+ const stacking = this.resolvedStacking;
223244
+ const showLeadingUnit = stacking === "leading-unit" && Boolean(this.unit);
223245
+ const showLeadingSrc = stacking === "leading-src" && Boolean(this.src);
223246
+ return b`
223247
+ <div class="label-container" part="label-container">
223248
+ ${this.hasLeadingIcon ? b`<span class="leading-icon" aria-hidden="true"
223249
+ ><slot name="leading-icon"></slot
223250
+ ></span>` : A}
223251
+ <div class="label-stack" part="label-stack">
223252
+ ${this.label ? this.renderTextbox("label", this.label) : A}
223253
+ ${showLeadingUnit ? this.renderTextbox(
223254
+ "unit",
223255
+ this.unit ?? "",
223256
+ this.unitOptions?.spaceReserver
223257
+ ) : A}
223258
+ ${showLeadingSrc ? this.renderTextbox(
223259
+ "source",
223260
+ this.src ?? "",
223261
+ this.srcOptions?.spaceReserver,
223262
+ this.srcOptions
223263
+ ) : A}
223264
+ </div>
222593
223265
  </div>
222594
223266
  `;
222595
223267
  }
222596
223268
  renderTrailingUnit() {
222597
- if (!this.hasUnit || this.stacking === "leading-unit") {
223269
+ if (this.resolvedStacking === "leading-unit" || !this.unit) {
222598
223270
  return A;
222599
223271
  }
222600
- return b`<div class="unit unit-trailing" part="unit-trailing">
222601
- ${this.unit}
222602
- </div>`;
223272
+ return this.renderTextbox(
223273
+ "unit",
223274
+ this.unit,
223275
+ this.unitOptions?.spaceReserver
223276
+ );
222603
223277
  }
222604
223278
  renderTrailingSource() {
222605
- if (!this.showsTrailingSource) {
223279
+ if (this.resolvedStacking === "leading-src" || !this.src) {
222606
223280
  return A;
222607
223281
  }
222608
223282
  return b`
222609
223283
  <div class="divider" part="divider" aria-hidden="true"></div>
222610
- <div class="source source-trailing" part="source-trailing">
222611
- ${this.src}
222612
- </div>
223284
+ ${this.renderTextbox(
223285
+ "source",
223286
+ this.src,
223287
+ this.srcOptions?.spaceReserver,
223288
+ this.srcOptions
223289
+ )}
222613
223290
  `;
222614
223291
  }
222615
- render() {
222616
- return wrapWithAlertFrame(
222617
- this.alert,
222618
- b`
222619
- <div
222620
- class=${e$1({
222621
- root: true,
222622
- [`size-${this.size}`]: true,
222623
- [`stacking-${this.stacking}`]: true,
222624
- "priority-enhanced": this.priority === "enhanced",
222625
- "priority-setpoint": this.priority === "setpoint",
222626
- "priority-setpoint-flip-flop": this.priority === "setpoint-flip-flop",
222627
- "data-none": this.dataState === "none",
222628
- "data-low-integrity": this.dataState === "low-integrity",
222629
- "data-invalid": this.dataState === "invalid",
222630
- "has-leading-icon": this.hasLeadingIcon,
222631
- "has-value-icon": this.hasValueIcon
222632
- })}
222633
- part="root"
222634
- >
222635
- <div class="content" part="content">
222636
- <div class="label-container" part="label-container">
222637
- ${this.hasLeadingIcon ? b`<span class="leading-icon" aria-hidden="true"
222638
- ><slot name="leading-icon"></slot
222639
- ></span>` : A}
222640
- ${this.renderLabelContainer()}
222641
- </div>
222642
-
222643
- ${this.labelOnly ? A : b`
222644
- <div class="value-container" part="value-container">
222645
- ${this.renderValue()} ${this.renderTrailingUnit()}
222646
- </div>
222647
-
222648
- ${this.renderTrailingSource()}
222649
- `}
223292
+ renderContent() {
223293
+ return b`
223294
+ <div class="content" part="content">
223295
+ ${this.renderLabelContainer()}
223296
+ <div class="value-area" part="value-area">
223297
+ ${this.renderValueCluster()} ${this.renderValueUnitGap()}
223298
+ <div class="unit-area" part="unit-area">
223299
+ ${this.renderTrailingUnit()} ${this.renderDegreeSpacer()}
222650
223300
  </div>
222651
223301
  </div>
222652
- `,
222653
- true
222654
- );
223302
+ ${this.renderTrailingSource()}
223303
+ </div>
223304
+ `;
223305
+ }
223306
+ updated(changed) {
223307
+ super.updated(changed);
223308
+ const firstUpdate = !this.hasCompletedFirstUpdate;
223309
+ this.hasCompletedFirstUpdate = true;
223310
+ if (!this.isPopUp || this.setpointTouching) {
223311
+ this.clearDeferredSetpointHide();
223312
+ return;
223313
+ }
223314
+ const shouldHide = this.hasSetpoint && this.isAtSetpoint;
223315
+ if (firstUpdate) {
223316
+ this.deferredSetpointHidePhase = shouldHide ? "hidden" : "none";
223317
+ return;
223318
+ }
223319
+ if (!shouldHide) {
223320
+ this.clearDeferredSetpointHide();
223321
+ return;
223322
+ }
223323
+ if (this.deferredSetpointHidePhase !== "none") {
223324
+ return;
223325
+ }
223326
+ this.deferredSetpointHidePhase = "hiding";
223327
+ window.clearTimeout(this.deferredSetpointHideTimer);
223328
+ this.deferredSetpointHideTimer = window.setTimeout(() => {
223329
+ this.deferredSetpointHidePhase = "hidden";
223330
+ this.deferredSetpointHideTimer = void 0;
223331
+ }, 100);
223332
+ }
223333
+ clearDeferredSetpointHide() {
223334
+ if (this.deferredSetpointHidePhase !== "none") {
223335
+ this.deferredSetpointHidePhase = "none";
223336
+ }
223337
+ window.clearTimeout(this.deferredSetpointHideTimer);
223338
+ this.deferredSetpointHideTimer = void 0;
223339
+ }
223340
+ disconnectedCallback() {
223341
+ window.clearTimeout(this.deferredSetpointHideTimer);
223342
+ this.deferredSetpointHideTimer = void 0;
223343
+ if (this.deferredSetpointHidePhase === "hiding") {
223344
+ this.deferredSetpointHidePhase = "hidden";
223345
+ }
223346
+ super.disconnectedCallback();
223347
+ }
223348
+ render() {
223349
+ const clickable = this.resolvedClickable;
223350
+ const dataQuality = this.dataQuality;
223351
+ const classes = e$1({
223352
+ root: true,
223353
+ [`size-${this.resolvedSize}`]: true,
223354
+ [`stacking-${this.resolvedStacking}`]: true,
223355
+ [`priority-${this.resolvedPriority}`]: true,
223356
+ "data-low-integrity": dataQuality === "low-integrity",
223357
+ "data-invalid": dataQuality === "invalid",
223358
+ "flip-flop": this.isFlipFlop,
223359
+ clickable: Boolean(clickable),
223360
+ [`border-${clickable ? clickable.border : "squared"}`]: Boolean(clickable)
223361
+ });
223362
+ const surface = b`<div class="surface" part="surface">
223363
+ ${this.renderContent()}
223364
+ </div>`;
223365
+ const root = clickable ? b`<button class=${classes} part="root" type="button">
223366
+ ${surface}
223367
+ </button>` : b`<div class=${classes} part="root">${surface}</div>`;
223368
+ const alert = this.alert === true ? {} : this.alert;
223369
+ return wrapWithAlertFrame(alert, root, true);
222655
223370
  }
222656
223371
  };
222657
223372
  ObcReadoutListItem.styles = r$7(componentStyle$4);
222658
- __decorateClass$f([
222659
- n$3({ type: String })
222660
- ], ObcReadoutListItem.prototype, "size", 2);
222661
- __decorateClass$f([
222662
- n$3({ type: String })
222663
- ], ObcReadoutListItem.prototype, "stacking", 2);
222664
- __decorateClass$f([
222665
- n$3({ type: String })
222666
- ], ObcReadoutListItem.prototype, "priority", 2);
222667
- __decorateClass$f([
222668
- n$3({ type: String })
222669
- ], ObcReadoutListItem.prototype, "dataState", 2);
222670
- __decorateClass$f([
222671
- n$3({ type: Object })
222672
- ], ObcReadoutListItem.prototype, "alert", 2);
222673
223373
  __decorateClass$f([
222674
223374
  n$3({ type: String })
222675
223375
  ], ObcReadoutListItem.prototype, "label", 2);
@@ -222679,48 +223379,78 @@ __decorateClass$f([
222679
223379
  __decorateClass$f([
222680
223380
  n$3({ type: String })
222681
223381
  ], ObcReadoutListItem.prototype, "src", 2);
223382
+ __decorateClass$f([
223383
+ n$3({ type: Boolean, attribute: false })
223384
+ ], ObcReadoutListItem.prototype, "hasValue", 2);
222682
223385
  __decorateClass$f([
222683
223386
  n$3({ type: Number })
222684
223387
  ], ObcReadoutListItem.prototype, "value", 2);
222685
223388
  __decorateClass$f([
222686
- n$3({ type: Number })
222687
- ], ObcReadoutListItem.prototype, "setpointValue", 2);
223389
+ n$3({ type: Boolean })
223390
+ ], ObcReadoutListItem.prototype, "off", 2);
222688
223391
  __decorateClass$f([
222689
223392
  n$3({ type: Boolean })
222690
223393
  ], ObcReadoutListItem.prototype, "hasSetpoint", 2);
222691
223394
  __decorateClass$f([
222692
- n$3({ type: Boolean })
222693
- ], ObcReadoutListItem.prototype, "hasDegree", 2);
223395
+ n$3({ type: Number })
223396
+ ], ObcReadoutListItem.prototype, "setpoint", 2);
222694
223397
  __decorateClass$f([
222695
223398
  n$3({ type: Boolean })
222696
- ], ObcReadoutListItem.prototype, "hasUnit", 2);
223399
+ ], ObcReadoutListItem.prototype, "hasAdvice", 2);
222697
223400
  __decorateClass$f([
222698
- n$3({ type: Boolean })
222699
- ], ObcReadoutListItem.prototype, "hasLabel", 2);
223401
+ n$3({ type: Number })
223402
+ ], ObcReadoutListItem.prototype, "advice", 2);
222700
223403
  __decorateClass$f([
222701
- n$3({ type: Boolean })
222702
- ], ObcReadoutListItem.prototype, "hasSource", 2);
223404
+ n$3({ type: String })
223405
+ ], ObcReadoutListItem.prototype, "size", 2);
223406
+ __decorateClass$f([
223407
+ n$3({ type: String })
223408
+ ], ObcReadoutListItem.prototype, "priority", 2);
223409
+ __decorateClass$f([
223410
+ n$3({ type: String })
223411
+ ], ObcReadoutListItem.prototype, "stacking", 2);
223412
+ __decorateClass$f([
223413
+ n$3({ type: Object })
223414
+ ], ObcReadoutListItem.prototype, "clickable", 2);
222703
223415
  __decorateClass$f([
222704
223416
  n$3({ type: Boolean })
222705
223417
  ], ObcReadoutListItem.prototype, "hasLeadingIcon", 2);
222706
223418
  __decorateClass$f([
222707
223419
  n$3({ type: Boolean })
222708
- ], ObcReadoutListItem.prototype, "hasValueIcon", 2);
223420
+ ], ObcReadoutListItem.prototype, "hasDegree", 2);
223421
+ __decorateClass$f([
223422
+ n$3({ type: Boolean })
223423
+ ], ObcReadoutListItem.prototype, "hasDegreeSpacer", 2);
222709
223424
  __decorateClass$f([
222710
223425
  n$3({ type: Number })
222711
223426
  ], ObcReadoutListItem.prototype, "fractionDigits", 2);
222712
- __decorateClass$f([
222713
- n$3({ type: Boolean })
222714
- ], ObcReadoutListItem.prototype, "showZeroPadding", 2);
222715
223427
  __decorateClass$f([
222716
223428
  n$3({ type: Number })
222717
- ], ObcReadoutListItem.prototype, "minValueLength", 2);
223429
+ ], ObcReadoutListItem.prototype, "maxDigits", 2);
222718
223430
  __decorateClass$f([
222719
- n$3({ type: Boolean })
222720
- ], ObcReadoutListItem.prototype, "hasHintedZeros", 2);
223431
+ n$3({ type: String })
223432
+ ], ObcReadoutListItem.prototype, "dataQuality", 2);
222721
223433
  __decorateClass$f([
222722
- n$3({ type: Boolean })
222723
- ], ObcReadoutListItem.prototype, "labelOnly", 2);
223434
+ n$3({ type: Object })
223435
+ ], ObcReadoutListItem.prototype, "alert", 2);
223436
+ __decorateClass$f([
223437
+ n$3({ type: Object })
223438
+ ], ObcReadoutListItem.prototype, "valueOptions", 2);
223439
+ __decorateClass$f([
223440
+ n$3({ type: Object })
223441
+ ], ObcReadoutListItem.prototype, "setpointOptions", 2);
223442
+ __decorateClass$f([
223443
+ n$3({ type: Object })
223444
+ ], ObcReadoutListItem.prototype, "adviceOptions", 2);
223445
+ __decorateClass$f([
223446
+ n$3({ type: Object })
223447
+ ], ObcReadoutListItem.prototype, "unitOptions", 2);
223448
+ __decorateClass$f([
223449
+ n$3({ type: Object })
223450
+ ], ObcReadoutListItem.prototype, "srcOptions", 2);
223451
+ __decorateClass$f([
223452
+ r$3()
223453
+ ], ObcReadoutListItem.prototype, "deferredSetpointHidePhase", 2);
222724
223454
  ObcReadoutListItem = __decorateClass$f([
222725
223455
  customElement("obc-readout-list-item")
222726
223456
  ], ObcReadoutListItem);