@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.61 → 2.0.0-next.62

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 (181) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +181 -166
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +12 -64
  4. package/dist/icons/icon-03-tidal-stream.js +2 -2
  5. package/dist/icons/icon-03-tidal-stream.js.map +1 -1
  6. package/dist/icons/icon-add-row-above.js +1 -1
  7. package/dist/icons/icon-add-row-above.js.map +1 -1
  8. package/dist/icons/icon-alarm-acknowledged-iec.js +1 -1
  9. package/dist/icons/icon-alarm-acknowledged-iec.js.map +1 -1
  10. package/dist/icons/icon-alarm-emergency-iec.js +2 -2
  11. package/dist/icons/icon-alarm-emergency-iec.js.map +1 -1
  12. package/dist/icons/icon-alarm-rectified-iec.js +1 -1
  13. package/dist/icons/icon-alarm-rectified-iec.js.map +1 -1
  14. package/dist/icons/icon-alarm-silenced-iec.js +2 -2
  15. package/dist/icons/icon-alarm-silenced-iec.js.map +1 -1
  16. package/dist/icons/icon-alarm-unacknowledged-iec.js +2 -2
  17. package/dist/icons/icon-alarm-unacknowledged-iec.js.map +1 -1
  18. package/dist/icons/icon-alert-empty.js +1 -1
  19. package/dist/icons/icon-alert-empty.js.map +1 -1
  20. package/dist/icons/icon-caution-color-iec.js +1 -1
  21. package/dist/icons/icon-caution-color-iec.js.map +1 -1
  22. package/dist/icons/icon-caution-empty.js +1 -1
  23. package/dist/icons/icon-caution-empty.js.map +1 -1
  24. package/dist/icons/icon-connector-corner.js +1 -1
  25. package/dist/icons/icon-connector-corner.js.map +1 -1
  26. package/dist/icons/icon-connector-straight.js +1 -1
  27. package/dist/icons/icon-connector-straight.js.map +1 -1
  28. package/dist/icons/icon-connector-threeway.js +1 -1
  29. package/dist/icons/icon-connector-threeway.js.map +1 -1
  30. package/dist/icons/icon-light-rain-showers-night-colour.js +2 -2
  31. package/dist/icons/icon-light-rain-showers-night-colour.js.map +1 -1
  32. package/dist/icons/icon-rain-showers-night.js +2 -2
  33. package/dist/icons/icon-rain-showers-night.js.map +1 -1
  34. package/dist/icons/icon-simplified-buoy-default.js +2 -2
  35. package/dist/icons/icon-simplified-buoy-default.js.map +1 -1
  36. package/dist/icons/icon-simplified-buoy-safe-water.js +2 -2
  37. package/dist/icons/icon-simplified-buoy-safe-water.js.map +1 -1
  38. package/dist/icons/icon-simplified-buoy-special-purpose.js +2 -2
  39. package/dist/icons/icon-simplified-buoy-special-purpose.js.map +1 -1
  40. package/dist/icons/icon-switch-03-off.js +2 -2
  41. package/dist/icons/icon-switch-03-off.js.map +1 -1
  42. package/dist/icons/icon-switch-horizontal-off-large.js +2 -2
  43. package/dist/icons/icon-switch-horizontal-off-large.js.map +1 -1
  44. package/dist/icons/icon-switch-horizontal-off.js +2 -2
  45. package/dist/icons/icon-switch-horizontal-off.js.map +1 -1
  46. package/dist/icons/icon-vessel-generic-anchored-colour.js +3 -3
  47. package/dist/icons/icon-vessel-generic-anchored-colour.js.map +1 -1
  48. package/dist/icons/icon-vessel-generic-default-colour.js +2 -2
  49. package/dist/icons/icon-vessel-generic-default-colour.js.map +1 -1
  50. package/dist/icons/icon-vessel-generic-fast-colour.js +5 -5
  51. package/dist/icons/icon-vessel-generic-fast-colour.js.map +1 -1
  52. package/dist/icons/icon-vessel-generic-medium-colour.js +4 -4
  53. package/dist/icons/icon-vessel-generic-medium-colour.js.map +1 -1
  54. package/dist/icons/icon-vessel-generic-slow-colour.js +3 -3
  55. package/dist/icons/icon-vessel-generic-slow-colour.js.map +1 -1
  56. package/dist/icons/icon-vessel-generic-stopped-colour.js +4 -4
  57. package/dist/icons/icon-vessel-generic-stopped-colour.js.map +1 -1
  58. package/dist/icons/icon-vessel-type-barge-colour.js +4 -4
  59. package/dist/icons/icon-vessel-type-barge-colour.js.map +1 -1
  60. package/dist/icons/icon-vessel-type-cargo-colour.js +5 -5
  61. package/dist/icons/icon-vessel-type-cargo-colour.js.map +1 -1
  62. package/dist/icons/icon-vessel-type-cruise-colour.js +3 -3
  63. package/dist/icons/icon-vessel-type-cruise-colour.js.map +1 -1
  64. package/dist/icons/icon-vessel-type-fishing-colour.js +4 -4
  65. package/dist/icons/icon-vessel-type-fishing-colour.js.map +1 -1
  66. package/dist/icons/icon-vessel-type-fishing-filled.js +2 -2
  67. package/dist/icons/icon-vessel-type-fishing-filled.js.map +1 -1
  68. package/dist/icons/icon-vessel-type-generic-colour.js +3 -3
  69. package/dist/icons/icon-vessel-type-generic-colour.js.map +1 -1
  70. package/dist/icons/icon-vessel-type-lifeboat-colour.js +4 -4
  71. package/dist/icons/icon-vessel-type-lifeboat-colour.js.map +1 -1
  72. package/dist/icons/icon-vessel-type-military-colour.js +3 -3
  73. package/dist/icons/icon-vessel-type-military-colour.js.map +1 -1
  74. package/dist/icons/icon-vessel-type-motor-boat-colour.js +2 -2
  75. package/dist/icons/icon-vessel-type-motor-boat-colour.js.map +1 -1
  76. package/dist/icons/icon-vessel-type-passenger-colour.js +10 -10
  77. package/dist/icons/icon-vessel-type-passenger-colour.js.map +1 -1
  78. package/dist/icons/icon-vessel-type-pilot-colour.js +5 -5
  79. package/dist/icons/icon-vessel-type-pilot-colour.js.map +1 -1
  80. package/dist/icons/icon-vessel-type-psv-colour.js +5 -5
  81. package/dist/icons/icon-vessel-type-psv-colour.js.map +1 -1
  82. package/dist/icons/icon-vessel-type-sailing-colour.js +2 -2
  83. package/dist/icons/icon-vessel-type-sailing-colour.js.map +1 -1
  84. package/dist/icons/icon-vessel-type-sar-colour.js +3 -3
  85. package/dist/icons/icon-vessel-type-sar-colour.js.map +1 -1
  86. package/dist/icons/icon-vessel-type-smallcraft-colour.js +2 -2
  87. package/dist/icons/icon-vessel-type-smallcraft-colour.js.map +1 -1
  88. package/dist/icons/icon-vessel-type-speed-craft-colour.js +2 -2
  89. package/dist/icons/icon-vessel-type-speed-craft-colour.js.map +1 -1
  90. package/dist/icons/icon-vessel-type-tanker-colour.js +5 -5
  91. package/dist/icons/icon-vessel-type-tanker-colour.js.map +1 -1
  92. package/dist/icons/icon-vessel-type-tug-colour.js +4 -4
  93. package/dist/icons/icon-vessel-type-tug-colour.js.map +1 -1
  94. package/dist/icons/icon-vessel-type-unknown-colour.js +3 -3
  95. package/dist/icons/icon-vessel-type-unknown-colour.js.map +1 -1
  96. package/dist/icons/icon-warning-acknowledged-iec.js +1 -1
  97. package/dist/icons/icon-warning-acknowledged-iec.js.map +1 -1
  98. package/dist/icons/icon-warning-empty.js +1 -1
  99. package/dist/icons/icon-warning-empty.js.map +1 -1
  100. package/dist/icons/icon-warning-noack-iec.js +2 -2
  101. package/dist/icons/icon-warning-noack-iec.js.map +1 -1
  102. package/dist/icons/icon-warning-rectified-iec.js +1 -1
  103. package/dist/icons/icon-warning-rectified-iec.js.map +1 -1
  104. package/dist/icons/icon-warning-silenced-iec.js +1 -1
  105. package/dist/icons/icon-warning-silenced-iec.js.map +1 -1
  106. package/dist/icons/icon-warning-transferred-iec.js +1 -1
  107. package/dist/icons/icon-warning-transferred-iec.js.map +1 -1
  108. package/dist/icons/icon-warning-unacknowledged-iec.js +1 -1
  109. package/dist/icons/icon-warning-unacknowledged-iec.js.map +1 -1
  110. package/dist/integration-systems/integration-vessel-menu/integration-vessel-menu.css.js +34 -9
  111. package/dist/integration-systems/integration-vessel-menu/integration-vessel-menu.css.js.map +1 -1
  112. package/dist/integration-systems/integration-vessel-menu/integration-vessel-menu.d.ts +3 -16
  113. package/dist/integration-systems/integration-vessel-menu/integration-vessel-menu.d.ts.map +1 -1
  114. package/dist/integration-systems/integration-vessel-menu/integration-vessel-menu.js +14 -24
  115. package/dist/integration-systems/integration-vessel-menu/integration-vessel-menu.js.map +1 -1
  116. package/dist/openbridge.css +237 -65
  117. package/package.json +3 -2
  118. package/script/check-css-variables.ts +1 -8
  119. package/script/check-icon-hex-leaks.ts +70 -0
  120. package/script/convert-icons.ts +79 -8
  121. package/script/download-alert-icons.ts +13 -0
  122. package/script/download-icons.ts +53 -14
  123. package/script/figmavariables.json +18 -1
  124. package/src/icons/icon-03-tidal-stream.ts +2 -2
  125. package/src/icons/icon-add-row-above.ts +1 -1
  126. package/src/icons/icon-alarm-acknowledged-iec.ts +1 -1
  127. package/src/icons/icon-alarm-emergency-iec.ts +2 -2
  128. package/src/icons/icon-alarm-rectified-iec.ts +1 -1
  129. package/src/icons/icon-alarm-silenced-iec.ts +2 -2
  130. package/src/icons/icon-alarm-unacknowledged-iec.ts +2 -2
  131. package/src/icons/icon-alert-empty.ts +1 -1
  132. package/src/icons/icon-caution-color-iec.ts +1 -1
  133. package/src/icons/icon-caution-empty.ts +1 -1
  134. package/src/icons/icon-connector-corner.ts +1 -1
  135. package/src/icons/icon-connector-straight.ts +1 -1
  136. package/src/icons/icon-connector-threeway.ts +1 -1
  137. package/src/icons/icon-light-rain-showers-night-colour.ts +2 -2
  138. package/src/icons/icon-rain-showers-night.ts +2 -2
  139. package/src/icons/icon-simplified-buoy-default.ts +2 -2
  140. package/src/icons/icon-simplified-buoy-safe-water.ts +2 -2
  141. package/src/icons/icon-simplified-buoy-special-purpose.ts +2 -2
  142. package/src/icons/icon-switch-03-off.ts +2 -2
  143. package/src/icons/icon-switch-horizontal-off-large.ts +2 -2
  144. package/src/icons/icon-switch-horizontal-off.ts +2 -2
  145. package/src/icons/icon-vessel-generic-anchored-colour.ts +3 -3
  146. package/src/icons/icon-vessel-generic-default-colour.ts +2 -2
  147. package/src/icons/icon-vessel-generic-fast-colour.ts +5 -5
  148. package/src/icons/icon-vessel-generic-medium-colour.ts +4 -4
  149. package/src/icons/icon-vessel-generic-slow-colour.ts +3 -3
  150. package/src/icons/icon-vessel-generic-stopped-colour.ts +4 -4
  151. package/src/icons/icon-vessel-type-barge-colour.ts +4 -4
  152. package/src/icons/icon-vessel-type-cargo-colour.ts +5 -5
  153. package/src/icons/icon-vessel-type-cruise-colour.ts +3 -3
  154. package/src/icons/icon-vessel-type-fishing-colour.ts +4 -4
  155. package/src/icons/icon-vessel-type-fishing-filled.ts +2 -2
  156. package/src/icons/icon-vessel-type-generic-colour.ts +3 -3
  157. package/src/icons/icon-vessel-type-lifeboat-colour.ts +4 -4
  158. package/src/icons/icon-vessel-type-military-colour.ts +3 -3
  159. package/src/icons/icon-vessel-type-motor-boat-colour.ts +2 -2
  160. package/src/icons/icon-vessel-type-passenger-colour.ts +10 -10
  161. package/src/icons/icon-vessel-type-pilot-colour.ts +5 -5
  162. package/src/icons/icon-vessel-type-psv-colour.ts +5 -5
  163. package/src/icons/icon-vessel-type-sailing-colour.ts +2 -2
  164. package/src/icons/icon-vessel-type-sar-colour.ts +3 -3
  165. package/src/icons/icon-vessel-type-smallcraft-colour.ts +2 -2
  166. package/src/icons/icon-vessel-type-speed-craft-colour.ts +2 -2
  167. package/src/icons/icon-vessel-type-tanker-colour.ts +5 -5
  168. package/src/icons/icon-vessel-type-tug-colour.ts +4 -4
  169. package/src/icons/icon-vessel-type-unknown-colour.ts +3 -3
  170. package/src/icons/icon-warning-acknowledged-iec.ts +1 -1
  171. package/src/icons/icon-warning-empty.ts +1 -1
  172. package/src/icons/icon-warning-noack-iec.ts +2 -2
  173. package/src/icons/icon-warning-rectified-iec.ts +1 -1
  174. package/src/icons/icon-warning-silenced-iec.ts +1 -1
  175. package/src/icons/icon-warning-transferred-iec.ts +1 -1
  176. package/src/icons/icon-warning-unacknowledged-iec.ts +1 -1
  177. package/src/integration-systems/integration-bar/integration-bar.stories.ts +69 -40
  178. package/src/integration-systems/integration-vessel-menu/integration-vessel-menu.css +33 -9
  179. package/src/integration-systems/integration-vessel-menu/integration-vessel-menu.stories.ts +54 -25
  180. package/src/integration-systems/integration-vessel-menu/integration-vessel-menu.ts +14 -38
  181. package/src/palettes/variables.css +237 -65
