@oicl/openbridge-webcomponents 2.0.0-next.151 → 2.0.0-next.152

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 (89) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +989 -319
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +1643 -51
  4. package/dist/alert-severity.d.ts +12 -9
  5. package/dist/alert-severity.d.ts.map +1 -1
  6. package/dist/alert-severity.js +30 -38
  7. package/dist/alert-severity.js.map +1 -1
  8. package/dist/building-blocks/bar-horizontal/bar-horizontal.d.ts +10 -0
  9. package/dist/building-blocks/bar-horizontal/bar-horizontal.d.ts.map +1 -1
  10. package/dist/building-blocks/bar-horizontal/bar-horizontal.js +6 -1
  11. package/dist/building-blocks/bar-horizontal/bar-horizontal.js.map +1 -1
  12. package/dist/building-blocks/bar-vertical/bar-vertical.d.ts +10 -0
  13. package/dist/building-blocks/bar-vertical/bar-vertical.d.ts.map +1 -1
  14. package/dist/building-blocks/bar-vertical/bar-vertical.js +6 -1
  15. package/dist/building-blocks/bar-vertical/bar-vertical.js.map +1 -1
  16. package/dist/building-blocks/chart-line/chart-line-base.d.ts +137 -0
  17. package/dist/building-blocks/chart-line/chart-line-base.d.ts.map +1 -1
  18. package/dist/building-blocks/chart-line/chart-line-base.js +464 -79
  19. package/dist/building-blocks/chart-line/chart-line-base.js.map +1 -1
  20. package/dist/building-blocks/external-scale/external-scale.d.ts +11 -0
  21. package/dist/building-blocks/external-scale/external-scale.d.ts.map +1 -1
  22. package/dist/building-blocks/external-scale/external-scale.js +45 -12
  23. package/dist/building-blocks/external-scale/external-scale.js.map +1 -1
  24. package/dist/charthelpers/index.d.ts +1 -0
  25. package/dist/charthelpers/index.d.ts.map +1 -1
  26. package/dist/charthelpers/index.js +7 -1
  27. package/dist/charthelpers/index.js.map +1 -1
  28. package/dist/charthelpers/range-labels.d.ts +55 -0
  29. package/dist/charthelpers/range-labels.d.ts.map +1 -0
  30. package/dist/charthelpers/range-labels.js +36 -0
  31. package/dist/charthelpers/range-labels.js.map +1 -0
  32. package/dist/components/alert-button/alert-button.css.js +13 -21
  33. package/dist/components/alert-button/alert-button.css.js.map +1 -1
  34. package/dist/components/alert-button/alert-button.d.ts +9 -4
  35. package/dist/components/alert-button/alert-button.d.ts.map +1 -1
  36. package/dist/components/alert-button/alert-button.js +24 -15
  37. package/dist/components/alert-button/alert-button.js.map +1 -1
  38. package/dist/components/alert-frame/alert-frame.css.js +109 -33
  39. package/dist/components/alert-frame/alert-frame.css.js.map +1 -1
  40. package/dist/components/alert-frame/alert-frame.d.ts +34 -7
  41. package/dist/components/alert-frame/alert-frame.d.ts.map +1 -1
  42. package/dist/components/alert-frame/alert-frame.js +134 -30
  43. package/dist/components/alert-frame/alert-frame.js.map +1 -1
  44. package/dist/components/alert-icon/alert-icon.d.ts +10 -7
  45. package/dist/components/alert-icon/alert-icon.d.ts.map +1 -1
  46. package/dist/components/alert-icon/alert-icon.js +37 -60
  47. package/dist/components/alert-icon/alert-icon.js.map +1 -1
  48. package/dist/components/alert-menu-item/alert-menu-item.css.js +1 -4
  49. package/dist/components/alert-menu-item/alert-menu-item.css.js.map +1 -1
  50. package/dist/components/date-item/date-item.css.js +3 -3
  51. package/dist/components/keyboard-full/keyboard-full.css.js +4 -4
  52. package/dist/components/message-menu-item/message-menu-item.css.js +2 -6
  53. package/dist/components/message-menu-item/message-menu-item.css.js.map +1 -1
  54. package/dist/components/sequence-toolbar/sequence-toolbar.css.js +1 -2
  55. package/dist/components/sequence-toolbar/sequence-toolbar.css.js.map +1 -1
  56. package/dist/index.js +2 -1
  57. package/dist/navigation-instruments/gauge-trend/gauge-trend.d.ts +6 -0
  58. package/dist/navigation-instruments/gauge-trend/gauge-trend.d.ts.map +1 -1
  59. package/dist/navigation-instruments/gauge-trend/gauge-trend.js +8 -0
  60. package/dist/navigation-instruments/gauge-trend/gauge-trend.js.map +1 -1
  61. package/dist/navigation-instruments/instrument-field/instrument-field.css.js +2 -2
  62. package/dist/navigation-instruments/readout/readout.d.ts.map +1 -1
  63. package/dist/navigation-instruments/readout/readout.js +2 -1
  64. package/dist/navigation-instruments/readout/readout.js.map +1 -1
  65. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
  66. package/dist/navigation-instruments/readout-list-item/readout-list-item.js +2 -1
  67. package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
  68. package/dist/openbridge.css +19 -4
  69. package/dist/palettes/blinking.d.ts +14 -4
  70. package/dist/palettes/blinking.d.ts.map +1 -1
  71. package/dist/palettes/blinking.js +41 -35
  72. package/dist/palettes/blinking.js.map +1 -1
  73. package/dist/palettes/flashing-controller.d.ts +21 -0
  74. package/dist/palettes/flashing-controller.d.ts.map +1 -0
  75. package/dist/palettes/flashing-controller.js +45 -0
  76. package/dist/palettes/flashing-controller.js.map +1 -0
  77. package/dist/svghelpers/index.d.ts +1 -0
  78. package/dist/svghelpers/index.d.ts.map +1 -1
  79. package/dist/svghelpers/index.js +2 -0
  80. package/dist/svghelpers/index.js.map +1 -1
  81. package/dist/svghelpers/rounded-rect.d.ts +15 -0
  82. package/dist/svghelpers/rounded-rect.d.ts.map +1 -0
  83. package/dist/svghelpers/rounded-rect.js +29 -0
  84. package/dist/svghelpers/rounded-rect.js.map +1 -0
  85. package/dist/types.d.ts +14 -0
  86. package/dist/types.d.ts.map +1 -1
  87. package/dist/types.js +9 -0
  88. package/dist/types.js.map +1 -1
  89. package/package.json +1 -1
@@ -16,6 +16,14 @@ var AlertType = /* @__PURE__ */ ((AlertType2) => {
16
16
  AlertType2["LevelDiagnostic"] = "level-diagnostic";
17
17
  return AlertType2;
18
18
  })(AlertType || {});
19
+ var FlashingSpeed = /* @__PURE__ */ ((FlashingSpeed2) => {
20
+ FlashingSpeed2["Default"] = "default";
21
+ FlashingSpeed2["Fast"] = "fast";
22
+ FlashingSpeed2["Slow"] = "slow";
23
+ FlashingSpeed2["VerySlow"] = "very-slow";
24
+ FlashingSpeed2["Fixed"] = "fixed";
25
+ return FlashingSpeed2;
26
+ })(FlashingSpeed || {});
19
27
  const ALERT_SEVERITY_PRIORITY = [
20
28
  "level-critical",
21
29
  "alarm",
@@ -14555,7 +14563,9 @@ const compentStyle$1g = i$7`* {
14555
14563
  .wrapper {
14556
14564
  --bg-color: var(--alert-alarm-color);
14557
14565
  --thickness: var(--global-size-spacing-border-weight-alertframe);
14558
- --blink-on: var(--alarm-blink-on);
14566
+ /* 0/1 from the flash-<tempo> classes below; steady when no class applies. */
14567
+ --blink-on: 0;
14568
+ --blink-off: 1;
14559
14569
  color: var(--on-alarm-active-color);
14560
14570
  position: relative;
14561
14571
  width: 100%;
@@ -14565,12 +14575,12 @@ const compentStyle$1g = i$7`* {
14565
14575
  );
14566
14576
  outline: var(--thickness) solid var(--bg-color);
14567
14577
  outline-offset: 0;
14578
+ /* +2 px outward while on, both thicknesses (Figma Flash=yes: 2 → 4 px). */
14568
14579
  --blink-width: 2px;
14569
14580
  }
14570
14581
 
14571
14582
  .wrapper.thickness-small {
14572
14583
  --thickness: 2px;
14573
- --blink-width: 1px;
14574
14584
  }
14575
14585
 