@@ -2711,8 +2711,10 @@
2711
2711
  --pui-components-border-radius-button: 6px;
2712
2712
  --pui-components-border-radius-cutout: 7px;
2713
2713
  --pui-components-line-thickness-min: 1px;
2714
- --pui-components-button-container-height: 56px;
2714
+ --pui-components-button-button-size-min: 48px;
2715
2715
  --pui-components-indicator-container-height: 24px;
2716
+ --pui-components-button-button-size: 52px;
2717
+ --pui-components-indicator-container-padding-vertical: 4px;
2716
2718
  }
2717
2719
  .obc-component-size-medium {
2718
2720
  --global-size-spacing-touch-target-min: 56px;
@@ -5344,8 +5346,10 @@
5344
5346
  --pui-components-border-radius-button: 8px;
5345
5347
  --pui-components-border-radius-cutout: 10px;
5346
5348
  --pui-components-line-thickness-min: 2px;
5347
- --pui-components-button-container-height: 56px;
5349
+ --pui-components-button-button-size-min: 56px;
5348
5350
  --pui-components-indicator-container-height: 32px;
5351
+ --pui-components-button-button-size: 56px;
5352
+ --pui-components-indicator-container-padding-vertical: 4px;
5349
5353
  }
5350
5354
  .obc-component-size-large {
5351
5355
  --global-size-spacing-touch-target-min: 72px;
@@ -7967,8 +7971,10 @@
7967
7971
  --pui-components-border-radius-button: 12px;
7968
7972
  --pui-components-border-radius-cutout: 14px;
7969
7973
  --pui-components-line-thickness-min: 2px;
7970
- --pui-components-button-container-height: 72px;
7974
+ --pui-components-button-button-size-min: 72px;
7971
7975
  --pui-components-indicator-container-height: 32px;
7976
+ --pui-components-button-button-size: 72px;
7977
+ --pui-components-indicator-container-padding-vertical: 32px;
7972
7978
  }
7973
7979
  .obc-component-size-xl {
7974
7980
  --global-size-spacing-touch-target-min: 96px;
@@ -10608,58 +10614,12 @@
10608
10614
  --pui-components-border-radius-button: 16px;
10609
10615
  --pui-components-border-radius-cutout: 18px;
10610
10616
  --pui-components-line-thickness-min: 2px;
10611
- --pui-components-button-container-height: 96px;
10617
+ --pui-components-button-button-size-min: 96px;
10612
10618
  --pui-components-indicator-container-height: 48px;
10619
+ --pui-components-button-button-size: 96px;
10620
+ --pui-components-indicator-container-padding-vertical: 48px;
10613
10621
  }
10614
10622
  * {
10615
- --typography-primitives-font-family-main: "Noto Sans";
10616
- --typography-primitives-font-size-071: 11.5px;
10617
- --typography-primitives-font-size-100: 16px;
10618
- --typography-primitives-font-size-150: 23px;
10619
- --typography-primitives-font-size-200: 34px;
10620
- --typography-primitives-font-size-250: 39px;
10621
- --typography-primitives-font-size-300: 45px;
10622
- --typography-primitives-font-size-350: 57px;
10623
- --typography-primitives-font-size-400: 68px;
10624
- --typography-primitives-font-size-450: 73px;
10625
- --typography-primitives-font-size-500: 78px;
10626
- --typography-primitives-line-height-071: 16px;
10627
- --typography-primitives-line-height-100: 20px;
10628
- --typography-primitives-line-height-150: 24px;
10629
- --typography-primitives-line-height-200: 32px;
10630
- --typography-primitives-line-height-250: 36px;
10631
- --typography-primitives-line-height-300: 48px;
10632
- --typography-primitives-line-height-350: 36px;
10633
- --typography-primitives-line-height-400: 64px;
10634
- --typography-primitives-line-height-450: 68px;
10635
- --typography-primitives-line-height-500: 72px;
10636
- --typography-primitives-font-weight-300: 370;
10637
- --typography-primitives-font-weight-500: 570;
10638
- --typography-primitives-font-weight-600: 670;
10639
- --typography-primitives-font-weight-200: 270;
10640
- --typography-primitives-font-weight-400: 470;
10641
- --typography-primitives-baseline-offset-071: 0px;
10642
- --typography-primitives-baseline-offset-100: 0px;
10643
- --typography-primitives-baseline-offset-150: 2px;
10644
- --typography-primitives-baseline-offset-200: 2px;
10645
- --typography-primitives-baseline-offset-250: 2px;
10646
- --typography-primitives-baseline-offset-300: 2px;
10647
- --typography-primitives-baseline-offset-350: 4px;
10648
- --typography-primitives-baseline-offset-400: 4px;
10649
- --typography-primitives-baseline-offset-450: 4px;
10650
- --typography-primitives-baseline-offset-500: 4px;
10651
- --typography-primitives-letter-spacing-071: 0px;
10652
- --typography-primitives-letter-spacing-100: 0px;
10653
- --typography-primitives-letter-spacing-150: 0px;
10654
- --typography-primitives-letter-spacing-200: 0.0024999999441206455px;
10655
- --typography-primitives-letter-spacing-250: -0.5px;
10656
- --typography-primitives-letter-spacing-300: -0.5px;
10657
- --typography-primitives-letter-spacing-350: -0.5px;
10658
- --typography-primitives-letter-spacing-400: -1px;
10659
- --typography-primitives-letter-spacing-450: -1px;
10660
- --typography-primitives-letter-spacing-500: -1px;
10661
- --weight-demo: "470";
10662
- --weight-demo-2: 470px;
10663
10623
  --font-size-075: 12px;
10664
10624
  --font-size-100: 16px;
10665
10625
  --font-size-150: 24px;
@@ -10902,6 +10862,103 @@
10902
10862
  --border-radius-br-12: 12px;
10903
10863
  --border-radius-br-16: 16px;
10904
10864
  --border-radius-br-24: 24px;
10865
+ --advice-indicator-padding: var(
10866
+ --instrument-components-advice-indicator-padding-indicator-padding-regular
10867
+ );
10868
+ --watchface-label-container-width: var(
10869
+ --instrument-components-watchface-label-container-size-1
10870
+ );
10871
+ --scale-margin: var(--instrument-components-watchface-scale-margin-regular);
10872
+ --scale-padding: var(--instrument-components-watchface-scale-padding-regular);
10873
+ --scale-size: var(--instrument-components-watchface-scale-size-regular);
10874
+ --tick-mark-main: var(
10875
+ --instrument-components-watchface-tick-marks-length-main-regular
10876
+ );
10877
+ --tick-mark-primary: var(
10878
+ --instrument-components-watchface-tick-marks-length-primary-regular
10879
+ );
10880
+ --tick-mark-secondary: var(
10881
+ --instrument-components-watchface-tick-marks-length-secondary-regular
10882
+ );
10883
+ --tick-mark-tertiary: var(
10884
+ --instrument-components-watchface-tick-marks-length-tertiary-regular
10885
+ );
10886
+ --frame-thickness: var(
10887
+ --instrument-components-watchface-frame-regular-thickness
10888
+ );
10889
+ --frame-outer-margin: var(
10890
+ --instrument-components-watchface-frame-regular-outer-margin
10891
+ );
10892
+ --frame-border-radius: var(
10893
+ --instrument-components-watchface-frame-regular-border-radius
10894
+ );
10895
+ --frame-double-thickness: var(
10896
+ --instrument-components-watchface-frame-regular-double-thickness
10897
+ );
10898
+ --frame-track-size: var(
10899
+ --instrument-components-watchface-frame-regular-track-size
10900
+ );
10901
+ --typography-font-weight-regular: var(--day-typography-font-weight-regular);
10902
+ --watchface-label-margin-size: var(
10903
+ --instrument-components-watchface-label-margin-size-1
10904
+ );
10905
+ --tick-mark-main-visibility: var(
10906
+ --instrument-components-watchface-tick-marks-visibility-main-regular
10907
+ );
10908
+ --tick-mark-primary-visibility: var(
10909
+ --instrument-components-watchface-tick-marks-visibility-primary-regular
10910
+ );
10911
+ --tick-mark-secondary-visibility: var(
10912
+ --instrument-components-watchface-tick-marks-visibility-secondary-regular
10913
+ );
10914
+ --tick-mark-tertiary-visibility: var(
10915
+ --instrument-components-watchface-tick-marks-visibility-tertiary-regular
10916
+ );
10917
+ --advice-indicator-visibility: var(
10918
+ --instrument-components-advice-indicator-visibility-indicator-visibility-regular
10919
+ );
10920
+ --scale-framed-size: var(
10921
+ --instrument-components-watchface-scale-size-framed-regular
10922
+ );
10923
+ --advice-indicator-offset: var(
10924
+ --instrument-components-advice-indicator-offset-offset-regular
10925
+ );
10926
+ --advice-indicator-container-size: var(
10927
+ --instrument-components-advice-indicator-container-size-size-regular
10928
+ );
10929
+ --frame-track-margin: var(
10930
+ --instrument-components-watchface-frame-regular-track-margin
10931
+ );
10932
+ --typography-font-weight-semibold: var(--day-typography-font-weight-semibold);
10933
+ --typography-primitives-font-size-071: 11.5px;
10934
+ --typography-primitives-font-weight-300: 370;
10935
+ --typography-primitives-line-height-071: 16px;
10936
+ --typography-primitives-baseline-offset-071: 0px;
10937
+ --typography-primitives-letter-spacing-071: 0px;
10938
+ --typography-primitives-font-weight-500: 570;
10939
+ --typography-primitives-font-weight-600: 670;
10940
+ --typography-primitives-font-size-100: 16.5px;
10941
+ --typography-primitives-line-height-100: 20px;
10942
+ --typography-primitives-baseline-offset-100: 0px;
10943
+ --typography-primitives-letter-spacing-100: 0px;
10944
+ --typography-primitives-font-size-150: 23px;
10945
+ --typography-primitives-line-height-150: 24px;
10946
+ --typography-primitives-baseline-offset-150: 2px;
10947
+ --typography-primitives-letter-spacing-150: 0px;
10948
+ --typography-primitives-font-size-200: 34px;
10949
+ --typography-primitives-line-height-200: 32px;
10950
+ --typography-primitives-baseline-offset-200: 2px;
10951
+ --typography-primitives-letter-spacing-200: 0.0024999999441206455px;
10952
+ --typography-primitives-font-size-300: 45px;
10953
+ --typography-primitives-line-height-300: 40px;
10954
+ --typography-primitives-baseline-offset-300: 2px;
10955
+ --typography-primitives-letter-spacing-300: -0.5px;
10956
+ --typography-primitives-font-size-400: 68px;
10957
+ --typography-primitives-line-height-400: 64px;
10958
+ --typography-primitives-baseline-offset-400: 4px;
10959
+ --typography-primitives-letter-spacing-400: -1px;
10960
+ --day-typography-font-weight-regular: 370;
10961
+ --day-typography-font-weight-semibold: 570;
10905
10962
  --shadow-flat: var(--shadow-flat-x) var(--shadow-flat-y)
10906
10963
  var(--shadow-flat-blur) var(--shadow-flat-spread) var(--shadow-flat-color);
10907
10964
  --shadow-raised: var(--shadow-raised-x) var(--shadow-raised-y)
@@ -11764,7 +11821,7 @@
11764
11821
  --alert-caution-tint-color: rgb(251, 219, 1, 0.15000000596046448);
11765
11822
  --alert-running-tint-color: rgb(22, 155, 13, 0.11999999731779099);
11766
11823
  --integration-container-container: rgb(30, 30, 30);
11767
- --pui-beta-normal-background-color: rgb(31, 31, 31);
11824
+ --pui-beta-opaque-cap-regular-background-color: rgb(31, 31, 31);
11768
11825
  --pui-beta-effect-button-highlight-color: rgb(
11769
11826
  255,
11770
11827
  255,
@@ -11772,10 +11829,10 @@
11772
11829
  0.10000000149011612
11773
11830
  );
11774
11831
  --pui-beta-effect-button-edge-color: rgb(255, 255, 255, 0.03999999910593033);
11775
- --pui-beta-normal-content-color: rgb(217, 217, 217);
11776
- --pui-beta-emergency-background-color: rgb(56, 21, 21);
11832
+ --pui-beta-opaque-backlight-active-color: rgb(240, 240, 240);
11833
+ --pui-beta-opaque-cap-emergency-background-color: rgb(56, 21, 21);
11777
11834
  --pui-beta-emergency-content-color: rgb(180, 180, 180);
11778
- --pui-beta-element-neutral-color: rgb(149, 149, 149);
11835
+ --pui-beta-element-neutral-color: rgb(163, 163, 163);
11779
11836
  --pui-beta-element-active-color: rgb(217, 217, 217);
11780
11837
  --pui-beta-element-inactive-color: rgb(117, 117, 117);
11781
11838
  --pui-beta-element-symbol-color: rgb(89, 89, 89);
@@ -11814,6 +11871,46 @@
11814
11871
  --base-automation-enhanced-500: rgb(45, 84, 139);
11815
11872
  --base-automation-enhanced-600: rgb(29, 60, 103);
11816
11873
  --base-automation-enhanced-050-tint: rgb(10, 100, 237, 0.10999999940395355);
11874
+ --pui-beta-translucent-backlight-regular-color: rgb(117, 117, 117);
11875
+ --pui-beta-translucent-content-regular-color: rgb(31, 31, 31);
11876
+ --pui-beta-translucent-backlight-alarm-color: rgb(255, 77, 71);
11877
+ --pui-beta-opaque-backlight-alarm-color: rgb(255, 77, 71);
11878
+ --pui-beta-translucent-content-color-enhanced: rgb(217, 217, 217);
11879
+ --pui-beta-opaque-backlight-enhanced-color: rgb(124, 169, 233);
11880
+ --pui-beta-opaque-backlight-running-color: rgb(57, 162, 52);
11881
+ --pui-beta-opaque-backlight-warning-color: rgb(255, 135, 42);
11882
+ --pui-beta-opaque-backlight-caution-color: rgb(232, 179, 0);
11883
+ --pui-beta-opaque-backlight-neutral-color: rgb(180, 180, 180);
11884
+ --pui-beta-translucent-backlight-warning-color: rgb(233, 103, 0);
11885
+ --pui-beta-translucent-backlight-caution-color: rgb(232, 179, 0);
11886
+ --pui-beta-translucent-backlight-enhanced-color: rgb(93, 143, 213);
11887
+ --pui-beta-translucent-backlight-running-color: rgb(57, 162, 52);
11888
+ --pui-beta-translucent-backlight-active-color: rgb(180, 180, 180);
11889
+ --pui-beta-translucent-cap-regular-background-color: rgb(
11890
+ 255,
11891
+ 255,
11892
+ 255,
11893
+ 0.10000000149011612
11894
+ );
11895
+ --pui-beta-translucent-cap-regular-border-color: rgb(
11896
+ 255,
11897
+ 255,
11898
+ 255,
11899
+ 0.20000000298023224
11900
+ );
11901
+ --pui-beta-alert-running-color: rgb(57, 162, 52);
11902
+ --pui-beta-alert-running-outline-color: rgb(57, 162, 52);
11903
+ --pui-beta-alert-caution-color: rgb(232, 179, 0);
11904
+ --pui-beta-alert-warning-color: rgb(233, 103, 0);
11905
+ --pui-beta-alert-enhanced-color: rgb(93, 143, 213);
11906
+ --pui-beta-element-enhanced-active-color: rgb(156, 193, 245);
11907
+ --pui-beta-element-enhanced-neutral-color: rgb(93, 143, 213);
11908
+ --pui-beta-border-indicator-edge-color: rgb(
11909
+ 255,
11910
+ 255,
11911
+ 255,
11912
+ 0.20999999344348907
11913
+ );
11817
11914
  }