14576
14586
  .wrapper.wrap-content {
@@ -14582,17 +14592,69 @@ const compentStyle$1g = i$7`* {
14582
14592
  width: 100%;
14583
14593
  }
14584
14594
 
14595
+ .wrapper.flash-fast {
14596
+ --blink-on: var(--flash-fast-on);
14597
+ --blink-off: var(--flash-fast-off);
14598
+ }
14599
+
14600
+ .wrapper.flash-slow {
14601
+ --blink-on: var(--flash-slow-on);
14602
+ --blink-off: var(--flash-slow-off);
14603
+ }
14604
+
14605
+ .wrapper.flash-very-slow {
14606
+ --blink-on: var(--flash-very-slow-on);
14607
+ --blink-off: var(--flash-very-slow-off);
14608
+ }
14609
+
14610
+ .wrapper {
14611
+
14612
+ --flash-transition: 50ms linear;
14613
+ }
14614
+
14615
+ .wrapper.flash-effect-outline-eased {
14616
+ transition: outline-width var(--flash-transition);
14617
+ }
14618
+
14619
+ .wrapper.flash-effect-outline-eased .flap {
14620
+ transition: box-shadow var(--flash-transition);
14621
+ }
14622
+
14623
+ .wrapper.flash-effect-outline-eased .mask {
14624
+ transition:
14625
+ top var(--flash-transition),
14626
+ bottom var(--flash-transition),
14627
+ left var(--flash-transition),
14628
+ right var(--flash-transition);
14629
+ }
14630
+
14631
+ .wrapper.flash-effect-outline-eased .dash path {
14632
+ transition: stroke-width var(--flash-transition);
14633
+ }
14634
+
14585
14635
  .wrapper {
14586
14636
 
14587
14637
  --blink-width-dynamic: calc(var(--blink-width) * var(--blink-on));
14638
+ /* One knob for flap and masks, so they cannot drift apart from the outline. */
14639
+ --flap-grow: 0px;
14588
14640
  }
14589
14641
 
14590
- .wrapper.unacked-active {
14642
+ .wrapper.unacked-active,.wrapper.unacked-rectified {
14591
14643
  outline-width: calc(var(--thickness) + var(--blink-width-dynamic));
14592
14644
  }
14593
14645
 
14646
+ .wrapper.unacked-active {
14647
+ --flap-grow: var(--blink-width-dynamic);
14648
+ }
14649
+
14650
+ .wrapper.unacked-rectified {
14651
+ /* The dashed stroke is centred, so it moves out by half its growth. */
14652
+ --flap-grow: calc(var(--blink-width-dynamic) / 2);
14653
+ }
14654
+
14594
14655
  .wrapper.unacked-rectified {
14595
- outline-style: dashed;
14656
+ /* The dash pattern (12/6) needs an SVG stroke; outlines have no dash array. */
14657
+ outline-style: none;
14596
14658
  }
14597
14659
 
14598
14660
  .wrapper.alarm,.wrapper.level-high {
@@ -14602,23 +14664,16 @@ const compentStyle$1g = i$7`* {
14602
14664
 
14603
14665
  .wrapper.warning,.wrapper.level-medium {
14604
14666
  --bg-color: var(--alert-warning-color);
14605
- --blink-on: var(--warning-blink-on);
14606
14667
  color: var(--on-warning-active-color);
14607
14668
  }
14608
14669
 
14609
14670
  .wrapper.caution,.wrapper.level-low {
14610
14671
  --bg-color: var(--alert-caution-color);
14611
- --blink-on: 1;
14612
14672
  color: var(--on-caution-active-color);
14613
14673
  }
14614
14674
 
14615
- .wrapper.level-low {
14616
- --blink-on: var(--low-blink-on);
14617
- }
14618
-
14619
14675
  .wrapper.level-critical {
14620
14676
  --bg-color: var(--critical-enabled-background-color);
14621
- --blink-on: var(--critical-blink-on);
14622
14677
  color: var(--on-critical-active-color);
14623
14678
  }
14624
14679
 
@@ -14673,7 +14728,7 @@ const compentStyle$1g = i$7`* {
14673
14728
  width: calc(
14674
14729
  var(--ui-components-button-border-radius) + var(--thickness) + 0.5px
14675
14730
  );
14676
- top: 0;
14731
+ top: calc(-1 * var(--flap-grow));
14677
14732
  left: calc(
14678
14733
  -1 * var(--ui-components-button-border-radius) - var(--thickness)
14679
14734
  );
@@ -14686,15 +14741,11 @@ const compentStyle$1g = i$7`* {
14686
14741
  );
14687
14742
  }
14688
14743
 
14689
- .unacked-active .up:is(.flap .mask) {
14690
- top: calc(-1 * var(--blink-width-dynamic));
14691
- }
14692
-
14693
14744
  .down:is(.flap .mask) {
14694
14745
  width: calc(
14695
14746
  var(--ui-components-button-border-radius) + var(--thickness) + 0.5px
14696
14747
  );
14697
- bottom: 0;
14748
+ bottom: calc(-1 * var(--flap-grow));
14698
14749
  left: calc(
14699
14750
  -1 * var(--ui-components-button-border-radius) - var(--thickness)
14700
14751
  );
@@ -14707,10 +14758,6 @@ const compentStyle$1g = i$7`* {
14707
14758
  );
14708
14759
  }
14709
14760
 
14710
- .unacked-active .down:is(.flap .mask) {
14711
- bottom: calc(-1 * var(--blink-width-dynamic));
14712
- }
14713
-
14714
14761
  .left:is(.flap .mask) {
14715
14762
  height: calc(
14716
14763
  var(--ui-components-button-border-radius) + var(--thickness) + 0.5px
@@ -14718,7 +14765,7 @@ const compentStyle$1g = i$7`* {
14718
14765
  top: calc(
14719
14766
  -1 * var(--ui-components-button-border-radius) - var(--thickness)
14720
14767
  );
14721
- left: 0;
14768
+ left: calc(-1 * var(--flap-grow));
14722
14769
  clip-path: polygon(
14723
14770
  0 0,
14724
14771
  0 100%,
@@ -14728,10 +14775,6 @@ const compentStyle$1g = i$7`* {
14728
14775
  );
14729
14776
  }
14730
14777
 
14731
- .unacked-active .left:is(.flap .mask) {
14732
- left: calc(-1 * var(--blink-width-dynamic));
14733
- }
14734
-
14735
14778
  .top .left:is(.flap .mask) {
14736
14779
  top: unset;
14737
14780
  bottom: calc(
@@ -14753,7 +14796,7 @@ const compentStyle$1g = i$7`* {
14753
14796
  top: calc(
14754
14797
  -1 * var(--ui-components-button-border-radius) - var(--thickness)
14755
14798
  );
14756
- right: 0;
14799
+ right: calc(-1 * var(--flap-grow));
14757
14800
  clip-path: polygon(
14758
14801
  100% 0,
14759
14802
  100% 100%,
@@ -14777,10 +14820,6 @@ const compentStyle$1g = i$7`* {
14777
14820
  );
14778
14821
  }
14779
14822
 
14780
- .unacked-active .right:is(.flap .mask) {
14781
- right: calc(-1 * var(--blink-width-dynamic));
14782
- }
14783
-
14784
14823
  .flap.large {
14785
14824
  flex-direction: column;
14786
14825
  top: calc(-1 * var(--thickness));
@@ -14878,8 +14917,35 @@ const compentStyle$1g = i$7`* {
14878
14917
  overflow: hidden;
14879
14918
  }
14880
14919
 
14881
- .unacked-active .flap {
14882
- outline: var(--bg-color) solid var(--blink-width-dynamic);
14920
+ /* Grows the flap outward with the outline, never toward the content: shifted
14921
+ copies leave the inner edge where it is (an outline would cross it). */
14922
+
14923
+ .flap.small,
14924
+ .flap.large {
14925
+ box-shadow:
14926
+ var(--flap-grow) 0 0 0 var(--bg-color),
14927
+ 0 calc(-1 * var(--flap-grow)) 0 0 var(--bg-color),
14928
+ 0 var(--flap-grow) 0 0 var(--bg-color),
14929
+ var(--flap-grow) calc(-1 * var(--flap-grow)) 0 0 var(--bg-color),
14930
+ var(--flap-grow) var(--flap-grow) 0 0 var(--bg-color);
14931
+ }
14932
+
14933
+ .flap.bottom {
14934
+ box-shadow:
14935
+ 0 var(--flap-grow) 0 0 var(--bg-color),
14936
+ calc(-1 * var(--flap-grow)) 0 0 0 var(--bg-color),
14937
+ var(--flap-grow) 0 0 0 var(--bg-color),
14938
+ calc(-1 * var(--flap-grow)) var(--flap-grow) 0 0 var(--bg-color),
14939
+ var(--flap-grow) var(--flap-grow) 0 0 var(--bg-color);
14940
+ }
14941
+
14942
+ .flap.top {
14943
+ box-shadow:
14944
+ 0 calc(-1 * var(--flap-grow)) 0 0 var(--bg-color),
14945
+ calc(-1 * var(--flap-grow)) 0 0 0 var(--bg-color),
14946
+ var(--flap-grow) 0 0 0 var(--bg-color),
14947
+ calc(-1 * var(--flap-grow)) calc(-1 * var(--flap-grow)) 0 0 var(--bg-color),
14948
+ var(--flap-grow) calc(-1 * var(--flap-grow)) 0 0 var(--bg-color);
14883
14949
  }
14884
14950
 
14885
14951
  ::slotted([slot="label"]) {
@@ -14894,6 +14960,24 @@ const compentStyle$1g = i$7`* {
14894
14960
  display: block;
14895
14961
  flex-shrink: 0;
14896
14962
  }
14963
+
14964
+ .dash {
14965
+ /* Overridden inline per render from the measured thickness. */
14966
+ --dash-pad: 0px;
14967
+ position: absolute;
14968
+ top: calc(-1 * var(--dash-pad));
14969
+ left: calc(-1 * var(--dash-pad));
14970
+ overflow: visible;
14971
+ pointer-events: none;
14972
+ fill: none;
14973
+ stroke: var(--bg-color);
14974
+ stroke-dasharray: 12 6;
14975
+ }
14976
+
14977
+ .dash path {
14978
+ /* Animated on the one path: a wider second path would drift its dashes. */
14979
+ stroke-width: calc(var(--thickness) + var(--blink-width-dynamic));
14980
+ }
14897
14981
  `;
14898
14982
  var __defProp$Ax = Object.defineProperty;
14899
14983
  var __getOwnPropDesc$AB = Object.getOwnPropertyDescriptor;
@@ -15151,18 +15235,34 @@ function requiresAcknowledgement(type) {
15151
15235
  AlertType.LevelLow
15152
15236
  ].includes(type);
15153
15237
  }
15154
- function supportsBlinking(type, acknowledged) {
15155
- if (acknowledged) {
15156
- return false;
15238
+ var AlertFlashPhase = /* @__PURE__ */ ((AlertFlashPhase2) => {
15239
+ AlertFlashPhase2["Active"] = "active";
15240
+ AlertFlashPhase2["Rectified"] = "rectified";
15241
+ return AlertFlashPhase2;
15242
+ })(AlertFlashPhase || {});
15243
+ function resolveFlashingSpeed(speed, type, phase = "active") {
15244
+ if (speed !== FlashingSpeed.Default) {
15245
+ return speed;
15246
+ }
15247
+ if (type === AlertType.Caution || type === AlertType.LevelDiagnostic) {
15248
+ return FlashingSpeed.Fixed;
15249
+ }
15250
+ if (phase === "rectified") {
15251
+ return FlashingSpeed.VerySlow;
15252
+ }
15253
+ switch (type) {
15254
+ case AlertType.LevelCritical:
15255
+ case AlertType.Alarm:
15256
+ case AlertType.LevelHigh:
15257
+ return FlashingSpeed.Fast;
15258
+ case AlertType.Warning:
15259
+ case AlertType.LevelMedium:
15260
+ return FlashingSpeed.Slow;
15261
+ case AlertType.LevelLow:
15262
+ return FlashingSpeed.VerySlow;
15263
+ default:
15264
+ return FlashingSpeed.Fixed;
15157
15265
  }
15158
- return [
15159
- AlertType.Alarm,
15160
- AlertType.Warning,
15161
- AlertType.LevelCritical,
15162
- AlertType.LevelHigh,
15163
- AlertType.LevelMedium,
15164
- AlertType.LevelLow
15165
- ].includes(type);
15166
15266
  }
15167
15267
  function getAlertBadgeComponent(type) {
15168
15268
  switch (type) {
@@ -15208,22 +15308,6 @@ function getAlertTwotoneComponent(type) {
15208
15308
  return "obi-alerts-alarm-twotone";
15209
15309
  }
15210
15310
  }
15211
- function getAlertBlinkMode(type) {
15212
- switch (type) {
15213
- case AlertType.LevelCritical:
15214
- return "critical";
15215
- case AlertType.Warning:
15216
- case AlertType.LevelMedium:
15217
- return "warning";
15218
- case AlertType.Caution:
15219
- case AlertType.LevelLow:
15220
- return "low";
15221
- case AlertType.Alarm:
15222
- case AlertType.LevelHigh:
15223
- default:
15224
- return "alarm";
15225
- }
15226
- }
15227
15311
  function getBamAlertTypeForBlinking(type) {
15228
15312
  switch (type) {
15229
15313
  case AlertType.LevelCritical:
@@ -15247,41 +15331,104 @@ function usesAlarmNoAckIcon(type) {
15247
15331
  AlertType.LevelHigh
15248
15332
  ].includes(type);
15249
15333
  }
15250
- const CRITICAL_PERIOD = 1e3;
15251
- const ALARM_PERIOD = 2e3;
15252
- const WARNING_PERIOD = 4e3;
15253
- const LOW_PERIOD = 8e3;
15254
- function blinkingInstall(el, period, label) {
15255
- const anim = el.animate(
15256
- [
15257
- { [label + "-on"]: 1, [label + "-off"]: 0 },
15258
- { [label + "-on"]: 0, [label + "-off"]: 1 }
15259
- ],
15260
- { duration: period, iterations: Infinity, easing: "steps(2, jump-none)" }
15261
- );
15334
+ const FLASH_OFF_MS = 400;
15335
+ const FLASH_ON_MS = {
15336
+ [FlashingSpeed.Fast]: 400,
15337
+ [FlashingSpeed.Slow]: 1200,
15338
+ [FlashingSpeed.VerySlow]: 2800
15339
+ };
15340
+ [
15341
+ FlashingSpeed.Fast,
15342
+ FlashingSpeed.Slow,
15343
+ FlashingSpeed.VerySlow
15344
+ ];
15345
+ function flashPeriodMs(tempo) {
15346
+ return FLASH_ON_MS[tempo] + FLASH_OFF_MS;
15347
+ }
15348
+ function flashVariable(tempo, phase) {
15349
+ return `--flash-${tempo}-${phase}`;
15350
+ }
15351
+ function installFlashing(el, tempo) {
15352
+ const on2 = flashVariable(tempo, "on");
15353
+ const off2 = flashVariable(tempo, "off");
15354
+ const period = flashPeriodMs(tempo);
15355
+ const frames = [
15356
+ { [on2]: 1, [off2]: 0, easing: "step-end" },
15357
+ {
15358
+ [on2]: 0,
15359
+ [off2]: 1,
15360
+ offset: FLASH_ON_MS[tempo] / period,
15361
+ easing: "step-end"
15362
+ },
15363
+ { [on2]: 0, [off2]: 1 }
15364
+ ];
15365
+ const anim = el.animate(frames, { duration: period, iterations: Infinity });
15262
15366
  anim.startTime = 0;
15263
15367
  return () => anim.cancel();
15264
15368
  }
15265
- function blinkingCritical(el) {
15266
- return blinkingInstall(el, CRITICAL_PERIOD, "--critical-blink");
15267
- }
15268
- function blinkingAlarm(el) {
15269
- return blinkingInstall(el, ALARM_PERIOD, "--alarm-blink");
15270
- }
15271
- function blinkingWarning(el) {
15272
- return blinkingInstall(el, WARNING_PERIOD, "--warning-blink");
15273
- }
15274
- function blinkingLow(el) {
15275
- return blinkingInstall(el, LOW_PERIOD, "--low-blink");
15369
+ class FlashingController {
15370
+ constructor(host, resolve2) {
15371
+ this.host = host;
15372
+ this.resolve = resolve2;
15373
+ host.addController(this);
15374
+ }
15375
+ get tempo() {
15376
+ return this.installed;
15377
+ }
15378
+ hostConnected() {
15379
+ if (this.host.hasUpdated) {
15380
+ this.sync();
15381
+ }
15382
+ }
15383
+ hostUpdated() {
15384
+ this.sync();
15385
+ }
15386
+ hostDisconnected() {
15387
+ this.stop();
15388
+ }
15389
+ sync() {
15390
+ const wanted = this.host.isConnected ? this.resolve() : FlashingSpeed.Fixed;
15391
+ if (wanted === FlashingSpeed.Fixed) {
15392
+ this.stop();
15393
+ return;
15394
+ }
15395
+ if (wanted === this.installed) {
15396
+ return;
15397
+ }
15398
+ this.stop();
15399
+ this.cancel = installFlashing(this.host, wanted);
15400
+ this.installed = wanted;
15401
+ }
15402
+ stop() {
15403
+ this.cancel?.();
15404
+ this.cancel = void 0;
15405
+ this.installed = void 0;
15406
+ }
15276
15407
  }
15277
- function blinkingAll(el) {
15278
- const animes = [
15279
- blinkingCritical(el),
15280
- blinkingAlarm(el),
15281
- blinkingWarning(el),
15282
- blinkingLow(el)
15283
- ];
15284
- return () => animes.forEach((anim) => anim());
15408
+ function roundedRectPath({
15409
+ x: x2,
15410
+ y: y3,
15411
+ width,
15412
+ height,
15413
+ radii
15414
+ }) {
15415
+ const max2 = Math.min(width, height) / 2;
15416
+ const [tl, tr, br, bl] = radii.map((r2) => Math.max(0, Math.min(r2, max2)));
15417
+ const right = x2 + width;
15418
+ const bottom = y3 + height;
15419
+ const arc = (r2, endX, endY) => r2 > 0 ? `A${r2} ${r2} 0 0 1 ${endX} ${endY}` : "";
15420
+ return [
15421
+ `M${x2 + tl} ${y3}`,
15422
+ `H${right - tr}`,
15423
+ arc(tr, right, y3 + tr),
15424
+ `V${bottom - br}`,
15425
+ arc(br, right - br, bottom),
15426
+ `H${x2 + bl}`,
15427
+ arc(bl, x2, bottom - bl),
15428
+ `V${y3 + tl}`,
15429
+ arc(tl, x2 + tl, y3),
15430
+ "Z"
15431
+ ].filter(Boolean).join(" ");
15285
15432
  }
15286
15433
  var __defProp$At = Object.defineProperty;
15287
15434
  var __getOwnPropDesc$Aw = Object.getOwnPropertyDescriptor;
@@ -15312,6 +15459,10 @@ var ObcAlertFrameMode = /* @__PURE__ */ ((ObcAlertFrameMode2) => {
15312
15459
  ObcAlertFrameMode2["unackedRectified"] = "unacked-rectified";
15313
15460
  return ObcAlertFrameMode2;
15314
15461
  })(ObcAlertFrameMode || {});
15462
+ const DASH_FLASH_GROWTH_PX = 2;
15463
+ function sameDashBox(a2, b2) {
15464
+ return b2 !== void 0 && a2.width === b2.width && a2.height === b2.height && a2.thickness === b2.thickness && a2.radii.every((r2, i4) => r2 === b2.radii[i4]);
15465
+ }
15315
15466
  let ObcAlertFrame = class extends i$4 {
15316
15467
  constructor() {
15317
15468
  super(...arguments);
@@ -15319,6 +15470,34 @@ let ObcAlertFrame = class extends i$4 {
15319
15470
  this.thickness = "small";
15320
15471
  this.status = AlertType.Alarm;
15321
15472
  this.mode = "acked-active";
15473
+ this.flashingSpeed = FlashingSpeed.Default;
15474
+ this.flashEffect = "outline";
15475
+ this.flashing = new FlashingController(
15476
+ this,
15477
+ () => this.resolvedFlashingSpeed
15478
+ );
15479
+ this.measureDash = () => {
15480
+ const wrapper = this.wrapper;
15481
+ if (!wrapper) {
15482
+ return;
15483
+ }
15484
+ const style2 = getComputedStyle(wrapper);
15485
+ const px = (value) => parseFloat(value) || 0;
15486
+ const box = {
15487
+ width: wrapper.offsetWidth,
15488
+ height: wrapper.offsetHeight,
15489
+ thickness: px(style2.getPropertyValue("--thickness")),
15490
+ radii: [
15491
+ px(style2.borderTopLeftRadius),
15492
+ px(style2.borderTopRightRadius),
15493
+ px(style2.borderBottomRightRadius),
15494
+ px(style2.borderBottomLeftRadius)
15495
+ ]
15496
+ };
15497
+ if (!sameDashBox(box, this.dashBox)) {
15498
+ this.dashBox = box;
15499
+ }
15500
+ };
15322
15501
  this.wrapContent = false;
15323
15502
  this.fullWidth = false;
15324
15503
  this.sharpEdgeTopLeft = false;
@@ -15329,6 +15508,79 @@ let ObcAlertFrame = class extends i$4 {
15329
15508
  this.showIcon = false;
15330
15509
  this.showAlertCategoryIcon = true;
15331
15510
  }
15511
+ connectedCallback() {
15512
+ super.connectedCallback();
15513
+ if (this.hasUpdated) {
15514
+ this.requestUpdate();
15515
+ }
15516
+ }
15517
+ updated() {
15518
+ const wantsDash = this.mode === "unacked-rectified" && this.isConnected;
15519
+ if (wantsDash && !this.dashObserver && this.wrapper) {
15520
+ this.dashObserver = new ResizeObserver(this.measureDash);
15521
+ this.dashObserver.observe(this.wrapper);
15522
+ }
15523
+ if (wantsDash) {
15524
+ this.measureDash();
15525
+ }
15526
+ if (!wantsDash && this.dashObserver) {
15527
+ this.dashObserver.disconnect();
15528
+ this.dashObserver = void 0;
15529
+ this.dashBox = void 0;
15530
+ }
15531
+ }
15532
+ disconnectedCallback() {
15533
+ super.disconnectedCallback();
15534
+ this.dashObserver?.disconnect();
15535
+ this.dashObserver = void 0;
15536
+ }
15537
+ renderDash() {
15538
+ const box = this.dashBox;
15539
+ if (this.mode !== "unacked-rectified" || !box) {
15540
+ return A;
15541
+ }
15542
+ const pad = box.thickness + DASH_FLASH_GROWTH_PX;
15543
+ const centreline = {
15544
+ x: pad - box.thickness / 2,
15545
+ y: pad - box.thickness / 2,
15546
+ width: box.width + box.thickness,
15547
+ height: box.height + box.thickness,
15548
+ // A radius of 0 is a sharp edge and must stay square.
15549
+ radii: box.radii.map(
15550
+ (r2) => r2 > 0 ? r2 + box.thickness / 2 : 0
15551
+ )
15552
+ };
15553
+ const width = box.width + 2 * pad;
15554
+ const height = box.height + 2 * pad;
15555
+ return b`<svg
15556
+ class="dash"
15557
+ aria-hidden="true"
15558
+ width=${width}
15559
+ height=${height}
15560
+ viewBox="0 0 ${width} ${height}"
15561
+ style="--dash-pad: ${pad}px"
15562
+ >
15563
+ <path d=${roundedRectPath(centreline)}></path>
15564
+ </svg>`;
15565
+ }
15566
+ get resolvedFlashingSpeed() {
15567
+ switch (this.mode) {
15568
+ case "unacked-active":
15569
+ return resolveFlashingSpeed(
15570
+ this.flashingSpeed,
15571
+ this.status,
15572
+ AlertFlashPhase.Active
15573
+ );
15574
+ case "unacked-rectified":
15575
+ return resolveFlashingSpeed(
15576
+ this.flashingSpeed,
15577
+ this.status,
15578
+ AlertFlashPhase.Rectified
15579
+ );
15580
+ default:
15581
+ return FlashingSpeed.Fixed;
15582
+ }
15583
+ }
15332
15584
  render() {
15333
15585
  return b`
15334
15586
  <div
@@ -15344,37 +15596,16 @@ let ObcAlertFrame = class extends i$4 {
15344
15596
  "sharp-edge-top-right": this.sharpEdgeTopRight,
15345
15597
  "sharp-edge-bottom-left": this.sharpEdgeBottomLeft,
15346
15598
  "sharp-edge-bottom-right": this.sharpEdgeBottomRight,
15347
- [this.mode]: true
15599
+ [this.mode]: true,
15600
+ ["flash-" + this.resolvedFlashingSpeed]: true,
15601
+ ["flash-effect-" + this.flashEffect]: true
15348
15602
  })}
15349
15603
  >
15350
15604
  <slot></slot>
15351
- ${this.flap()}
15605
+ ${this.renderDash()} ${this.flap()}
15352
15606
  </div>
15353
15607
  `;
15354
15608
  }
15355
- syncBlinking() {
15356
- if (this.mode !== "unacked-active" && this._blinkAnimationCancel) {
15357
- this._blinkAnimationCancel();
15358
- this._blinkAnimationCancel = void 0;
15359
- }
15360
- if (this.mode === "unacked-active" && !this._blinkAnimationCancel) {
15361
- this._blinkAnimationCancel = blinkingAll(this);
15362
- }
15363
- }
15364
- connectedCallback() {
15365
- super.connectedCallback();
15366
- if (this.hasUpdated) {
15367
- this.syncBlinking();
15368
- }
15369
- }
15370
- updated() {
15371
- this.syncBlinking();
15372
- }
15373
- disconnectedCallback() {
15374
- super.disconnectedCallback();
15375
- this._blinkAnimationCancel?.();
15376
- this._blinkAnimationCancel = void 0;
15377
- }
15378
15609
  flap() {
15379
15610
  if (this.type === "regular") {
15380
15611
  return A;
@@ -15453,6 +15684,18 @@ __decorateClass$AE([
15453
15684
  __decorateClass$AE([
15454
15685
  n$3({ type: String })
15455
15686
  ], ObcAlertFrame.prototype, "mode", 2);
15687
+ __decorateClass$AE([
15688
+ n$3({ type: String })
15689
+ ], ObcAlertFrame.prototype, "flashingSpeed", 2);
15690
+ __decorateClass$AE([
15691
+ n$3({ type: String })
15692
+ ], ObcAlertFrame.prototype, "flashEffect", 2);
15693
+ __decorateClass$AE([
15694
+ r$3()
15695
+ ], ObcAlertFrame.prototype, "dashBox", 2);
15696
+ __decorateClass$AE([
15697
+ e$3(".wrapper")
15698
+ ], ObcAlertFrame.prototype, "wrapper", 2);
15456
15699
  __decorateClass$AE([
15457
15700
  n$3({ type: Boolean, reflect: true })
15458
15701
  ], ObcAlertFrame.prototype, "wrapContent", 2);
@@ -15492,6 +15735,7 @@ function wrapWithAlertFrame(options, content, fullWidth = false) {
15492
15735
  .thickness=${options.thickness ?? "small"}
15493
15736
  .status=${options.status ?? AlertType.Alarm}
15494
15737
  .mode=${options.mode ?? "acked-active"}
15738
+ .flashingSpeed=${options.flashingSpeed ?? FlashingSpeed.Default}
15495
15739
  .showIcon=${options.showIcon ?? false}
15496
15740
  .showAlertCategoryIcon=${options.showAlertCategoryIcon ?? true}
15497
15741
  .wrapContent=${true}
@@ -35092,6 +35336,34 @@ function observeLabelThreshold(target, isAboveThreshold, callbacks) {
35092
35336
  observer.observe(target);
35093
35337
  return observer;
35094
35338
  }
35339
+ function rangeLabelFontString(font2) {
35340
+ return `${font2.weight} ${font2.sizePx}px ${font2.family}`;
35341
+ }
35342
+ function rangeLabelLineHeight(font2) {
35343
+ return Math.round(font2.sizePx * 1.2);
35344
+ }
35345
+ function formatRangeValue(value, min2, max2) {
35346
+ const decimals = Number.isInteger(min2) && Number.isInteger(max2) ? 0 : 1;
35347
+ return value.toFixed(decimals);
35348
+ }
35349
+ function yRangeLabelValues(min2, max2) {
35350
+ return min2 < 0 && max2 > 0 ? [min2, 0, max2] : [min2, max2];
35351
+ }
35352
+ const SIDE_GAP = 8;
35353
+ const BOTTOM_GAP = 4;
35354
+ function measureRangeLabelGutters(ctx, font2, yTexts, xTexts) {
35355
+ ctx.save();
35356
+ ctx.font = rangeLabelFontString(font2);
35357
+ const widest = yTexts.reduce(
35358
+ (width, text) => Math.max(width, ctx.measureText(text).width),
35359
+ 0
35360
+ );
35361
+ ctx.restore();
35362
+ return {
35363
+ side: yTexts.length ? Math.ceil(widest) + SIDE_GAP : 0,
35364
+ bottom: xTexts.length ? rangeLabelLineHeight(font2) + BOTTOM_GAP : 0
35365
+ };
35366
+ }
35095
35367
  var TickmarkType$1 = /* @__PURE__ */ ((TickmarkType2) => {
35096
35368
  TickmarkType2["zeroLineThick"] = "zeroLineThick";
35097
35369
  TickmarkType2["zeroLine"] = "zeroLine";
@@ -35728,6 +36000,28 @@ function isOutwardPositive(config) {
35728
36000
  function rangeIncludesZero(minValue, maxValue) {
35729
36001
  return minValue <= 0 && maxValue >= 0;
35730
36002
  }
36003
+ function resolveMainTickmarkValues(config) {
36004
+ const source = config.mainTickmarks?.length ? config.mainTickmarks : [config.minValue, 0, config.maxValue];
36005
+ return [...new Set(source)].filter((v2) => v2 >= config.minValue && v2 <= config.maxValue).sort((a2, b2) => a2 - b2);
36006
+ }
36007
+ const EXTERNAL_SCALE_MAX_TICKS = 1e3;
36008
+ const DENSE_LADDER_WARNINGS_KEPT = 64;
36009
+ const warnedDenseLadders = /* @__PURE__ */ new Set();
36010
+ function isLadderTooDense(config, interval) {
36011
+ const count = Math.floor((config.maxValue - config.minValue) / interval) + 1;
36012
+ if (!(count > EXTERNAL_SCALE_MAX_TICKS)) return false;
36013
+ const key = `${config.minValue}/${config.maxValue}/${interval}`;
36014
+ if (!warnedDenseLadders.has(key)) {
36015
+ if (warnedDenseLadders.size >= DENSE_LADDER_WARNINGS_KEPT) {
36016
+ warnedDenseLadders.clear();
36017
+ }
36018
+ warnedDenseLadders.add(key);
36019
+ console.warn(
36020
+ `[external-scale] tick interval ${interval} over the range ${config.minValue}…${config.maxValue} is ${count} ticks; the ladder is not drawn (limit ${EXTERNAL_SCALE_MAX_TICKS}). A range in epoch milliseconds needs an interval in milliseconds.`
36021
+ );
36022
+ }
36023
+ return true;
36024
+ }
35731
36025
  function calculateAtSetpoint(config) {
35732
36026
  const isTouching = config.touching ?? false;
35733
36027
  return computeAtSetpoint({
@@ -35842,6 +36136,7 @@ function generateTickmarksAtInterval(config, interval, perpStart, perpLen, skipV
35842
36136
  const svgs = [];
35843
36137
  const values = [];
35844
36138
  if (interval <= 0 || !Number.isFinite(interval)) return { svgs, values };
36139
+ if (isLadderTooDense(config, interval)) return { svgs, values };
35845
36140
  const includesZero = rangeIncludesZero(config.minValue, config.maxValue);
35846
36141
  const pushTick = (v2) => {
35847
36142
  if (skipValues.includes(v2)) return;
@@ -35890,9 +36185,7 @@ function generateTickmarks$1(config) {
35890
36185
  const start = config.frameStyle === "flat" ? base : tickmarksStart;
35891
36186
  const mainLen = config.frameStyle === "flat" ? main + 4 : main;
35892
36187
  const dirLen = isOutwardPositive(config) ? mainLen : -mainLen;
35893
- const mainTickValues = config.mainTickmarks.length > 0 ? config.mainTickmarks : [config.minValue, 0, config.maxValue];
35894
- for (const value of mainTickValues) {
35895
- if (value < config.minValue || value > config.maxValue) continue;
36188
+ for (const value of resolveMainTickmarkValues(config)) {
35896
36189
  if (config.scaleBackground && (value === config.minValue || value === config.maxValue)) {
35897
36190
  skipValues.push(value);
35898
36191
  continue;
@@ -35937,36 +36230,47 @@ function generateTickmarks$1(config) {
35937
36230
  return svgs;
35938
36231
  }
35939
36232
  function generateLabels(config) {
35940
- if (!config.labels || config.primaryTickmarkInterval === void 0) return [];
35941
- const interval = config.primaryTickmarkInterval;
35942
- if (interval <= 0 || !Number.isFinite(interval)) return [];
36233
+ if (!config.labels) return [];
35943
36234
  const fontFamily = "var(--font-family-main)";
35944
36235
  const fontColor = "var(--instrument-tick-mark-label-secondary-color)";
35945
36236
  const fontSize = "calc(var(--global-typography-ui-label-font-size) / var(--scale, 1))";
35946
36237
  const base = tickBasePerp(config);
35947
36238
  const effectiveTickThickness = computeExternalScaleEffectiveTickThickness(config);
35948
36239
  const labelPos = isOutwardPositive(config) ? base + (config.hasScale ? effectiveTickThickness : 0) + labelGap() : base - (config.hasScale ? effectiveTickThickness : 0) - labelGap();
35949
- const includesZero = rangeIncludesZero(config.minValue, config.maxValue);
35950
36240
  const labels = [];
35951
- const push = (v2) => {
36241
+ const push = (v2, edge) => {
35952
36242
  const main = valueToMainAxis(config, v2);
35953
36243
  if (isVertical(config)) {
35954
36244
  const x22 = labelPos;
35955
36245
  const y22 = main;
35956
- const anchor = isOutwardPositive(config) ? "start" : "end";
36246
+ const anchor2 = isOutwardPositive(config) ? "start" : "end";
36247
+ const baseline2 = edge?.baseline ?? "middle";
35957
36248
  labels.push(
35958
- w`<text x=${x22} y=${y22} text-anchor=${anchor} dominant-baseline="middle" font-family=${fontFamily} style="font-size: ${fontSize}" fill=${fontColor}>${v2}</text>`
36249
+ w`<text x=${x22} y=${y22} text-anchor=${anchor2} dominant-baseline=${baseline2} font-family=${fontFamily} style="font-size: ${fontSize}" fill=${fontColor}>${v2}</text>`
35959
36250
  );
35960
36251
  return;
35961
36252
  }
35962
36253
  const y3 = labelPos;
35963
36254
  const x2 = main;
35964
36255
  const baseline = isOutwardPositive(config) ? "hanging" : "auto";
36256
+ const anchor = edge?.anchor ?? "middle";
35965
36257
  labels.push(
35966
- w`<text x=${x2} y=${y3} text-anchor="middle" dominant-baseline=${baseline} font-family=${fontFamily} style="font-size: ${fontSize}" fill=${fontColor}>${v2}</text>`
36258
+ w`<text x=${x2} y=${y3} text-anchor=${anchor} dominant-baseline=${baseline} font-family=${fontFamily} style="font-size: ${fontSize}" fill=${fontColor}>${v2}</text>`
35967
36259
  );
35968
36260
  };
35969
- if (includesZero) {
36261
+ if (config.mainTickmarkLabels) {
36262
+ for (const v2 of resolveMainTickmarkValues(config)) {
36263
+ const edge = v2 === config.minValue ? { anchor: "start", baseline: "auto" } : v2 === config.maxValue ? { anchor: "end", baseline: "hanging" } : void 0;
36264
+ push(v2, edge);
36265
+ }
36266
+ return labels;
36267
+ }
36268
+ const interval = config.primaryTickmarkInterval;
36269
+ if (interval === void 0 || interval <= 0 || !Number.isFinite(interval)) {
36270
+ return [];
36271
+ }
36272
+ if (isLadderTooDense(config, interval)) return [];
36273
+ if (rangeIncludesZero(config.minValue, config.maxValue)) {
35970
36274
  for (let v2 = 0; v2 <= config.maxValue; v2 += interval) push(v2);
35971
36275
  for (let v2 = -interval; v2 >= config.minValue; v2 -= interval) push(v2);
35972
36276
  } else {
@@ -36979,6 +37283,7 @@ const LINE_GRAPH_WATCHED_PROP_NAMES = [
36979
37283
  "xAxisType",
36980
37284
  "yAxisPosition",
36981
37285
  "yAxes",
37286
+ "xAxis",
36982
37287
  "showGrid",
36983
37288
  "showGridX",
36984
37289
  "showGridY",
@@ -37003,14 +37308,17 @@ const LINE_GRAPH_WATCHED_PROP_NAMES = [
37003
37308
  "height",
37004
37309
  "fixedAspectRatioScaling",
37005
37310
  // Triggers responsive mode change
37006
- "hasLabelPadding"
37311
+ "hasLabelPadding",
37007
37312
  // Toggles edge-to-edge rendering and label visibility
37313
+ "rangeLabels"
37008
37314
  ];
37009
37315
  const LINE_GRAPH_RECREATE_PROP_NAMES = [
37010
37316
  "showDebugOverlay",
37011
37317
  "width",
37012
37318
  "height",
37013
- "fixedAspectRatioScaling"
37319
+ "fixedAspectRatioScaling",
37320
+ "rangeLabels"
37321
+ // Adds or removes the range-labels plugin
37014
37322
  ];
37015
37323
  const LINE_GRAPH_DIMENSION_PROP_NAMES = [
37016
37324
  "width",
@@ -37033,11 +37341,14 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37033
37341
  this.xAxisType = "category";
37034
37342
  this.yAxisPosition = "left";
37035
37343
  this.yAxes = void 0;
37344
+ this.xAxis = void 0;
37036
37345
  this.showGrid = false;
37037
37346
  this.showGridX = false;
37038
37347
  this.showGridY = false;
37039
37348
  this.showTickMarks = false;
37040
37349
  this.hasLabelPadding = true;
37350
+ this.rangeLabels = "none";
37351
+ this.warnedDateDisplayScale = false;
37041
37352
  this.DEFAULT_TENSION = 0.4;
37042
37353
  this.POINT_RADIUS = 3;
37043
37354
  this.showPoints = false;
@@ -37060,6 +37371,10 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37060
37371
  this.currentBorderRadiusPx = 8;
37061
37372
  this.computedWidth = 480;
37062
37373
  this.computedHeight = 320;
37374
+ this.savedLabelThickness = /* @__PURE__ */ new WeakMap();
37375
+ this.savedMainTickmarkLabels = /* @__PURE__ */ new WeakMap();
37376
+ this.lastRangeLabels = [];
37377
+ this.rangeLabelCache = { y: [], x: [] };
37063
37378
  this.updateBorderRadius = () => {
37064
37379
  if (!this.canvasEl) return;
37065
37380
  let next;
@@ -37099,10 +37414,25 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37099
37414
  }, 16);
37100
37415
  };
37101
37416
  }
37417
+ /** @internal - The y side wants range labels; an edge-to-edge chart never does. */
37418
+ get rangeLabelsY() {
37419
+ return this.hasLabelPadding && (this.rangeLabels === "y" || this.rangeLabels === "xy");
37420
+ }
37421
+ /** @internal - The x side wants range labels; an edge-to-edge chart never does. */
37422
+ get rangeLabelsX() {
37423
+ return this.hasLabelPadding && (this.rangeLabels === "x" || this.rangeLabels === "xy");
37424
+ }
37102
37425
  /** @internal - True when the x-axis positions points by numeric value. */
37103
37426
  get isNumericXAxis() {
37104
37427
  return this.xAxisType === "time" || this.xAxisType === "number";
37105
37428
  }
37429
+ /**
37430
+ * Id of the y scale a dataset lands on when it names none. Chart.js would
37431
+ * otherwise add a default `y` scale next to the configured ones and draw it.
37432
+ */
37433
+ get primaryYAxisId() {
37434
+ return this.yAxes?.length ? this.yAxes[0].id ?? "y0" : "y";
37435
+ }
37106
37436
  /** @internal - Normalization mode for the current x-axis type. */
37107
37437
  get xValueMode() {
37108
37438
  return this.xAxisType === "number" ? XValueMode.number : XValueMode.time;
@@ -37141,37 +37471,221 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37141
37471
  throw new Error("shouldStack() must be implemented in subclass");
37142
37472
  }
37143
37473
  /**
37144
- * Compute which corners should be rounded based on borderRadiusPosition and
37145
- * which external scales are present.
37146
- *
37147
- * Logic:
37148
- * - Opposite scales (left+right OR top+bottom) → no rounding (middleChild behavior)
37149
- * - Perpendicular scales (e.g., right+bottom):
37150
- * - innerFirstChild → round corner adjacent to both scales
37151
- * - outerLastChild → round free corner opposite to scales
37152
- * - Single-side scales:
37153
- * - When external scale is on RIGHT, chart is on LEFT
37154
- * - innerFirstChild → round LEFT corners (top-left + bottom-left)
37155
- * - outerLastChild → round RIGHT corners (top-right + bottom-right)
37156
- * - When external scale is on LEFT, chart is on RIGHT (opposite)
37157
- * - When external scale is on TOP, chart is on BOTTOM
37158
- * - innerFirstChild → round BOTTOM corners (bottom-left + bottom-right)
37159
- * - outerLastChild → round TOP corners (top-left + top-right)
37160
- * - When external scale is on BOTTOM, chart is on TOP (opposite)
37161
- * - middleChild → no rounding
37162
- */
37163
- /**
37164
- * Check if a slotted scale element is actually visible (renders content).
37165
- * For bar-vertical/bar-horizontal elements, checks hasBar and hasScale properties.
37474
+ * Label band a slotted scale needs for its compact labels, in the scale's
37475
+ * own viewBox units. The scale prints the raw values, so those are what is
37476
+ * measured; the x band is one text line.
37166
37477
  */
37167
- hasVisibleScale(side) {
37168
- const slotMap = {
37478
+ compactLabelThickness(axis) {
37479
+ const context = this.canvasEl?.getContext("2d");
37480
+ if (!context) return void 0;
37481
+ const font2 = this.rangeLabelFont();
37482
+ let visual;
37483
+ if (axis === "y") {
37484
+ const bounds = this.rangeLabelCache.bounds;
37485
+ if (!bounds) return void 0;
37486
+ const texts = yRangeLabelValues(bounds.min, bounds.max).map(String);
37487
+ visual = measureRangeLabelGutters(context, font2, texts, []).side + 4;
37488
+ } else {
37489
+ visual = measureRangeLabelGutters(context, font2, [], ["x"]).bottom + 8;
37490
+ }
37491
+ if (!this.fixedAspectRatioScaling) return Math.ceil(visual);
37492
+ const effectiveLength = axis === "y" ? this.getEffectiveHeight() : this.getEffectiveWidth();
37493
+ return Math.ceil(visual * this.scaleReferenceSize / effectiveLength);
37494
+ }
37495
+ slotFor(side) {
37496
+ return {
37169
37497
  left: this.leftScaleSlot,
37170
37498
  right: this.rightScaleSlot,
37171
37499
  top: this.topScaleSlot,
37172
37500
  bottom: this.bottomScaleSlot
37501
+ }[side];
37502
+ }
37503
+ hasSlottedScale(side) {
37504
+ return (this.slotFor(side)?.assignedElements().length ?? 0) > 0;
37505
+ }
37506
+ /** @internal - Below the label threshold on either dimension. */
37507
+ isBelowThreshold() {
37508
+ return this.getEffectiveWidth() < RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS || this.getEffectiveHeight() < RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;
37509
+ }
37510
+ get ySide() {
37511
+ const first = this.yAxes?.[0]?.position;
37512
+ return (first ?? this.yAxisPosition) === "right" ? "right" : "left";
37513
+ }
37514
+ rangeLabelFont() {
37515
+ const sizePx = Number.parseFloat(
37516
+ getCssVariableValue(this, LINE_GRAPH_LABEL_CONFIG.fontSizeVar)
37517
+ );
37518
+ return {
37519
+ family: getCssVariableValue(this, LINE_GRAPH_LABEL_CONFIG.fontFamily),
37520
+ sizePx: Number.isFinite(sizePx) ? sizePx : 12,
37521
+ weight: getCssVariableValue(this, LINE_GRAPH_LABEL_CONFIG.fontWeightVar)
37173
37522
  };
37174
- const slot = slotMap[side];
37523
+ }
37524
+ /**
37525
+ * Extent of the prepared data: one for x, one per y scale id. Each y axis
37526
+ * ranges from its own datasets, so a merged extent would label one axis
37527
+ * with another's values.
37528
+ */
37529
+ dataExtents(prepared) {
37530
+ const x2 = { min: Infinity, max: -Infinity };
37531
+ const y3 = /* @__PURE__ */ new Map();
37532
+ const take = (extent, v2) => {
37533
+ if (!Number.isFinite(v2)) return;
37534
+ extent.min = Math.min(extent.min, v2);
37535
+ extent.max = Math.max(extent.max, v2);
37536
+ };
37537
+ prepared.datasets.forEach((dataset) => {
37538
+ const id = dataset.yAxisID ?? this.primaryYAxisId;
37539
+ const extent = y3.get(id) ?? { min: Infinity, max: -Infinity };
37540
+ y3.set(id, extent);
37541
+ dataset.data.forEach((point) => {
37542
+ if (typeof point === "number") {
37543
+ take(extent, point);
37544
+ } else if (point) {
37545
+ take(x2, point.x);
37546
+ take(extent, point.y);
37547
+ }
37548
+ });
37549
+ });
37550
+ y3.forEach((extent, id) => {
37551
+ if (!(extent.min <= extent.max)) y3.delete(id);
37552
+ });
37553
+ return { x: x2.min <= x2.max ? x2 : void 0, y: y3 };
37554
+ }
37555
+ /**
37556
+ * Range the y labels describe. Below the threshold the axis runs on data
37557
+ * bounds, so its datasets' extent is exact and needs no chart to read from.
37558
+ */
37559
+ yRangeBounds(extents) {
37560
+ let axis;
37561
+ let id = "y";
37562
+ if (this.yAxes?.length) {
37563
+ const match = this.yAxes.findIndex(
37564
+ (a2) => (a2.position ?? "left") === this.ySide
37565
+ );
37566
+ const index2 = match === -1 ? 0 : match;
37567
+ axis = this.yAxes[index2];
37568
+ id = axis.id ?? `y${index2}`;
37569
+ }
37570
+ const extent = extents.get(id);
37571
+ const stackedScale = this.shouldStack() ? this.chart?.scales[id] : void 0;
37572
+ const min2 = axis?.min ?? stackedScale?.min ?? extent?.min;
37573
+ const max2 = axis?.max ?? stackedScale?.max ?? extent?.max;
37574
+ return min2 !== void 0 && max2 !== void 0 ? { min: min2, max: max2 } : void 0;
37575
+ }
37576
+ /** First and last x label, or nothing when there is no span to label. */
37577
+ xEdgeLabelTexts(prepared, extent) {
37578
+ if (!this.isNumericXAxis) {
37579
+ const labels = prepared.labels.map(String);
37580
+ const first = labels[0];
37581
+ const last = labels[labels.length - 1];
37582
+ return labels.length > 1 && first !== last ? [first, last] : [];
37583
+ }
37584
+ const min2 = this.xAxis?.min ?? extent?.min;
37585
+ const max2 = this.xAxis?.max ?? extent?.max;
37586
+ if (min2 === void 0 || max2 === void 0 || min2 === max2) return [];
37587
+ const reference = this.timeDisplay === "minutes" ? this.computeTimeReference() : void 0;
37588
+ return [
37589
+ formatXValue(min2, this.xValueMode, reference),
37590
+ formatXValue(max2, this.xValueMode, reference)
37591
+ ];
37592
+ }
37593
+ /**
37594
+ * Recompute the range labels. A side with a slotted scale is labelled by
37595
+ * the scale, so it gets no text here; the y bounds are kept regardless,
37596
+ * since the scale's compact band is measured from them.
37597
+ */
37598
+ refreshRangeLabels() {
37599
+ const cache = { y: [], x: [] };
37600
+ if (this.isBelowThreshold() && (this.rangeLabelsY || this.rangeLabelsX)) {
37601
+ const prepared = this.prepareChartDataAndLabels();
37602
+ const extents = this.dataExtents(prepared);
37603
+ if (this.rangeLabelsY) {
37604
+ cache.bounds = this.yRangeBounds(extents.y);
37605
+ if (cache.bounds && !this.hasSlottedScale("left") && !this.hasSlottedScale("right")) {
37606
+ const { min: min2, max: max2 } = cache.bounds;
37607
+ cache.y = yRangeLabelValues(min2, max2).map(
37608
+ (v2) => formatRangeValue(v2, min2, max2)
37609
+ );
37610
+ }
37611
+ }
37612
+ if (this.rangeLabelsX && !this.hasSlottedScale("top") && !this.hasSlottedScale("bottom")) {
37613
+ cache.x = this.xEdgeLabelTexts(prepared, extents.x);
37614
+ }
37615
+ }
37616
+ this.rangeLabelCache = cache;
37617
+ return cache;
37618
+ }
37619
+ /**
37620
+ * Paints min / 0 / max and first / last once Chart.js has drawn, inside the
37621
+ * gutters `getChartOptions()` reserved. The end labels sit flush with the
37622
+ * plot edges so no vertical padding is needed for them.
37623
+ */
37624
+ createRangeLabelsPlugin() {
37625
+ return {
37626
+ id: "rangeLabels",
37627
+ afterDraw: (chart) => {
37628
+ this.lastRangeLabels = [];
37629
+ const { y: yTexts, x: xTexts, bounds } = this.rangeLabelCache;
37630
+ if (!yTexts.length && !xTexts.length) return;
37631
+ const area = chart.chartArea;
37632
+ const ctx = chart.ctx;
37633
+ const font2 = this.rangeLabelFont();
37634
+ const lineHeight = rangeLabelLineHeight(font2);
37635
+ ctx.save();
37636
+ ctx.font = rangeLabelFontString(font2);
37637
+ ctx.fillStyle = getCssVariableValue(
37638
+ this,
37639
+ LINE_GRAPH_LABEL_CONFIG.fontColorVar
37640
+ );
37641
+ const scale = chart.scales[this.primaryYAxisId];
37642
+ if (yTexts.length && bounds && scale) {
37643
+ const onRight = this.ySide === "right";
37644
+ const x2 = onRight ? area.right + 8 : area.left - 8;
37645
+ ctx.textAlign = onRight ? "left" : "right";
37646
+ const values = yRangeLabelValues(bounds.min, bounds.max);
37647
+ for (let i4 = values.length - 1; i4 >= 0; i4--) {
37648
+ const isMax = i4 === values.length - 1;
37649
+ const isMin = i4 === 0;
37650
+ const y3 = isMax ? area.top : isMin ? area.bottom : scale.getPixelForValue(values[i4]);
37651
+ if (!isMax && !isMin && (y3 - area.top < lineHeight || area.bottom - y3 < lineHeight)) {
37652
+ continue;
37653
+ }
37654
+ ctx.textBaseline = isMax ? "top" : isMin ? "bottom" : "middle";
37655
+ ctx.fillText(yTexts[i4], x2, y3);
37656
+ this.lastRangeLabels.push({ axis: "y", text: yTexts[i4], x: x2, y: y3 });
37657
+ }
37658
+ }
37659
+ if (xTexts.length === 2) {
37660
+ const y3 = area.bottom + 4;
37661
+ ctx.textBaseline = "top";
37662
+ ctx.textAlign = "left";
37663
+ ctx.fillText(xTexts[0], area.left, y3);
37664
+ this.lastRangeLabels.push({
37665
+ axis: "x",
37666
+ text: xTexts[0],
37667
+ x: area.left,
37668
+ y: y3
37669
+ });
37670
+ ctx.textAlign = "right";
37671
+ ctx.fillText(xTexts[1], area.right, y3);
37672
+ this.lastRangeLabels.push({
37673
+ axis: "x",
37674
+ text: xTexts[1],
37675
+ x: area.right,
37676
+ y: y3
37677
+ });
37678
+ }
37679
+ ctx.restore();
37680
+ }
37681
+ };
37682
+ }
37683
+ /**
37684
+ * Check if a slotted scale element is actually visible (renders content).
37685
+ * For bar-vertical/bar-horizontal elements, checks hasBar and hasScale properties.
37686
+ */
37687
+ hasVisibleScale(side) {
37688
+ const slot = this.slotFor(side);
37175
37689
  const elements = slot?.assignedElements() ?? [];
37176
37690
  return elements.some((el) => {
37177
37691
  const barEl = el;
@@ -37551,13 +38065,13 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37551
38065
  if (this.isUpdatingScales) return false;
37552
38066
  this.isUpdatingScales = true;
37553
38067
  try {
37554
- const padding = this.calculatePaddingFromScales();
37555
- const effectiveWidth = this.width - padding.left - padding.right;
37556
- const effectiveHeight = this.height - padding.top - padding.bottom;
38068
+ const padding = this.computeChartPadding();
38069
+ const effectiveWidth = this.getEffectiveWidth() - padding.left - padding.right;
38070
+ const effectiveHeight = this.getEffectiveHeight() - padding.top - padding.bottom;
37557
38071
  if (effectiveWidth <= 0 || effectiveHeight <= 0) {
37558
38072
  console.warn("[chart-line-base] Invalid effective dimensions", {
37559
- width: this.width,
37560
- height: this.height,
38073
+ width: this.getEffectiveWidth(),
38074
+ height: this.getEffectiveHeight(),
37561
38075
  padding,
37562
38076
  effectiveWidth,
37563
38077
  effectiveHeight
@@ -37594,47 +38108,139 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37594
38108
  };
37595
38109
  return padding;
37596
38110
  }
38111
+ /**
38112
+ * Range a slotted scale on the given side has to cover.
38113
+ *
38114
+ * A range pinned in the axis configuration is used as is: it is the source
38115
+ * of truth, and on the first sync there is no chart to read yet. Otherwise
38116
+ * the live Chart.js scale is read under the id `buildScalesConfig()` gives
38117
+ * it. A side with no axis of its own follows the first configured one.
38118
+ */
38119
+ resolveAxisRange(side) {
38120
+ let id = side === "x" ? "x" : "y";
38121
+ let configured;
38122
+ if (side === "x") {
38123
+ configured = this.isNumericXAxis ? this.xAxis : void 0;
38124
+ } else if (this.yAxes?.length) {
38125
+ const match = this.yAxes.findIndex(
38126
+ (axis2) => (axis2.position ?? "left") === side
38127
+ );
38128
+ const index2 = match === -1 ? 0 : match;
38129
+ const axis = this.yAxes[index2];
38130
+ id = axis.id ?? `y${index2}`;
38131
+ configured = axis;
38132
+ }
38133
+ if (configured?.min !== void 0 && configured.max !== void 0) {
38134
+ return { min: configured.min, max: configured.max };
38135
+ }
38136
+ const scale = this.chart?.scales[id];
38137
+ return {
38138
+ min: scale?.min ?? configured?.min ?? 0,
38139
+ max: scale?.max ?? configured?.max ?? 100
38140
+ };
38141
+ }
38142
+ /**
38143
+ * Range pushed to the top and bottom scales, or `undefined` to leave them
38144
+ * alone. A scale prints its values verbatim, and on a `time` axis the raw
38145
+ * range is epoch milliseconds. In `minutes` display the range is converted
38146
+ * to the minutes the chart's own labels show; `date` display has no numeric
38147
+ * equivalent, so the scale keeps its own range.
38148
+ */
38149
+ resolveSlottedXRange() {
38150
+ const range = this.resolveAxisRange("x");
38151
+ if (this.xAxisType !== "time") return range;
38152
+ if (this.timeDisplay !== "minutes") {
38153
+ if (!this.warnedDateDisplayScale) {
38154
+ this.warnedDateDisplayScale = true;
38155
+ console.warn(
38156
+ "[obc-chart] a slotted horizontal scale cannot label a time axis in 'date' display and keeps its own range; use timeDisplay='minutes' or a number axis."
38157
+ );
38158
+ }
38159
+ return void 0;
38160
+ }
38161
+ const pinned = this.xAxis?.min !== void 0 && this.xAxis?.max !== void 0;
38162
+ const reference = this.computeTimeReference();
38163
+ if (reference === void 0 || !this.chart && !pinned) return void 0;
38164
+ const minute = 6e4;
38165
+ return {
38166
+ min: (range.min - reference) / minute,
38167
+ max: (range.max - reference) / minute
38168
+ };
38169
+ }
37597
38170
  /**
37598
38171
  * Update properties on slotted scale elements
37599
38172
  */
37600
38173
  updateScaleProperties(padding) {
37601
- const yMin = this.chart?.scales["y"]?.min ?? 0;
37602
- const yMax = this.chart?.scales["y"]?.max ?? 100;
37603
- const xMin = this.chart?.scales["x"]?.min ?? 0;
37604
- const xMax = this.chart?.scales["x"]?.max ?? 100;
38174
+ const leftRange = this.resolveAxisRange("left");
38175
+ const rightRange = this.resolveAxisRange("right");
38176
+ const xRange = this.resolveSlottedXRange();
37605
38177
  const effectiveWidth = this.getEffectiveWidth();
37606
38178
  const effectiveHeight = this.getEffectiveHeight();
37607
- const showLabels = this.hasLabelPadding && effectiveWidth >= RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS && effectiveHeight >= RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;
38179
+ const aboveThreshold = effectiveWidth >= RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS && effectiveHeight >= RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;
38180
+ const showLabels = this.hasLabelPadding && aboveThreshold;
38181
+ const compactY = !aboveThreshold && this.rangeLabelsY;
38182
+ const compactX = !aboveThreshold && this.rangeLabelsX;
38183
+ const compactYThickness = compactY ? this.compactLabelThickness("y") : void 0;
38184
+ const compactXThickness = compactX ? this.compactLabelThickness("x") : void 0;
38185
+ const mainLabelsFor = (scale, compact) => {
38186
+ if (compact) {
38187
+ if (!this.savedMainTickmarkLabels.has(scale)) {
38188
+ this.savedMainTickmarkLabels.set(
38189
+ scale,
38190
+ scale.showMainTickmarkLabels ?? false
38191
+ );
38192
+ }
38193
+ return true;
38194
+ }
38195
+ if (!this.savedMainTickmarkLabels.has(scale)) return void 0;
38196
+ const saved = this.savedMainTickmarkLabels.get(scale);
38197
+ this.savedMainTickmarkLabels.delete(scale);
38198
+ return saved;
38199
+ };
38200
+ const bandFor = (scale, compact, thickness) => {
38201
+ if (compact) {
38202
+ if (thickness === void 0 || typeof scale.labelThickness !== "number") {
38203
+ return void 0;
38204
+ }
38205
+ if (!this.savedLabelThickness.has(scale)) {
38206
+ this.savedLabelThickness.set(scale, scale.labelThickness);
38207
+ }
38208
+ return thickness;
38209
+ }
38210
+ const saved = this.savedLabelThickness.get(scale);
38211
+ this.savedLabelThickness.delete(scale);
38212
+ return saved;
38213
+ };
37608
38214
  const verticalViewBoxPadding = this.fixedAspectRatioScaling ? {
37609
38215
  top: Math.round(
37610
- padding.top * this.scaleReferenceSize / this.height
38216
+ padding.top * this.scaleReferenceSize / effectiveHeight
37611
38217
  ),
37612
38218
  bottom: Math.round(
37613
- padding.bottom * this.scaleReferenceSize / this.height
38219
+ padding.bottom * this.scaleReferenceSize / effectiveHeight
37614
38220
  )
37615
38221
  } : { top: padding.top, bottom: padding.bottom };
37616
38222
  const horizontalViewBoxPadding = this.fixedAspectRatioScaling ? {
37617
38223
  left: Math.round(
37618
- padding.left * this.scaleReferenceSize / this.width
38224
+ padding.left * this.scaleReferenceSize / effectiveWidth
37619
38225
  ),
37620
38226
  right: Math.round(
37621
- padding.right * this.scaleReferenceSize / this.width
38227
+ padding.right * this.scaleReferenceSize / effectiveWidth
37622
38228
  )
37623
38229
  } : { left: padding.left, right: padding.right };
37624
38230
  const updates = [];
38231
+ const rangeProps = (side, range) => this.ownsSlottedScaleRange(side) ? { minValue: range.min, maxValue: range.max } : {};
37625
38232
  if (this.leftScaleSlot) {
37626
38233
  const scales = this.leftScaleSlot.assignedElements();
37627
38234
  scales.forEach((scale) => {
37628
38235
  const props = {
37629
- minValue: yMin,
37630
- maxValue: yMax,
38236
+ ...rangeProps("left", leftRange),
37631
38237
  height: effectiveHeight,
37632
38238
  // Use effective height for proper sizing
37633
38239
  paddingTop: verticalViewBoxPadding.top,
37634
38240
  paddingBottom: verticalViewBoxPadding.bottom,
37635
38241
  paddingStart: verticalViewBoxPadding.top,
37636
38242
  paddingEnd: verticalViewBoxPadding.bottom,
37637
- showLabels,
38243
+ showLabels: showLabels || compactY,
37638
38244
  fixedAspectRatio: this.fixedAspectRatioScaling,
37639
38245
  // Use chart's scaleReferenceSize property for proportional scaling
37640
38246
  scaleReferenceSize: this.scaleReferenceSize,
@@ -37646,6 +38252,10 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37646
38252
  if (this.yStepSize !== void 0) {
37647
38253
  props.primaryTickmarkInterval = this.yStepSize;
37648
38254
  }
38255
+ const band = bandFor(scale, compactY, compactYThickness);
38256
+ const mainLabels = mainLabelsFor(scale, compactY);
38257
+ if (mainLabels !== void 0) props.showMainTickmarkLabels = mainLabels;
38258
+ if (band !== void 0) props.labelThickness = band;
37649
38259
  updates.push([this.leftScaleSlot, scale, props]);
37650
38260
  });
37651
38261
  }
@@ -37653,15 +38263,14 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37653
38263
  const scales = this.rightScaleSlot.assignedElements();
37654
38264
  scales.forEach((scale) => {
37655
38265
  const props = {
37656
- minValue: yMin,
37657
- maxValue: yMax,
38266
+ ...rangeProps("right", rightRange),
37658
38267
  height: effectiveHeight,
37659
38268
  // Use effective height for proper sizing
37660
38269
  paddingTop: verticalViewBoxPadding.top,
37661
38270
  paddingBottom: verticalViewBoxPadding.bottom,
37662
38271
  paddingStart: verticalViewBoxPadding.top,
37663
38272
  paddingEnd: verticalViewBoxPadding.bottom,
37664
- showLabels,
38273
+ showLabels: showLabels || compactY,
37665
38274
  fixedAspectRatio: this.fixedAspectRatioScaling,
37666
38275
  // Use chart's scaleReferenceSize property for proportional scaling
37667
38276
  scaleReferenceSize: this.scaleReferenceSize,
@@ -37673,6 +38282,10 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37673
38282
  if (this.yStepSize !== void 0) {
37674
38283
  props.primaryTickmarkInterval = this.yStepSize;
37675
38284
  }
38285
+ const band = bandFor(scale, compactY, compactYThickness);
38286
+ const mainLabels = mainLabelsFor(scale, compactY);
38287
+ if (mainLabels !== void 0) props.showMainTickmarkLabels = mainLabels;
38288
+ if (band !== void 0) props.labelThickness = band;
37676
38289
  updates.push([this.rightScaleSlot, scale, props]);
37677
38290
  });
37678
38291
  }
@@ -37680,15 +38293,14 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37680
38293
  const scales = this.topScaleSlot.assignedElements();
37681
38294
  scales.forEach((scale) => {
37682
38295
  const props = {
37683
- minValue: xMin,
37684
- maxValue: xMax,
38296
+ ...xRange,
37685
38297
  width: effectiveWidth,
37686
38298
  // Use effective width for proper sizing
37687
38299
  paddingLeft: horizontalViewBoxPadding.left,
37688
38300
  paddingRight: horizontalViewBoxPadding.right,
37689
38301
  paddingStart: horizontalViewBoxPadding.left,
37690
38302
  paddingEnd: horizontalViewBoxPadding.right,
37691
- showLabels,
38303
+ showLabels: showLabels || compactX,
37692
38304
  fixedAspectRatio: this.fixedAspectRatioScaling,
37693
38305
  // Use chart's scaleReferenceSize property for proportional scaling
37694
38306
  scaleReferenceSize: this.scaleReferenceSize,
@@ -37700,6 +38312,10 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37700
38312
  if (this.xStepSize !== void 0) {
37701
38313
  props.primaryTickmarkInterval = this.xStepSize;
37702
38314
  }
38315
+ const band = bandFor(scale, compactX, compactXThickness);
38316
+ const mainLabels = mainLabelsFor(scale, compactX);
38317
+ if (mainLabels !== void 0) props.showMainTickmarkLabels = mainLabels;
38318
+ if (band !== void 0) props.labelThickness = band;
37703
38319
  updates.push([this.topScaleSlot, scale, props]);
37704
38320
  });
37705
38321
  }
@@ -37707,15 +38323,14 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37707
38323
  const scales = this.bottomScaleSlot.assignedElements();
37708
38324
  scales.forEach((scale) => {
37709
38325
  const props = {
37710
- minValue: xMin,
37711
- maxValue: xMax,
38326
+ ...xRange,
37712
38327
  width: effectiveWidth,
37713
38328
  // Use effective width for proper sizing
37714
38329
  paddingLeft: horizontalViewBoxPadding.left,
37715
38330
  paddingRight: horizontalViewBoxPadding.right,
37716
38331
  paddingStart: horizontalViewBoxPadding.left,
37717
38332
  paddingEnd: horizontalViewBoxPadding.right,
37718
- showLabels,
38333
+ showLabels: showLabels || compactX,
37719
38334
  fixedAspectRatio: this.fixedAspectRatioScaling,
37720
38335
  // Use chart's scaleReferenceSize property for proportional scaling
37721
38336
  scaleReferenceSize: this.scaleReferenceSize,
@@ -37727,6 +38342,10 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37727
38342
  if (this.xStepSize !== void 0) {
37728
38343
  props.primaryTickmarkInterval = this.xStepSize;
37729
38344
  }
38345
+ const band = bandFor(scale, compactX, compactXThickness);
38346
+ const mainLabels = mainLabelsFor(scale, compactX);
38347
+ if (mainLabels !== void 0) props.showMainTickmarkLabels = mainLabels;
38348
+ if (band !== void 0) props.labelThickness = band;
37730
38349
  updates.push([this.bottomScaleSlot, scale, props]);
37731
38350
  });
37732
38351
  }
@@ -37734,6 +38353,34 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37734
38353
  Object.assign(scale, props);
37735
38354
  });
37736
38355
  }
38356
+ /**
38357
+ * Whether the chart's axis range is what a slotted scale on this side should
38358
+ * describe. A subclass that slots a scale of its own and gives it a separate
38359
+ * range returns false for that side, otherwise the sync below overwrites it.
38360
+ */
38361
+ ownsSlottedScaleRange(_side) {
38362
+ return true;
38363
+ }
38364
+ /**
38365
+ * Push the current axis ranges to the slotted scales. The full
38366
+ * `updateScaleProperties()` cascade runs before the chart is (re)built and
38367
+ * so reads the previous chart's ranges; this closes that gap once the new
38368
+ * chart exists, and keeps auto-ranged scales in step with the data.
38369
+ */
38370
+ syncSlottedScaleRanges() {
38371
+ const apply = (side, slot, range) => {
38372
+ if (!slot || !range || !this.ownsSlottedScaleRange(side)) return;
38373
+ slot.assignedElements().forEach((scale) => {
38374
+ scale.minValue = range.min;
38375
+ scale.maxValue = range.max;
38376
+ });
38377
+ };
38378
+ apply("left", this.leftScaleSlot, this.resolveAxisRange("left"));
38379
+ apply("right", this.rightScaleSlot, this.resolveAxisRange("right"));
38380
+ const xRange = this.resolveSlottedXRange();
38381
+ apply("top", this.topScaleSlot, xRange);
38382
+ apply("bottom", this.bottomScaleSlot, xRange);
38383
+ }
37737
38384
  hasAnyChanged(changed, props) {
37738
38385
  return props.some((prop) => changed.has(prop));
37739
38386
  }
@@ -37807,7 +38454,10 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37807
38454
  if (this.hasAnyChanged(changed, LINE_GRAPH_DIMENSION_PROP_NAMES)) {
37808
38455
  if (this.updateComputedDimensions()) return;
37809
38456
  }
37810
- if (changed.has("hasLabelPadding") && this.hasExternalScales()) {
38457
+ const belowThreshold = this.isBelowThreshold();
38458
+ const crossedThreshold = this.wasBelowThreshold !== void 0 && this.wasBelowThreshold !== belowThreshold;
38459
+ this.wasBelowThreshold = belowThreshold;
38460
+ if ((changed.has("hasLabelPadding") || changed.has("rangeLabels") || crossedThreshold) && this.hasExternalScales()) {
37811
38461
  this.syncScalesAndChart();
37812
38462
  return;
37813
38463
  }
@@ -37862,7 +38512,7 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37862
38512
  if (!this.canvasEl) return;
37863
38513
  this.resizeObserver = observeLabelThreshold(
37864
38514
  this.canvasEl,
37865
- () => (this.canvasEl?.clientHeight ?? 0) >= RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS,
38515
+ () => (this.canvasEl?.clientHeight ?? 0) >= RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS && (this.canvasEl?.clientWidth ?? 0) >= RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS,
37866
38516
  {
37867
38517
  rebuild: () => {
37868
38518
  this.chart?.destroy();
@@ -37983,6 +38633,7 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
37983
38633
  const result = {
37984
38634
  ...existingDataset || {},
37985
38635
  data: existingDataset?.data ?? values,
38636
+ yAxisID: existingDataset?.yAxisID ?? this.primaryYAxisId,
37986
38637
  borderColor,
37987
38638
  backgroundColor,
37988
38639
  borderWidth: existingDataset?.borderWidth ?? 2,
@@ -38029,6 +38680,7 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
38029
38680
  const baselineDataset = {
38030
38681
  label: "threshold-baseline",
38031
38682
  data: baselineData,
38683
+ yAxisID: this.primaryYAxisId,
38032
38684
  borderColor: "transparent",
38033
38685
  backgroundColor: "transparent",
38034
38686
  borderWidth: 0,
@@ -38114,6 +38766,36 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
38114
38766
  const datasets = fill2 && fillMode === "threshold" ? this.createThresholdDatasets(values, chartColors) : [this.buildDataset(values, 0, chartColors)];
38115
38767
  return { datasets, labels };
38116
38768
  }
38769
+ /**
38770
+ * One padding source for the Chart.js layout and the slotted scales: two
38771
+ * sources painted the canvas over a scale and inset a scale inside a chart.
38772
+ */
38773
+ computeChartPadding() {
38774
+ const isTooSmall = this.isBelowThreshold();
38775
+ const scaleFactor = this.getScaleFactor();
38776
+ const defaultPaddingScaled = !this.hasLabelPadding ? 0 : this.fixedAspectRatioScaling ? Math.round(CHART_DIMENSIONS.CANVAS_PADDING * scaleFactor) : CHART_DIMENSIONS.CANVAS_PADDING;
38777
+ const { y: yTexts, x: xTexts } = this.refreshRangeLabels();
38778
+ const context = this.canvasEl?.getContext("2d");
38779
+ const gutters = (yTexts.length || xTexts.length) && context ? measureRangeLabelGutters(
38780
+ context,
38781
+ this.rangeLabelFont(),
38782
+ yTexts,
38783
+ xTexts
38784
+ ) : { side: 0, bottom: 0 };
38785
+ const scalePadding = this.calculatePaddingFromScales();
38786
+ const freeSide = (side) => {
38787
+ if (!isTooSmall) return defaultPaddingScaled;
38788
+ if (side === "bottom") return gutters.bottom;
38789
+ return side === this.ySide ? gutters.side : 0;
38790
+ };
38791
+ const padding = {
38792
+ top: this.externalScaleDimensions.has("top") ? scalePadding.top : freeSide("top"),
38793
+ right: this.externalScaleDimensions.has("right") ? scalePadding.right : freeSide("right"),
38794
+ bottom: this.externalScaleDimensions.has("bottom") ? scalePadding.bottom : freeSide("bottom"),
38795
+ left: this.externalScaleDimensions.has("left") ? scalePadding.left : freeSide("left")
38796
+ };
38797
+ return padding;
38798
+ }
38117
38799
  /**
38118
38800
  * Get Chart.js options with dynamic sizing and padding
38119
38801
  */
@@ -38121,27 +38803,7 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
38121
38803
  const effectiveWidth = this.getEffectiveWidth();
38122
38804
  const effectiveHeight = this.getEffectiveHeight();
38123
38805
  const isTooSmall = effectiveWidth < RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS || effectiveHeight < RECTANGULAR_CHART_DIMENSIONS.MIN_HEIGHT_WITH_LABELS;
38124
- const scaleFactor = this.getScaleFactor();
38125
- let padding;
38126
- const defaultPaddingScaled = !this.hasLabelPadding ? 0 : this.fixedAspectRatioScaling ? Math.round(CHART_DIMENSIONS.CANVAS_PADDING * scaleFactor) : CHART_DIMENSIONS.CANVAS_PADDING;
38127
- if (isTooSmall && this.hasLabelPadding) {
38128
- padding = { top: 0, right: 0, bottom: 0, left: 0 };
38129
- } else if (this.hasExternalScales()) {
38130
- const scalePadding = this.calculatePaddingFromScales();
38131
- padding = {
38132
- top: this.externalScaleDimensions.has("top") ? scalePadding.top : defaultPaddingScaled,
38133
- right: this.externalScaleDimensions.has("right") ? scalePadding.right : defaultPaddingScaled,
38134
- bottom: this.externalScaleDimensions.has("bottom") ? scalePadding.bottom : defaultPaddingScaled,
38135
- left: this.externalScaleDimensions.has("left") ? scalePadding.left : defaultPaddingScaled
38136
- };
38137
- } else {
38138
- padding = {
38139
- top: defaultPaddingScaled,
38140
- right: defaultPaddingScaled,
38141
- bottom: defaultPaddingScaled,
38142
- left: defaultPaddingScaled
38143
- };
38144
- }
38806
+ const padding = this.computeChartPadding();
38145
38807
  if (this.fixedAspectRatioScaling) {
38146
38808
  this.style.setProperty("--chart-width", "100%");
38147
38809
  this.style.setProperty("--chart-height", `${effectiveHeight}px`);
@@ -38196,9 +38858,13 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
38196
38858
  /**
38197
38859
  * Compute reference timestamp for time axis formatting.
38198
38860
  * Returns earliest timestamp for 'date' mode, latest for 'minutes' mode.
38861
+ * A pinned x range supplies the reference instead, so the axis edge stays
38862
+ * the reference while the data has not reached it yet.
38199
38863
  */
38200
38864
  computeTimeReference() {
38201
38865
  if (this.xAxisType !== "time") return void 0;
38866
+ const pinned = this.timeDisplay === "minutes" ? this.xAxis?.max : this.xAxis?.min;
38867
+ if (pinned !== void 0 && Number.isFinite(pinned)) return pinned;
38202
38868
  const timestamps = [];
38203
38869
  if (this.datasets?.length) {
38204
38870
  this.datasets.forEach((ds) => {
@@ -38271,6 +38937,9 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
38271
38937
  // No extra margin
38272
38938
  bounds: "data",
38273
38939
  // Use data bounds for edge-to-edge rendering
38940
+ // A category axis has no numeric range to pin.
38941
+ min: this.isNumericXAxis ? this.xAxis?.min : void 0,
38942
+ max: this.isNumericXAxis ? this.xAxis?.max : void 0,
38274
38943
  grid: {
38275
38944
  display: this.showGrid && this.showGridX,
38276
38945
  color: gridColor,
@@ -38371,10 +39040,14 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
38371
39040
  type: "line",
38372
39041
  data: { labels, datasets },
38373
39042
  options: this.getChartOptions(),
38374
- plugins: this.borderRadiusPosition ? [this.createBorderPlugin()] : []
39043
+ plugins: [
39044
+ ...this.borderRadiusPosition ? [this.createBorderPlugin()] : [],
39045
+ ...this.rangeLabels !== "none" ? [this.createRangeLabelsPlugin()] : []
39046
+ ]
38375
39047
  });
38376
39048
  requestAnimationFrame(() => this.updateLegend());
38377
39049
  this.applyFillModes();
39050
+ this.syncSlottedScaleRanges();
38378
39051
  }
38379
39052
  updateChart() {
38380
39053
  if (!this.chart || !this.canvasEl || !this.canvasEl.isConnected) return;
@@ -38384,6 +39057,7 @@ const _ObcChartLineBase = class _ObcChartLineBase extends i$4 {
38384
39057
  Object.assign(this.chart.options, this.getChartOptions());
38385
39058
  this.applyFillModes();
38386
39059
  this.chart.update();
39060
+ this.syncSlottedScaleRanges();
38387
39061
  requestAnimationFrame(() => this.updateLegend());
38388
39062
  }
38389
39063
  /**
@@ -38509,6 +39183,9 @@ __decorateClass$zY([
38509
39183
  __decorateClass$zY([
38510
39184
  n$3({ type: Array, attribute: false })
38511
39185
  ], ObcChartLineBase.prototype, "yAxes");
39186
+ __decorateClass$zY([
39187
+ n$3({ type: Object, attribute: false })
39188
+ ], ObcChartLineBase.prototype, "xAxis");
38512
39189
  __decorateClass$zY([
38513
39190
  n$3({ type: Boolean })
38514
39191
  ], ObcChartLineBase.prototype, "showGrid");
@@ -38524,6 +39201,9 @@ __decorateClass$zY([
38524
39201
  __decorateClass$zY([
38525
39202
  n$3({ type: Boolean, attribute: false })
38526
39203
  ], ObcChartLineBase.prototype, "hasLabelPadding");
39204
+ __decorateClass$zY([
39205
+ n$3({ type: String })
39206
+ ], ObcChartLineBase.prototype, "rangeLabels");
38527
39207
  __decorateClass$zY([
38528
39208
  n$3({ type: Boolean })
38529
39209
  ], ObcChartLineBase.prototype, "showPoints");
@@ -38869,6 +39549,7 @@ let ObcBarVertical = class extends SetpointMixin(i$4, {
38869
39549
  });
38870
39550
  this.hasScale = true;
38871
39551
  this.showLabels = true;
39552
+ this.showMainTickmarkLabels = false;
38872
39553
  this.hasBar = false;
38873
39554
  this.scaleBackground = false;
38874
39555
  this.barContainerStyle = void 0;
@@ -38913,6 +39594,7 @@ let ObcBarVertical = class extends SetpointMixin(i$4, {
38913
39594
  maxValue: this.maxValue,
38914
39595
  hasScale: this.hasScale,
38915
39596
  labels: this.showLabels,
39597
+ mainTickmarkLabels: this.showMainTickmarkLabels,
38916
39598
  hasBar: this.hasBar,
38917
39599
  scaleBackground: this.scaleBackground,
38918
39600
  barContainerStyle: this.barContainerStyle,
@@ -38990,7 +39672,7 @@ let ObcBarVertical = class extends SetpointMixin(i$4, {
38990
39672
  if (changed.has("scaleReferenceSize") && this.fixedAspectRatio) {
38991
39673
  this._updateScaleFromCurrentSize();
38992
39674
  }
38993
- const layoutChanged = changed.has("side") || changed.has("showLabels") || changed.has("hasScale") || changed.has("hasBar") || changed.has("barThickness") || changed.has("tickThickness") || changed.has("labelThickness") || changed.has("scaleType") || changed.has("borderRadiusPosition") || changed.has("borderRadius") || changed.has("advices") || changed.has("advicePosition") || this.setpointPresenceChanged(changed);
39675
+ const layoutChanged = changed.has("side") || changed.has("showLabels") || changed.has("showMainTickmarkLabels") || changed.has("hasScale") || changed.has("hasBar") || changed.has("barThickness") || changed.has("tickThickness") || changed.has("labelThickness") || changed.has("scaleType") || changed.has("borderRadiusPosition") || changed.has("borderRadius") || changed.has("advices") || changed.has("advicePosition") || this.setpointPresenceChanged(changed);
38994
39676
  if (!this.fixedAspectRatio || layoutChanged) {
38995
39677
  this.reportDimensions();
38996
39678
  }
@@ -39163,6 +39845,9 @@ __decorateClass$zW([
39163
39845
  __decorateClass$zW([
39164
39846
  n$3({ type: Boolean, attribute: false })
39165
39847
  ], ObcBarVertical.prototype, "showLabels", 2);
39848
+ __decorateClass$zW([
39849
+ n$3({ type: Boolean })
39850
+ ], ObcBarVertical.prototype, "showMainTickmarkLabels", 2);
39166
39851
  __decorateClass$zW([
39167
39852
  n$3({ type: Boolean })
39168
39853
  ], ObcBarVertical.prototype, "hasBar", 2);
@@ -39386,6 +40071,14 @@ let ObcGaugeTrend = class extends SetpointMixin(ObcChartLineBase) {
39386
40071
  shouldStack() {
39387
40072
  return false;
39388
40073
  }
40074
+ /**
40075
+ * The right scale is this component's own bar, ranged by `minValue` /
40076
+ * `maxValue`. `chartMinValue` / `chartMaxValue` exist so the plotted range
40077
+ * can differ from it, so the chart's axis range must not overwrite it.
40078
+ */
40079
+ ownsSlottedScaleRange(side) {
40080
+ return side !== "right";
40081
+ }
39389
40082
  willUpdate(changed) {
39390
40083
  if (changed.has("xAxisType") && this.xAxisType !== this._autoAppliedXAxisType && (this.hasUpdated || this.xAxisType !== XAxisType.category)) {
39391
40084
  this._explicitXAxisType = true;
@@ -50599,6 +51292,7 @@ let ObcReadoutListItem = class extends i$4 {
50599
51292
  .thickness=${thickness}
50600
51293
  .status=${alert.status ?? AlertType.Alarm}
50601
51294
  .mode=${alert.mode ?? ObcAlertFrameMode.ackedActive}
51295
+ .flashingSpeed=${alert.flashingSpeed ?? FlashingSpeed.Default}
50602
51296
  .showIcon=${alert.showIcon ?? false}
50603
51297
  .showAlertCategoryIcon=${alert.showAlertCategoryIcon ?? true}
50604
51298
  .wrapContent=${false}
@@ -55974,6 +56668,7 @@ let ObcReadout = class extends i$4 {
55974
56668
  .thickness=${thickness}
55975
56669
  .status=${alert.status ?? AlertType.Alarm}
55976
56670
  .mode=${alert.mode ?? ObcAlertFrameMode.ackedActive}
56671
+ .flashingSpeed=${alert.flashingSpeed ?? FlashingSpeed.Default}
55977
56672
  .showIcon=${alert.showIcon ?? false}
55978
56673
  .showAlertCategoryIcon=${alert.showAlertCategoryIcon ?? true}
55979
56674
  .wrapContent=${false}
@@ -74925,6 +75620,7 @@ let ObcBarHorizontal = class extends SetpointMixin(i$4, {
74925
75620
  });
74926
75621
  this.hasScale = true;
74927
75622
  this.showLabels = true;
75623
+ this.showMainTickmarkLabels = false;
74928
75624
  this.hasBar = false;
74929
75625
  this.scaleBackground = false;
74930
75626
  this.barContainerStyle = void 0;
@@ -74969,6 +75665,7 @@ let ObcBarHorizontal = class extends SetpointMixin(i$4, {
74969
75665
  maxValue: this.maxValue,
74970
75666
  hasScale: this.hasScale,
74971
75667
  labels: this.showLabels,
75668
+ mainTickmarkLabels: this.showMainTickmarkLabels,
74972
75669
  hasBar: this.hasBar,
74973
75670
  scaleBackground: this.scaleBackground,
74974
75671
  barContainerStyle: this.barContainerStyle,
@@ -75046,7 +75743,7 @@ let ObcBarHorizontal = class extends SetpointMixin(i$4, {
75046
75743
  if (changed.has("scaleReferenceSize") && this.fixedAspectRatio) {
75047
75744
  this._updateScaleFromCurrentSize();
75048
75745
  }
75049
- const layoutChanged = changed.has("side") || changed.has("showLabels") || changed.has("hasScale") || changed.has("hasBar") || changed.has("barThickness") || changed.has("tickThickness") || changed.has("labelThickness") || changed.has("scaleType") || changed.has("borderRadiusPosition") || changed.has("borderRadius") || changed.has("advices") || changed.has("advicePosition") || this.setpointPresenceChanged(changed);
75746
+ const layoutChanged = changed.has("side") || changed.has("showLabels") || changed.has("showMainTickmarkLabels") || changed.has("hasScale") || changed.has("hasBar") || changed.has("barThickness") || changed.has("tickThickness") || changed.has("labelThickness") || changed.has("scaleType") || changed.has("borderRadiusPosition") || changed.has("borderRadius") || changed.has("advices") || changed.has("advicePosition") || this.setpointPresenceChanged(changed);
75050
75747
  if (!this.fixedAspectRatio || layoutChanged) {
75051
75748
  this.reportDimensions();
75052
75749
  }
@@ -75219,6 +75916,9 @@ __decorateClass$vM([
75219
75916
  __decorateClass$vM([
75220
75917
  n$3({ type: Boolean, attribute: false })
75221
75918
  ], ObcBarHorizontal.prototype, "showLabels", 2);
75919
+ __decorateClass$vM([
75920
+ n$3({ type: Boolean })
75921
+ ], ObcBarHorizontal.prototype, "showMainTickmarkLabels", 2);
75222
75922
  __decorateClass$vM([
75223
75923
  n$3({ type: Boolean })
75224
75924
  ], ObcBarHorizontal.prototype, "hasBar", 2);
@@ -78192,12 +78892,8 @@ const compentStyle$Z = i$7`* {
78192
78892
  }
78193
78893
 
78194
78894
  .trailing-icon {
78195
- width: var(
78196
- --app-components-alert-components-general-notification-item-icon-size-large
78197
- );
78198
- height: var(
78199
- --app-components-alert-components-general-notification-item-icon-size-large
78200
- );
78895
+ width: var(--app-components-message-menu-item-icon-size-large);
78896
+ height: var(--app-components-message-menu-item-icon-size-large);
78201
78897
  display: flex;
78202
78898
  align-items: center;
78203
78899
  justify-content: center;
@@ -80892,42 +81588,34 @@ button {
80892
81588
  width: min-content;
80893
81589
  }
80894
81590
 
80895
- :is(.blinking.alert-type-warning .alert-button,.blinking.alert-type-level-medium .alert-button) .visible-wrapper {
80896
- opacity: var(--warning-blink-on);
80897
- }
80898
-
80899
- :is(.blinking.alert-type-warning .alert-button,.blinking.alert-type-level-medium .alert-button) .blink {
80900
- opacity: var(--warning-blink-off);
80901
- }
80902
-
80903
- :is(.blinking.alert-type-level-critical .alert-button) .visible-wrapper {
80904
- opacity: var(--critical-blink-on);
81591
+ :is(.flash-fast .alert-button) .visible-wrapper {
81592
+ opacity: var(--flash-fast-on);
80905
81593
  }
80906
81594
 
80907
- :is(.blinking.alert-type-level-critical .alert-button) .blink {
80908
- opacity: var(--critical-blink-off);
81595
+ :is(.flash-fast .alert-button) .blink {
81596
+ opacity: var(--flash-fast-off);
80909
81597
  }
80910
81598
 
80911
- :is(.blinking.alert-type-alarm .alert-button,.blinking.alert-type-level-high .alert-button) .visible-wrapper {
80912
- opacity: var(--alarm-blink-on);
81599
+ :is(.flash-slow .alert-button) .visible-wrapper {
81600
+ opacity: var(--flash-slow-on);
80913
81601
  }
80914
81602
 
80915
- :is(.blinking.alert-type-alarm .alert-button,.blinking.alert-type-level-high .alert-button) .blink {
80916
- opacity: var(--alarm-blink-off);
81603
+ :is(.flash-slow .alert-button) .blink {
81604
+ opacity: var(--flash-slow-off);
80917
81605
  }
80918
81606
 
80919
- :is(.blinking.alert-type-caution .alert-button,.blinking.alert-type-level-low .alert-button) .visible-wrapper {
80920
- opacity: var(--low-blink-on);
81607
+ :is(.flash-very-slow .alert-button) .visible-wrapper {
81608
+ opacity: var(--flash-very-slow-on);
80921
81609
  }
80922
81610
 
80923
- :is(.blinking.alert-type-caution .alert-button,.blinking.alert-type-level-low .alert-button) .blink {
80924
- opacity: var(--low-blink-off);
81611
+ :is(.flash-very-slow .alert-button) .blink {
81612
+ opacity: var(--flash-very-slow-off);
80925
81613
  }
80926
81614
 
80927
81615
  .counter .alert-button .visible-wrapper,
80928
81616
  .counter .alert-button .blink {
80929
81617
  padding: 0px var(--ui-components-button-padding-horizontal);
80930
- gap: var(--app-components-global-alert-item-counter-spacing);
81618
+ gap: var(--app-components-alert-button-item-counter-spacing);
80931
81619
  }
80932
81620
 
80933
81621
  .alert-type-alarm {
@@ -81495,6 +82183,11 @@ let ObcAlertButton = class extends i$4 {
81495
82183
  this.silenceButtonDisabled = false;
81496
82184
  this.counter = false;
81497
82185
  this.blinking = false;
82186
+ this.flashingSpeed = FlashingSpeed.Default;
82187
+ this.flashing = new FlashingController(
82188
+ this,
82189
+ () => this.resolvedFlashingSpeed
82190
+ );
81498
82191
  this.flatMaxBreakpointPx = 0;
81499
82192
  this.silenceButtonMinBreakpointPx = 0;
81500
82193
  this.width = window.innerWidth;
@@ -81502,16 +82195,22 @@ let ObcAlertButton = class extends i$4 {
81502
82195
  this.width = window.innerWidth;
81503
82196
  };
81504
82197
  }
82198
+ get resolvedFlashingSpeed() {
82199
+ if (!this.blinking || this.nAlerts <= 0 || this.alertType === void 0) {
82200
+ return FlashingSpeed.Fixed;
82201
+ }
82202
+ return resolveFlashingSpeed(
82203
+ this.flashingSpeed,
82204
+ this.alertType,
82205
+ AlertFlashPhase.Active
82206
+ );
82207
+ }
81505
82208
  connectedCallback() {
81506
82209
  super.connectedCallback();
81507
82210
  window.addEventListener("resize", this.resizeListener);
81508
- if (this.hasUpdated) {
81509
- this.installBlinking();
81510
- }
81511
82211
  }
81512
82212
  disconnectedCallback() {
81513
82213
  window.removeEventListener("resize", this.resizeListener);
81514
- this._blinkAnimationCancel?.();
81515
82214
  super.disconnectedCallback();
81516
82215
  }
81517
82216
  renderAlertTwotoneIcon() {
@@ -81573,17 +82272,11 @@ let ObcAlertButton = class extends i$4 {
81573
82272
  get showSilenceButtonDynamic() {
81574
82273
  return this.showSilenceButton && this.width >= this.silenceButtonMinBreakpointPx && this.activeType !== "flat";
81575
82274
  }
81576
- installBlinking() {
81577
- this._blinkAnimationCancel?.();
81578
- this._blinkAnimationCancel = blinkingAll(this);
81579
- }
81580
- updated() {
81581
- this.installBlinking();
81582
- }
81583
82275
  render() {
81584
82276
  const hasAlerts = this.nAlerts > 0;
81585
82277
  const showCounter = this.counter && hasAlerts && this.activeType !== "flat";
81586
- const showBlinking = this.blinking && hasAlerts && this.alertType !== void 0 && supportsBlinking(this.alertType, false);
82278
+ const tempo = this.resolvedFlashingSpeed;
82279
+ const showBlinking = tempo !== FlashingSpeed.Fixed;
81587
82280
  return b`
81588
82281
  <div
81589
82282
  class=${e$1({
@@ -81592,7 +82285,7 @@ let ObcAlertButton = class extends i$4 {
81592
82285
  counter: showCounter,
81593
82286
  "has-silence": this.showSilenceButtonDynamic,
81594
82287
  [`type-${this.activeType}`]: true,
81595
- blinking: showBlinking,
82288
+ [`flash-${tempo}`]: true,
81596
82289
  large: this.large
81597
82290
  })}
81598
82291
  >
@@ -81650,6 +82343,9 @@ __decorateClass$vq([
81650
82343
  __decorateClass$vq([
81651
82344
  n$3({ type: Boolean })
81652
82345
  ], ObcAlertButton.prototype, "blinking", 2);
82346
+ __decorateClass$vq([
82347
+ n$3({ type: String })
82348
+ ], ObcAlertButton.prototype, "flashingSpeed", 2);
81653
82349
  __decorateClass$vq([
81654
82350
  n$3({ type: Number })
81655
82351
  ], ObcAlertButton.prototype, "flatMaxBreakpointPx", 2);
@@ -82709,6 +83405,21 @@ let ObcAlertIcon = class extends i$4 {
82709
83405
  constructor() {
82710
83406
  super(...arguments);
82711
83407
  this.alertType = AlertType.Alarm;
83408
+ this.flashingSpeed = FlashingSpeed.Default;
83409
+ this.flashing = new FlashingController(
83410
+ this,
83411
+ () => this.resolvedFlashingSpeed
83412
+ );
83413
+ }
83414
+ get resolvedFlashingSpeed() {
83415
+ if (this.acknowledged || !this.icon) {
83416
+ return FlashingSpeed.Fixed;
83417
+ }
83418
+ return resolveFlashingSpeed(
83419
+ this.flashingSpeed,
83420
+ this._effectiveType,
83421
+ this.active === false ? AlertFlashPhase.Rectified : AlertFlashPhase.Active
83422
+ );
82712
83423
  }
82713
83424
  get _effectiveType() {
82714
83425
  if (this.type) {
@@ -82872,19 +83583,11 @@ let ObcAlertIcon = class extends i$4 {
82872
83583
  if (!this._effectiveType) {
82873
83584
  return b`<div>No alarm</div>`;
82874
83585
  }
82875
- if (supportsBlinking(this._effectiveType, this.acknowledged ?? false)) {
82876
- const icons = this.icon;
82877
- if (!icons) {
82878
- throw new Error("No icon found");
82879
- }
82880
- const blinkMode = getAlertBlinkMode(this._effectiveType);
83586
+ const tempo = this.resolvedFlashingSpeed;
83587
+ const icons = this.icon;
83588
+ if (tempo !== FlashingSpeed.Fixed && icons) {
82881
83589
  return b`
82882
- <div
82883
- class=${e$1({
82884
- wrapper: true,
82885
- [`blink-${blinkMode}`]: true
82886
- })}
82887
- >
83590
+ <div class=${e$1({ wrapper: true, [`flash-${tempo}`]: true })}>
82888
83591
  <span class="a">${icons.a}</span>
82889
83592
  <span class="b">${icons.b}</span>
82890
83593
  </div>
@@ -82892,31 +83595,6 @@ let ObcAlertIcon = class extends i$4 {
82892
83595
  }
82893
83596
  return b`<div class="wrapper">${this.renderStaticIcon()}</div>`;
82894
83597
  }
82895
- syncBlinking() {
82896
- if (this._blinkAnimationCancel && !supportsBlinking(this._effectiveType, this.acknowledged ?? false)) {
82897
- this._blinkAnimationCancel();
82898
- this._blinkAnimationCancel = void 0;
82899
- }
82900
- if (!this._blinkAnimationCancel && supportsBlinking(this._effectiveType, this.acknowledged ?? false)) {
82901
- this._blinkAnimationCancel = blinkingAll(this);
82902
- }
82903
- }
82904
- connectedCallback() {
82905
- super.connectedCallback();
82906
- if (this.hasUpdated) {
82907
- this.syncBlinking();
82908
- }
82909
- }
82910
- updated() {
82911
- this.syncBlinking();
82912
- }
82913
- disconnectedCallback() {
82914
- super.disconnectedCallback();
82915
- if (this._blinkAnimationCancel) {
82916
- this._blinkAnimationCancel();
82917
- this._blinkAnimationCancel = void 0;
82918
- }
82919
- }
82920
83598
  };
82921
83599
  ObcAlertIcon.styles = i$7`
82922
83600
  .wrapper {
@@ -82943,36 +83621,28 @@ ObcAlertIcon.styles = i$7`
82943
83621
  top: 0;
82944
83622
  left: 0;
82945
83623
  }
82946
- &.blink-alarm .a {
82947
- opacity: var(--alarm-blink-on);
83624
+ &.flash-fast .a {
83625
+ opacity: var(--flash-fast-on);
82948
83626
  }
82949
83627
 
82950
- &.blink-alarm .b {
82951
- opacity: var(--alarm-blink-off);
83628
+ &.flash-fast .b {
83629
+ opacity: var(--flash-fast-off);
82952
83630
  }
82953
83631
 
82954
- &.blink-critical .a {
82955
- opacity: var(--critical-blink-on);
83632
+ &.flash-slow .a {
83633
+ opacity: var(--flash-slow-on);
82956
83634
  }
82957
83635
 
82958
- &.blink-critical .b {
82959
- opacity: var(--critical-blink-off);
83636
+ &.flash-slow .b {
83637
+ opacity: var(--flash-slow-off);
82960
83638
  }
82961
83639
 
82962
- &.blink-warning .a {
82963
- opacity: var(--warning-blink-on);
83640
+ &.flash-very-slow .a {
83641
+ opacity: var(--flash-very-slow-on);
82964
83642
  }
82965
83643
 
82966
- &.blink-warning .b {
82967
- opacity: var(--warning-blink-off);
82968
- }
82969
-
82970
- &.blink-low .a {
82971
- opacity: var(--low-blink-on);
82972
- }
82973
-
82974
- &.blink-low .b {
82975
- opacity: var(--low-blink-off);
83644
+ &.flash-very-slow .b {
83645
+ opacity: var(--flash-very-slow-off);
82976
83646
  }
82977
83647
  }
82978
83648
  `;
@@ -82991,6 +83661,9 @@ __decorateClass$va([
82991
83661
  __decorateClass$va([
82992
83662
  n$3({ type: Boolean })
82993
83663
  ], ObcAlertIcon.prototype, "silenced", 2);
83664
+ __decorateClass$va([
83665
+ n$3({ type: String })
83666
+ ], ObcAlertIcon.prototype, "flashingSpeed", 2);
82994
83667
  ObcAlertIcon = __decorateClass$va([
82995
83668
  customElement("obc-alert-icon")
82996
83669
  ], ObcAlertIcon);
@@ -86114,10 +86787,7 @@ const compentStyle$S = i$7`* {
86114
86787
 
86115
86788
  :host {
86116
86789
  --action-width: 82px;
86117
- --trailing-icon-size: var(
86118
- --app-components-alert-components-general-notification-item-icon-size-large,
86119
- 32px
86120
- );
86790
+ --trailing-icon-size: var(--app-components-message-menu-item-icon-size-large);
86121
86791
  display: block;
86122
86792
  }
86123
86793
 
@@ -94554,8 +95224,6 @@ const componentStyle$Q = i$7`* {
94554
95224
  width: 100%;
94555
95225
  max-width: var(--menu-navigation-components-date-item-touch-target);
94556
95226
  height: var(--menu-navigation-components-date-item-touch-target);
94557
- padding: var(--menu-navigation-components-date-item-padding-vertical)
94558
- var(--menu-navigation-components-date-item-padding-horizontal);
94559
95227
 
94560
95228
  /* Keyboard press visual feedback */
94561
95229
  }
@@ -94925,7 +95593,9 @@ const componentStyle$Q = i$7`* {
94925
95593
  display: flex;
94926
95594
  width: var(--menu-navigation-components-date-item-touch-target, 48px);
94927
95595
  height: var(--menu-navigation-components-date-item-touch-target, 48px);
94928
- padding: var(--menu-navigation-components-date-item-padding-vertical, 8px)
95596
+ /* TODO(designer): Figma pads this frame with Date item/padding-bottom, 12 and 16px in
95597
+ large and xl, less room than the date container needs; 8px fits every size (#929) */
95598
+ padding: 8px
94929
95599
  var(--menu-navigation-components-date-item-padding-horizontal, 8px);
94930
95600
  flex-direction: column;
94931
95601
  justify-content: center;
@@ -103698,8 +104368,8 @@ obc-input::part(input) {
103698
104368
  .key-button {
103699
104369
  display: flex;
103700
104370
  flex: 1 0 0;
103701
- min-width: var(--ui-components-keyboard-numeric-touch-target-size);
103702
- min-height: var(--ui-components-keyboard-numeric-button-size-min);
104371
+ min-width: var(--ui-components-keyboard-button-size-min);
104372
+ min-height: var(--ui-components-keyboard-button-size-min);
103703
104373
  }
103704
104374
 
103705
104375
  obc-button.key-button::part(wrapper) {
@@ -103710,8 +104380,8 @@ obc-button.key-button::part(visible-wrapper) {
103710
104380
  box-sizing: border-box;
103711
104381
  display: flex;
103712
104382
  width: 100%;
103713
- min-width: var(--ui-components-keyboard-numeric-touch-target-size);
103714
- min-height: var(--ui-components-keyboard-numeric-button-size-min);
104383
+ min-width: var(--ui-components-keyboard-button-size-min);
104384
+ min-height: var(--ui-components-keyboard-button-size-min);
103715
104385
  align-items: center;
103716
104386
  justify-content: center;
103717
104387
  align-self: stretch;
@@ -113360,7 +114030,7 @@ const style$1 = i$7`* {
113360
114030
  align-items: center;
113361
114031
  padding: 5px;
113362
114032
  border: 1px solid var(--border-outline-color);
113363
- background-color: var(--enabled-background-color);
114033
+ background-color: var(--container-global-color);
113364
114034
  }
113365
114035
 
113366
114036
  .sequence-toolbar.type-sequential,.sequence-toolbar.type-unordered {
@@ -113376,7 +114046,6 @@ const style$1 = i$7`* {
113376
114046
 
113377
114047
  .sequence-toolbar.type-condensed {
113378
114048
  border-radius: 100px;
113379
- background-color: var(--normal-enabled-background-color);
113380
114049
  }
113381
114050
 
113382
114051
  .sequence-toolbar.type-condensed .condensed-label__current {
@@ -229725,7 +230394,7 @@ const compentStyle$6 = i$7`* {
229725
230394
  "liga" off,
229726
230395
  "clig" off,
229727
230396
  "ss04" on;
229728
- width: var(--obc-instrument-field-tag-width);
230397
+ width: var(--obc-instrument-field-tag-width, auto);
229729
230398
  }
229730
230399
 
229731
230400
  :is(.wrapper .label) .unit {
@@ -229767,7 +230436,7 @@ const compentStyle$6 = i$7`* {
229767
230436
  "ss04" on;
229768
230437
  color: var(--element-neutral-color);
229769
230438
  justify-content: end;
229770
- width: var(--obc-instrument-field-source-width);
230439
+ width: var(--obc-instrument-field-source-width, auto);
229771
230440
  box-sizing: content-box;
229772
230441
  }
229773
230442
 
@@ -240247,6 +240916,7 @@ export {
240247
240916
  AlertCategory,
240248
240917
  AlertType,
240249
240918
  Direction$1 as Direction,
240919
+ FlashingSpeed,
240250
240920
  comparePriorityAlerts,
240251
240921
  formatTimeSince,
240252
240922
  isAcknowledged,