11818
11915
  :root[data-obc-theme="dusk"] {
11819
11916
  --icon-02-chevron-up: url('data:image/svg+xml,<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 14.0002L7.41 15.4102L12 10.8302L16.59 15.4102L18 14.0002L12 8.00016L6 14.0002Z" fill="rgba(255, 255, 255, .550)"/></svg>');
@@ -12699,11 +12796,11 @@
12699
12796
  --alert-caution-tint-color: rgb(239, 185, 0, 0.10000000149011612);
12700
12797
  --alert-running-tint-color: rgb(25, 129, 0, 0.11999999731779099);
12701
12798
  --integration-container-container: rgb(0, 0, 0);
12702
- --pui-beta-normal-background-color: rgb(255, 255, 255);
12799
+ --pui-beta-opaque-cap-regular-background-color: rgb(255, 255, 255);
12703
12800
  --pui-beta-effect-button-highlight-color: rgb(255, 255, 255);
12704
12801
  --pui-beta-effect-button-edge-color: rgb(255, 255, 255);
12705
- --pui-beta-normal-content-color: rgb(255, 255, 255);
12706
- --pui-beta-emergency-background-color: rgb(255, 255, 255);
12802
+ --pui-beta-opaque-backlight-active-color: rgb(255, 255, 255);
12803
+ --pui-beta-opaque-cap-emergency-background-color: rgb(255, 255, 255);
12707
12804
  --pui-beta-emergency-content-color: rgb(255, 255, 255);
12708
12805
  --pui-beta-element-neutral-color: rgb(255, 255, 255);
12709
12806
  --pui-beta-element-active-color: rgb(255, 255, 255);
@@ -12744,6 +12841,31 @@
12744
12841
  --base-automation-enhanced-500: rgb(43, 56, 73);
12745
12842
  --base-automation-enhanced-600: rgb(35, 46, 60);
12746
12843
  --base-automation-enhanced-050-tint: rgb(62, 146, 254, 0.12999999523162842);
12844
+ --pui-beta-translucent-backlight-regular-color: rgb(255, 255, 255);
12845
+ --pui-beta-translucent-content-regular-color: rgb(255, 255, 255);
12846
+ --pui-beta-translucent-backlight-alarm-color: rgb(255, 255, 255);
12847
+ --pui-beta-opaque-backlight-alarm-color: rgb(255, 255, 255);
12848
+ --pui-beta-translucent-content-color-enhanced: rgb(255, 255, 255);
12849
+ --pui-beta-opaque-backlight-enhanced-color: rgb(255, 255, 255);
12850
+ --pui-beta-opaque-backlight-running-color: rgb(255, 255, 255);
12851
+ --pui-beta-opaque-backlight-warning-color: rgb(255, 255, 255);
12852
+ --pui-beta-opaque-backlight-caution-color: rgb(255, 255, 255);
12853
+ --pui-beta-opaque-backlight-neutral-color: rgb(255, 255, 255);
12854
+ --pui-beta-translucent-backlight-warning-color: rgb(255, 255, 255);
12855
+ --pui-beta-translucent-backlight-caution-color: rgb(255, 255, 255);
12856
+ --pui-beta-translucent-backlight-enhanced-color: rgb(255, 255, 255);
12857
+ --pui-beta-translucent-backlight-running-color: rgb(255, 255, 255);
12858
+ --pui-beta-translucent-backlight-active-color: rgb(255, 255, 255);
12859
+ --pui-beta-translucent-cap-regular-background-color: rgb(255, 255, 255);
12860
+ --pui-beta-translucent-cap-regular-border-color: rgb(255, 255, 255);
12861
+ --pui-beta-alert-running-color: rgb(255, 255, 255);
12862
+ --pui-beta-alert-running-outline-color: rgb(255, 255, 255);
12863
+ --pui-beta-alert-caution-color: rgb(255, 255, 255);
12864
+ --pui-beta-alert-warning-color: rgb(255, 255, 255);
12865
+ --pui-beta-alert-enhanced-color: rgb(255, 255, 255);
12866
+ --pui-beta-element-enhanced-active-color: rgb(255, 255, 255);
12867
+ --pui-beta-element-enhanced-neutral-color: rgb(255, 255, 255);
12868
+ --pui-beta-border-indicator-edge-color: rgb(255, 255, 255);
12747
12869
  }
12748
12870
  :root[data-obc-theme="night"] {
12749
12871
  --icon-02-chevron-up: url('data:image/svg+xml,<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 14.0002L7.41 15.4102L12 10.8302L16.59 15.4102L18 14.0002L12 8.00016L6 14.0002Z" fill="rgb(51, 51, 0)"/></svg>');
@@ -13574,11 +13696,11 @@
13574
13696
  --alert-caution-tint-color: rgb(37, 29, 0);
13575
13697
  --alert-running-tint-color: rgb(0, 24, 0);
13576
13698
  --integration-container-container: rgb(0, 0, 0);
13577
- --pui-beta-normal-background-color: rgb(255, 255, 255);
13699
+ --pui-beta-opaque-cap-regular-background-color: rgb(255, 255, 255);
13578
13700
  --pui-beta-effect-button-highlight-color: rgb(255, 255, 255);
13579
13701
  --pui-beta-effect-button-edge-color: rgb(255, 255, 255);
13580
- --pui-beta-normal-content-color: rgb(255, 255, 255);
13581
- --pui-beta-emergency-background-color: rgb(255, 255, 255);
13702
+ --pui-beta-opaque-backlight-active-color: rgb(255, 255, 255);
13703
+ --pui-beta-opaque-cap-emergency-background-color: rgb(255, 255, 255);
13582
13704
  --pui-beta-emergency-content-color: rgb(255, 255, 255);
13583
13705
  --pui-beta-element-neutral-color: rgb(255, 255, 255);
13584
13706
  --pui-beta-element-active-color: rgb(255, 255, 255);
@@ -13619,6 +13741,31 @@
13619
13741
  --base-automation-enhanced-500: rgb(23, 30, 42);
13620
13742
  --base-automation-enhanced-600: rgb(14, 19, 28);
13621
13743
  --base-automation-enhanced-050-tint: rgb(14, 19, 28);
13744
+ --pui-beta-translucent-backlight-regular-color: rgb(255, 255, 255);
13745
+ --pui-beta-translucent-content-regular-color: rgb(255, 255, 255);
13746
+ --pui-beta-translucent-backlight-alarm-color: rgb(255, 255, 255);
13747
+ --pui-beta-opaque-backlight-alarm-color: rgb(255, 255, 255);
13748
+ --pui-beta-translucent-content-color-enhanced: rgb(255, 255, 255);
13749
+ --pui-beta-opaque-backlight-enhanced-color: rgb(255, 255, 255);
13750
+ --pui-beta-opaque-backlight-running-color: rgb(255, 255, 255);
13751
+ --pui-beta-opaque-backlight-warning-color: rgb(255, 255, 255);
13752
+ --pui-beta-opaque-backlight-caution-color: rgb(255, 255, 255);
13753
+ --pui-beta-opaque-backlight-neutral-color: rgb(255, 255, 255);
13754
+ --pui-beta-translucent-backlight-warning-color: rgb(255, 255, 255);
13755
+ --pui-beta-translucent-backlight-caution-color: rgb(255, 255, 255);
13756
+ --pui-beta-translucent-backlight-enhanced-color: rgb(255, 255, 255);
13757
+ --pui-beta-translucent-backlight-running-color: rgb(255, 255, 255);
13758
+ --pui-beta-translucent-backlight-active-color: rgb(255, 255, 255);
13759
+ --pui-beta-translucent-cap-regular-background-color: rgb(255, 255, 255);
13760
+ --pui-beta-translucent-cap-regular-border-color: rgb(255, 255, 255);
13761
+ --pui-beta-alert-running-color: rgb(255, 255, 255);
13762
+ --pui-beta-alert-running-outline-color: rgb(255, 255, 255);
13763
+ --pui-beta-alert-caution-color: rgb(255, 255, 255);
13764
+ --pui-beta-alert-warning-color: rgb(255, 255, 255);
13765
+ --pui-beta-alert-enhanced-color: rgb(255, 255, 255);
13766
+ --pui-beta-element-enhanced-active-color: rgb(255, 255, 255);
13767
+ --pui-beta-element-enhanced-neutral-color: rgb(255, 255, 255);
13768
+ --pui-beta-border-indicator-edge-color: rgb(255, 255, 255);
13622
13769
  }
13623
13770
  :root[data-obc-theme="bright"] {
13624
13771
  --icon-02-chevron-up: url('data:image/svg+xml,<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6 14.0002L7.41 15.4102L12 10.8302L16.59 15.4102L18 14.0002L12 8.00016L6 14.0002Z" fill="rgba(0, 0, 0, .650)"/></svg>');
@@ -14464,11 +14611,11 @@
14464
14611
  --alert-caution-tint-color: rgb(253, 242, 165);
14465
14612
  --alert-running-tint-color: rgb(6, 131, 6);
14466
14613
  --integration-container-container: rgb(0, 0, 0);
14467
- --pui-beta-normal-background-color: rgb(255, 255, 255);
14614
+ --pui-beta-opaque-cap-regular-background-color: rgb(255, 255, 255);
14468
14615
  --pui-beta-effect-button-highlight-color: rgb(255, 255, 255);
14469
14616
  --pui-beta-effect-button-edge-color: rgb(255, 255, 255);
14470
- --pui-beta-normal-content-color: rgb(255, 255, 255);
14471
- --pui-beta-emergency-background-color: rgb(255, 255, 255);
14617
+ --pui-beta-opaque-backlight-active-color: rgb(255, 255, 255);
14618
+ --pui-beta-opaque-cap-emergency-background-color: rgb(255, 255, 255);
14472
14619
  --pui-beta-emergency-content-color: rgb(255, 255, 255);
14473
14620
  --pui-beta-element-neutral-color: rgb(255, 255, 255);
14474
14621
  --pui-beta-element-active-color: rgb(255, 255, 255);
@@ -14509,6 +14656,31 @@
14509
14656
  --base-automation-enhanced-500: rgb(45, 84, 139);
14510
14657
  --base-automation-enhanced-600: rgb(29, 60, 103);
14511
14658
  --base-automation-enhanced-050-tint: rgb(228, 238, 253);
14659
+ --pui-beta-translucent-backlight-regular-color: rgb(255, 255, 255);
14660
+ --pui-beta-translucent-content-regular-color: rgb(255, 255, 255);
14661
+ --pui-beta-translucent-backlight-alarm-color: rgb(255, 255, 255);
14662
+ --pui-beta-opaque-backlight-alarm-color: rgb(255, 255, 255);
14663
+ --pui-beta-translucent-content-color-enhanced: rgb(255, 255, 255);
14664
+ --pui-beta-opaque-backlight-enhanced-color: rgb(255, 255, 255);
14665
+ --pui-beta-opaque-backlight-running-color: rgb(255, 255, 255);
14666
+ --pui-beta-opaque-backlight-warning-color: rgb(255, 255, 255);
14667
+ --pui-beta-opaque-backlight-caution-color: rgb(255, 255, 255);
14668
+ --pui-beta-opaque-backlight-neutral-color: rgb(255, 255, 255);
14669
+ --pui-beta-translucent-backlight-warning-color: rgb(255, 255, 255);
14670
+ --pui-beta-translucent-backlight-caution-color: rgb(255, 255, 255);
14671
+ --pui-beta-translucent-backlight-enhanced-color: rgb(255, 255, 255);
14672
+ --pui-beta-translucent-backlight-running-color: rgb(255, 255, 255);
14673
+ --pui-beta-translucent-backlight-active-color: rgb(255, 255, 255);
14674
+ --pui-beta-translucent-cap-regular-background-color: rgb(255, 255, 255);
14675
+ --pui-beta-translucent-cap-regular-border-color: rgb(255, 255, 255);
14676
+ --pui-beta-alert-running-color: rgb(255, 255, 255);
14677
+ --pui-beta-alert-running-outline-color: rgb(255, 255, 255);
14678
+ --pui-beta-alert-caution-color: rgb(255, 255, 255);
14679
+ --pui-beta-alert-warning-color: rgb(255, 255, 255);
14680
+ --pui-beta-alert-enhanced-color: rgb(255, 255, 255);
14681
+ --pui-beta-element-enhanced-active-color: rgb(255, 255, 255);
14682
+ --pui-beta-element-enhanced-neutral-color: rgb(255, 255, 255);
14683
+ --pui-beta-border-indicator-edge-color: rgb(255, 255, 255);
14512
14684
  }
14513
14685
  @property --alarm-blink-on {
14514
14686
  syntax: "<number>";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oicl/openbridge-webcomponents-full-bundle",
3
- "version": "2.0.0-next.61",
3
+ "version": "2.0.0-next.62",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -140,9 +140,10 @@
140
140
  "typecheck": "tsc --noEmit",
141
141
  "format": "prettier \"**/*.{cjs,html,js,json,md,ts,css}\" --write",
142
142
  "format:check": "prettier \"**/*.{cjs,html,js,json,md,ts,css}\" --check",
143
- "lint": "npm run lint:mixins && npm run lint:variables && npm run lint:lit-analyzer && npm run lint:eslint",
143
+ "lint": "npm run lint:mixins && npm run lint:variables && npm run lint:icons && npm run lint:lit-analyzer && npm run lint:eslint",
144
144
  "lint:mixins": "tsx ./script/check-css-mixins.ts",
145
145
  "lint:variables": "tsx ./script/check-css-variables.ts",
146
+ "lint:icons": "tsx ./script/check-icon-hex-leaks.ts",
146
147
  "lint:eslint": "eslint 'src/**/*.ts'",
147
148
  "lint:lit-analyzer": "lit-analyzer --strict --maxWarnings 0",
148
149
  "fix-imports": "node fix-imports.mjs",
@@ -11,7 +11,7 @@
11
11
  * - Identifies unique variable usages and their locations (including fallback detection).
12
12
  * - Detects duplicate variable definitions (warning).
13
13
  * - Detects usages of undefined variables (error), excluding a predefined set of allowed undefined variables.
14
- * - Skips `src/palettes/variables.css` for usage checks as it is considered a definition-only file.
14
+ * - Scans `src/palettes/variables.css` for `var(...)` usages too: its semantic tokens reference primitives in the same file, so a missing primitive (e.g. a token dropped from the Figma export) would otherwise go undetected.
15
15
  * - Exits with code 1 if any undefined variable usages (without fallbacks) are found.
16
16
  *
17
17
  * Usage Examples:
@@ -106,9 +106,6 @@ async function run(): Promise<void> {
106
106
 
107
107
  for (const file of cssFiles) {
108
108
  const content = fs.readFileSync(file, 'utf8');
109
- const isPaletteFile = file.endsWith(
110
- `${path.sep}src${path.sep}palettes${path.sep}variables.css`
111
- );
112
109
 
113
110
  const definitionRegex = /(^|[;{\s])(\-\-[A-Za-z0-9_-]+)\s*:/gm;
114
111
  for (const match of content.matchAll(definitionRegex)) {
@@ -132,10 +129,6 @@ async function run(): Promise<void> {
132
129
  definitions.set(name, [...(definitions.get(name) ?? []), location]);
133
130
  }
134
131
 
135
- if (isPaletteFile) {
136
- continue;
137
- }
138
-
139
132
  let start = 0;
140
133
  while ((start = content.indexOf('var(', start)) !== -1) {
141
134
  let openParens = 1;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Fails `npm run lint:icons` if any generated icon (`src/icons/*.ts`) still
3
+ * contains a literal hex `fill="#…"` or `stroke="#…"` attribute. Every such
4
+ * attribute indicates one of:
5
+ *
6
+ * 1. A converter regression in `script/convert-icons.ts` (the most recent
7
+ * example: `getSingleColorIcon` originally rewrote `fill` but not
8
+ * `stroke`, leaking raw hex strokes into 27 icons across `obi-alarm-*`,
9
+ * `obi-warning-*`, `obi-connector-*`, etc.).
10
+ * 2. An unbound Figma variable on a fill/stroke. Designers should bind the
11
+ * color in Figma; if the variable id is new, regenerate
12
+ * `script/figmavariables.json` from the obc-figma-plugin and re-run
13
+ * `npm run download:icons`. See `script/.cache/unknown-variables.json`
14
+ * for the per-id diagnostic.
15
+ *
16
+ * The check is intentionally zero-tolerance — there is currently no
17
+ * documented case where an icon legitimately needs a hard-coded hex, because
18
+ * the themed (`iconCss`) variant always uses CSS variables and the
19
+ * single-color (`icon`) variant always uses `currentColor`. If a future
20
+ * legitimate exception arises, prefer adding an explicit allowlist here over
21
+ * reintroducing a sliding budget.
22
+ */
23
+ import * as fs from 'fs';
24
+ import * as path from 'path';
25
+
26
+ const iconsDir = path.resolve('src/icons');
27
+ const hexAttrRegex = /(?:fill|stroke)="#[0-9A-Fa-f]{6,8}"/g;
28
+
29
+ interface Leak {
30
+ file: string;
31
+ attr: string;
32
+ }
33
+
34
+ const leaks: Leak[] = [];
35
+
36
+ for (const file of fs.readdirSync(iconsDir).sort()) {
37
+ if (!file.endsWith('.ts')) continue;
38
+ const text = fs.readFileSync(path.join(iconsDir, file), 'utf8');
39
+ const matches = text.match(hexAttrRegex);
40
+ if (!matches) continue;
41
+ for (const attr of matches) leaks.push({file, attr});
42
+ }
43
+
44
+ if (leaks.length === 0) {
45
+ console.log(
46
+ `[lint:icons] no literal hex fill/stroke attributes in ${iconsDir}`
47
+ );
48
+ process.exit(0);
49
+ }
50
+
51
+ console.error(
52
+ `[lint:icons] found ${leaks.length} literal hex fill/stroke attribute(s) in src/icons/*.ts:`
53
+ );
54
+ for (const {file, attr} of leaks) {
55
+ console.error(` ${file}\t${attr}`);
56
+ }
57
+ console.error('');
58
+ console.error(
59
+ ' Each leak is either (a) a converter regression in script/convert-icons.ts'
60
+ );
61
+ console.error(
62
+ ' or (b) a Figma variable that is not bound on the source fill/stroke.'
63
+ );
64
+ console.error(
65
+ ' See script/.cache/unknown-variables.json for unresolved variable ids,'
66
+ );
67
+ console.error(
68
+ ' and the JSDoc on this script for the full diagnostic checklist.'
69
+ );
70
+ process.exit(1);
@@ -6,25 +6,74 @@ const __dirname = path.dirname(new URL(import.meta.url).pathname);
6
6
  const figmaVariablesPath = path.join(__dirname, 'figmavariables.json');
7
7
  const figmaVariables = JSON.parse(fs.readFileSync(figmaVariablesPath, 'utf8'));
8
8
 
9
+ /**
10
+ * Figma variable IDs encountered on bound fills/strokes that are not present
11
+ * in `figmavariables.json`. These cause the converter to fall back to a
12
+ * literal hex color, which silently defeats the `var(--undefined)` grep gate.
13
+ * Downloaders should serialize this set after a run so designers can extend
14
+ * `figmavariables.json` to cover the missing tokens.
15
+ */
16
+ export const unresolvedFigmaVariables = new Set<string>();
17
+
18
+ function resolveFigmaVariable(variableId: string): string | undefined {
19
+ const token = figmaVariables[variableId];
20
+ if (token === undefined) unresolvedFigmaVariables.add(variableId);
21
+ return token;
22
+ }
23
+
24
+ /**
25
+ * Persist the `unresolvedFigmaVariables` set to disk so designers and CI can
26
+ * see which Figma variable IDs were referenced by icons but missing from
27
+ * `figmavariables.json`. Called by the download scripts after a run. Returns
28
+ * the number of unresolved IDs so the caller can fail the build.
29
+ */
30
+ export function writeUnresolvedFigmaVariablesReport(filePath: string): number {
31
+ const ids = [...unresolvedFigmaVariables].sort();
32
+ const dir = path.dirname(filePath);
33
+ fs.mkdirSync(dir, {recursive: true});
34
+ fs.writeFileSync(filePath, JSON.stringify(ids, null, 2) + '\n');
35
+ if (ids.length > 0) {
36
+ console.warn(
37
+ `[convert-icons] ${ids.length} unresolved Figma variable id(s) — see ${filePath}`
38
+ );
39
+ }
40
+ return ids.length;
41
+ }
42
+
9
43
  dotenv.config();
10
44
 
11
45
  export interface IconRef {
12
46
  name: string;
13
47
  id: string;
14
48
  javascriptName: string;
15
- styles: {[colorCode: string]: {cssClass: string}};
49
+ styles: {[colorCode: string]: {cssClass: string | undefined}};
16
50
  }
17
51
 
18
52
  export function getSingleColorIcon(imageData: string, icon: IconRef): string {
19
53
  // replace fill color with currentColor
20
54
  const fillRegex = /fill="[^"]+"/g;
21
- const replace = 'fill="currentColor"';
22
- let imageDataNew = imageData.replace(fillRegex, replace);
55
+ let imageDataNew = imageData.replace(fillRegex, 'fill="currentColor"');
23
56
 
24
57
  // remove fillOpacity
25
58
  const fillOpacityRegex = /fill-opacity="[^"]+"/g;
26
59
  imageDataNew = imageDataNew.replace(fillOpacityRegex, '');
27
60
 
61
+ // replace stroke color with currentColor (mirror the fill handling so the
62
+ // single-color variant inherits the host color for both paint operations;
63
+ // otherwise raw Figma hex strokes leak through and the icon ignores theme
64
+ // changes / `currentColor`).
65
+ const strokeRegex = /stroke="[^"]+"/g;
66
+ imageDataNew = imageDataNew.replace(strokeRegex, (match) => {
67
+ // Preserve `stroke="none"` so shapes that explicitly disable stroking
68
+ // (common in Figma exports of filled-only paths) stay unstroked.
69
+ if (match === 'stroke="none"') return match;
70
+ return 'stroke="currentColor"';
71
+ });
72
+
73
+ // remove strokeOpacity
74
+ const strokeOpacityRegex = /stroke-opacity="[^"]+"/g;
75
+ imageDataNew = imageDataNew.replace(strokeOpacityRegex, '');
76
+
28
77
  return imageDataNew;
29
78
  }
30
79
 
@@ -88,6 +137,28 @@ export function getCssColorIcon(imageData: string, icon: IconRef): string {
88
137
  const strokeOpacityRegex = /stroke-opacity="[^"]+"/g;
89
138
  imageData = imageData.replace(strokeOpacityRegex, '');
90
139
 
140
+ // Merge sibling `style="…"` attributes on the same element. The fill and
141
+ // stroke passes each emit their own `style="…"` independently, so an
142
+ // element with both attributes ends up with two `style` attributes — only
143
+ // the first is honored by browsers. Combine them into one per opening tag,
144
+ // regardless of whether the two `style` attributes are adjacent or have
145
+ // other attributes between them.
146
+ const tagRegex = /<[a-zA-Z][^>]*>/g;
147
+ const styleAttrRegex = /\s+style="([^"]*)"/g;
148
+ imageData = imageData.replace(tagRegex, (tag) => {
149
+ const styles: string[] = [];
150
+ const stripped = tag.replace(styleAttrRegex, (_m, decls) => {
151
+ const trimmed = decls.trim().replace(/;$/, '');
152
+ if (trimmed) styles.push(trimmed);
153
+ return '';
154
+ });
155
+ if (styles.length <= 1) return tag;
156
+ // Re-insert a single merged style attribute just before the closing `>`
157
+ // (or `/>`), preserving the rest of the tag's structure.
158
+ const merged = ` style="${styles.join('; ')}"`;
159
+ return stripped.replace(/\s*\/?>$/, (end) => merged + end);
160
+ });
161
+
91
162
  return imageData;
92
163
  }
93
164
 
@@ -102,8 +173,8 @@ export function kebabToUpperCamelCase(kebabCase: string): string {
102
173
  export function getStylesForNode(
103
174
  node: Node,
104
175
  styles: {[styleId: string]: Style}
105
- ): {[colorCode: string]: {cssClass: string}} {
106
- let out = {};
176
+ ): {[colorCode: string]: {cssClass: string | undefined}} {
177
+ let out: {[colorCode: string]: {cssClass: string | undefined}} = {};
107
178
 
108
179
  if ('children' in node) {
109
180
  for (const child of node.children) {
@@ -122,7 +193,7 @@ export function getStylesForNode(
122
193
  fils = rgbaToHexOrColorName(fill.color!);
123
194
  if ('boundVariables' in fill) {
124
195
  const variableId = fill.boundVariables.color.id;
125
- out[fils] = {cssClass: figmaVariables[variableId]};
196
+ out[fils] = {cssClass: resolveFigmaVariable(variableId)};
126
197
  }
127
198
  }
128
199
  });
@@ -147,7 +218,7 @@ export function getStylesForNode(
147
218
  strokes = rgbaToHexOrColorName(stroke.color!);
148
219
  if ('boundVariables' in stroke) {
149
220
  const variableId = stroke.boundVariables.color.id;
150
- out[strokes] = {cssClass: figmaVariables[variableId]};
221
+ out[strokes] = {cssClass: resolveFigmaVariable(variableId)};
151
222
  }
152
223
  }
153
224
  });
@@ -167,7 +238,7 @@ export function getStylesForNode(
167
238
  const color = rgbaToHexOrColorName(f.color!);
168
239
  if ('boundVariables' in f) {
169
240
  const variableId = f.boundVariables.color.id;
170
- out[color] = {cssClass: figmaVariables[variableId]};
241
+ out[color] = {cssClass: resolveFigmaVariable(variableId)};
171
242
  }
172
243
  }
173
244
  }