@oicl/openbridge-webcomponents-full-bundle 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.
- package/.storybook/vitest.setup.ts +12 -1
- package/bundle/openbridge-webcomponents.bundle.js +989 -319
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +1514 -77
- package/dist/alert-severity.d.ts +12 -9
- package/dist/alert-severity.d.ts.map +1 -1
- package/dist/alert-severity.js +30 -38
- package/dist/alert-severity.js.map +1 -1
- package/dist/building-blocks/bar-horizontal/bar-horizontal.d.ts +6 -0
- package/dist/building-blocks/bar-horizontal/bar-horizontal.d.ts.map +1 -1
- package/dist/building-blocks/bar-horizontal/bar-horizontal.js +6 -1
- package/dist/building-blocks/bar-horizontal/bar-horizontal.js.map +1 -1
- package/dist/building-blocks/bar-vertical/bar-vertical.d.ts +6 -0
- package/dist/building-blocks/bar-vertical/bar-vertical.d.ts.map +1 -1
- package/dist/building-blocks/bar-vertical/bar-vertical.js +6 -1
- package/dist/building-blocks/bar-vertical/bar-vertical.js.map +1 -1
- package/dist/building-blocks/chart-line/chart-line-base.d.ts +129 -0
- package/dist/building-blocks/chart-line/chart-line-base.d.ts.map +1 -1
- package/dist/building-blocks/chart-line/chart-line-base.js +464 -79
- package/dist/building-blocks/chart-line/chart-line-base.js.map +1 -1
- package/dist/building-blocks/external-scale/external-scale.d.ts +11 -0
- package/dist/building-blocks/external-scale/external-scale.d.ts.map +1 -1
- package/dist/building-blocks/external-scale/external-scale.js +45 -12
- package/dist/building-blocks/external-scale/external-scale.js.map +1 -1
- package/dist/charthelpers/index.d.ts +1 -0
- package/dist/charthelpers/index.d.ts.map +1 -1
- package/dist/charthelpers/index.js +7 -1
- package/dist/charthelpers/index.js.map +1 -1
- package/dist/charthelpers/range-labels.d.ts +55 -0
- package/dist/charthelpers/range-labels.d.ts.map +1 -0
- package/dist/charthelpers/range-labels.js +36 -0
- package/dist/charthelpers/range-labels.js.map +1 -0
- package/dist/components/alert-button/alert-button.css.js +13 -21
- package/dist/components/alert-button/alert-button.css.js.map +1 -1
- package/dist/components/alert-button/alert-button.d.ts +9 -4
- package/dist/components/alert-button/alert-button.d.ts.map +1 -1
- package/dist/components/alert-button/alert-button.js +24 -15
- package/dist/components/alert-button/alert-button.js.map +1 -1
- package/dist/components/alert-frame/alert-frame.css.js +109 -33
- package/dist/components/alert-frame/alert-frame.css.js.map +1 -1
- package/dist/components/alert-frame/alert-frame.d.ts +34 -7
- package/dist/components/alert-frame/alert-frame.d.ts.map +1 -1
- package/dist/components/alert-frame/alert-frame.js +134 -30
- package/dist/components/alert-frame/alert-frame.js.map +1 -1
- package/dist/components/alert-icon/alert-icon.d.ts +10 -7
- package/dist/components/alert-icon/alert-icon.d.ts.map +1 -1
- package/dist/components/alert-icon/alert-icon.js +37 -60
- package/dist/components/alert-icon/alert-icon.js.map +1 -1
- package/dist/components/alert-menu-item/alert-menu-item.css.js +1 -4
- package/dist/components/alert-menu-item/alert-menu-item.css.js.map +1 -1
- package/dist/components/date-item/date-item.css.js +3 -3
- package/dist/components/keyboard-full/keyboard-full.css.js +4 -4
- package/dist/components/message-menu-item/message-menu-item.css.js +2 -6
- package/dist/components/message-menu-item/message-menu-item.css.js.map +1 -1
- package/dist/components/sequence-toolbar/sequence-toolbar.css.js +1 -2
- package/dist/components/sequence-toolbar/sequence-toolbar.css.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/navigation-instruments/gauge-trend/gauge-trend.d.ts +6 -0
- package/dist/navigation-instruments/gauge-trend/gauge-trend.d.ts.map +1 -1
- package/dist/navigation-instruments/gauge-trend/gauge-trend.js +8 -0
- package/dist/navigation-instruments/gauge-trend/gauge-trend.js.map +1 -1
- package/dist/navigation-instruments/instrument-field/instrument-field.css.js +2 -2
- package/dist/navigation-instruments/readout/readout.d.ts.map +1 -1
- package/dist/navigation-instruments/readout/readout.js +2 -1
- package/dist/navigation-instruments/readout/readout.js.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js +2 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
- package/dist/openbridge.css +19 -4
- package/dist/palettes/blinking.d.ts +14 -4
- package/dist/palettes/blinking.d.ts.map +1 -1
- package/dist/palettes/blinking.js +41 -35
- package/dist/palettes/blinking.js.map +1 -1
- package/dist/palettes/flashing-controller.d.ts +21 -0
- package/dist/palettes/flashing-controller.d.ts.map +1 -0
- package/dist/palettes/flashing-controller.js +45 -0
- package/dist/palettes/flashing-controller.js.map +1 -0
- package/dist/svghelpers/index.d.ts +1 -0
- package/dist/svghelpers/index.d.ts.map +1 -1
- package/dist/svghelpers/index.js +2 -0
- package/dist/svghelpers/index.js.map +1 -1
- package/dist/svghelpers/rounded-rect.d.ts +15 -0
- package/dist/svghelpers/rounded-rect.d.ts.map +1 -0
- package/dist/svghelpers/rounded-rect.js +29 -0
- package/dist/svghelpers/rounded-rect.js.map +1 -0
- package/dist/types.d.ts +14 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- package/script/check-css-variables.ts +2 -15
- package/src/alert-severity.spec.ts +56 -0
- package/src/alert-severity.ts +45 -43
- package/src/bars-graphs/area-graph/area-graph.stories.ts +235 -1
- package/src/bars-graphs/line-graph/line-graph.stories.ts +24 -0
- package/src/building-blocks/bar-horizontal/bar-horizontal.ts +7 -0
- package/src/building-blocks/bar-vertical/bar-vertical.ts +7 -0
- package/src/building-blocks/chart-line/chart-line-base.spec.ts +767 -0
- package/src/building-blocks/chart-line/chart-line-base.stories.ts +124 -0
- package/src/building-blocks/chart-line/chart-line-base.ts +671 -97
- package/src/building-blocks/chart-line/chart-sizing-battleground.stories.ts +17 -0
- package/src/building-blocks/external-scale/external-scale.spec.ts +154 -0
- package/src/building-blocks/external-scale/external-scale.ts +78 -20
- package/src/charthelpers/index.ts +1 -0
- package/src/charthelpers/range-labels.spec.ts +46 -0
- package/src/charthelpers/range-labels.ts +93 -0
- package/src/components/alert-button/alert-button.css +10 -23
- package/src/components/alert-button/alert-button.spec.ts +56 -15
- package/src/components/alert-button/alert-button.stories.ts +5 -1
- package/src/components/alert-button/alert-button.ts +33 -24
- package/src/components/alert-frame/alert-flash-scenario.stories.ts +669 -0
- package/src/components/alert-frame/alert-frame.css +106 -33
- package/src/components/alert-frame/alert-frame.spec.ts +176 -17
- package/src/components/alert-frame/alert-frame.stories.ts +61 -0
- package/src/components/alert-frame/alert-frame.ts +179 -41
- package/src/components/alert-icon/alert-icon.spec.ts +82 -27
- package/src/components/alert-icon/alert-icon.stories.ts +7 -1
- package/src/components/alert-icon/alert-icon.ts +48 -74
- package/src/components/alert-menu-item/alert-menu-item.css +1 -4
- package/src/components/date-item/date-item.css +3 -3
- package/src/components/keyboard-full/keyboard-full.css +4 -4
- package/src/components/message-menu-item/message-menu-item.css +2 -6
- package/src/components/sequence-toolbar/sequence-toolbar.css +1 -2
- package/src/navigation-instruments/gauge-trend/gauge-trend.stories.ts +29 -0
- package/src/navigation-instruments/gauge-trend/gauge-trend.ts +11 -0
- package/src/navigation-instruments/instrument-field/instrument-field.css +2 -2
- package/src/navigation-instruments/readout/readout.ts +2 -1
- package/src/navigation-instruments/readout-list-item/readout-list-item.ts +2 -1
- package/src/palettes/blinking.spec.ts +83 -0
- package/src/palettes/blinking.ts +47 -35
- package/src/palettes/flashing-controller.ts +62 -0
- package/src/palettes/manual.css +18 -4
- package/src/svghelpers/index.ts +1 -0
- package/src/svghelpers/rounded-rect.spec.ts +47 -0
- package/src/svghelpers/rounded-rect.ts +42 -0
- package/src/types.ts +20 -0
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
.wrapper {
|
|
18
18
|
--bg-color: var(--alert-alarm-color);
|
|
19
19
|
--thickness: var(--global-size-spacing-border-weight-alertframe);
|
|
20
|
-
|
|
20
|
+
/* 0/1 from the flash-<tempo> classes below; steady when no class applies. */
|
|
21
|
+
--blink-on: 0;
|
|
22
|
+
--blink-off: 1;
|
|
21
23
|
color: var(--on-alarm-active-color);
|
|
22
24
|
position: relative;
|
|
23
25
|
width: 100%;
|
|
@@ -27,10 +29,10 @@
|
|
|
27
29
|
);
|
|
28
30
|
outline: var(--thickness) solid var(--bg-color);
|
|
29
31
|
outline-offset: 0;
|
|
32
|
+
/* +2 px outward while on, both thicknesses (Figma Flash=yes: 2 → 4 px). */
|
|
30
33
|
--blink-width: 2px;
|
|
31
34
|
&.thickness-small {
|
|
32
35
|
--thickness: 2px;
|
|
33
|
-
--blink-width: 1px;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
38
|
&.wrap-content {
|
|
@@ -42,14 +44,64 @@
|
|
|
42
44
|
width: 100%;
|
|
43
45
|
}
|
|
44
46
|
|
|
47
|
+
&.flash-fast {
|
|
48
|
+
--blink-on: var(--flash-fast-on);
|
|
49
|
+
--blink-off: var(--flash-fast-off);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
&.flash-slow {
|
|
53
|
+
--blink-on: var(--flash-slow-on);
|
|
54
|
+
--blink-off: var(--flash-slow-off);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
&.flash-very-slow {
|
|
58
|
+
--blink-on: var(--flash-very-slow-on);
|
|
59
|
+
--blink-off: var(--flash-very-slow-off);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
--flash-transition: 50ms linear;
|
|
63
|
+
|
|
64
|
+
&.flash-effect-outline-eased {
|
|
65
|
+
transition: outline-width var(--flash-transition);
|
|
66
|
+
|
|
67
|
+
.flap {
|
|
68
|
+
transition: box-shadow var(--flash-transition);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.mask {
|
|
72
|
+
transition:
|
|
73
|
+
top var(--flash-transition),
|
|
74
|
+
bottom var(--flash-transition),
|
|
75
|
+
left var(--flash-transition),
|
|
76
|
+
right var(--flash-transition);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.dash path {
|
|
80
|
+
transition: stroke-width var(--flash-transition);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
45
84
|
--blink-width-dynamic: calc(var(--blink-width) * var(--blink-on));
|
|
85
|
+
/* One knob for flap and masks, so they cannot drift apart from the outline. */
|
|
86
|
+
--flap-grow: 0px;
|
|
46
87
|
|
|
47
|
-
&.unacked-active
|
|
88
|
+
&.unacked-active,
|
|
89
|
+
&.unacked-rectified {
|
|
48
90
|
outline-width: calc(var(--thickness) + var(--blink-width-dynamic));
|
|
49
91
|
}
|
|
50
92
|
|
|
93
|
+
&.unacked-active {
|
|
94
|
+
--flap-grow: var(--blink-width-dynamic);
|
|
95
|
+
}
|
|
96
|
+
|
|
51
97
|
&.unacked-rectified {
|
|
52
|
-
|
|
98
|
+
/* The dashed stroke is centred, so it moves out by half its growth. */
|
|
99
|
+
--flap-grow: calc(var(--blink-width-dynamic) / 2);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
&.unacked-rectified {
|
|
103
|
+
/* The dash pattern (12/6) needs an SVG stroke; outlines have no dash array. */
|
|
104
|
+
outline-style: none;
|
|
53
105
|
}
|
|
54
106
|
|
|
55
107
|
&.alarm,
|
|
@@ -61,24 +113,17 @@
|
|
|
61
113
|
&.warning,
|
|
62
114
|
&.level-medium {
|
|
63
115
|
--bg-color: var(--alert-warning-color);
|
|
64
|
-
--blink-on: var(--warning-blink-on);
|
|
65
116
|
color: var(--on-warning-active-color);
|
|
66
117
|
}
|
|
67
118
|
|
|
68
119
|
&.caution,
|
|
69
120
|
&.level-low {
|
|
70
121
|
--bg-color: var(--alert-caution-color);
|
|
71
|
-
--blink-on: 1;
|
|
72
122
|
color: var(--on-caution-active-color);
|
|
73
123
|
}
|
|
74
124
|
|
|
75
|
-
&.level-low {
|
|
76
|
-
--blink-on: var(--low-blink-on);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
125
|
&.level-critical {
|
|
80
126
|
--bg-color: var(--critical-enabled-background-color);
|
|
81
|
-
--blink-on: var(--critical-blink-on);
|
|
82
127
|
color: var(--on-critical-active-color);
|
|
83
128
|
}
|
|
84
129
|
|
|
@@ -132,7 +177,7 @@
|
|
|
132
177
|
width: calc(
|
|
133
178
|
var(--ui-components-button-border-radius) + var(--thickness) + 0.5px
|
|
134
179
|
);
|
|
135
|
-
top:
|
|
180
|
+
top: calc(-1 * var(--flap-grow));
|
|
136
181
|
left: calc(
|
|
137
182
|
-1 * var(--ui-components-button-border-radius) - var(--thickness)
|
|
138
183
|
);
|
|
@@ -143,17 +188,13 @@
|
|
|
143
188
|
calc(100% - var(--thickness)) 50%,
|
|
144
189
|
50% var(--thickness)
|
|
145
190
|
);
|
|
146
|
-
|
|
147
|
-
.unacked-active & {
|
|
148
|
-
top: calc(-1 * var(--blink-width-dynamic));
|
|
149
|
-
}
|
|
150
191
|
}
|
|
151
192
|
|
|
152
193
|
&.down {
|
|
153
194
|
width: calc(
|
|
154
195
|
var(--ui-components-button-border-radius) + var(--thickness) + 0.5px
|
|
155
196
|
);
|
|
156
|
-
bottom:
|
|
197
|
+
bottom: calc(-1 * var(--flap-grow));
|
|
157
198
|
left: calc(
|
|
158
199
|
-1 * var(--ui-components-button-border-radius) - var(--thickness)
|
|
159
200
|
);
|
|
@@ -164,10 +205,6 @@
|
|
|
164
205
|
50% calc(100% - var(--thickness)),
|
|
165
206
|
calc(100% - var(--thickness)) 50%
|
|
166
207
|
);
|
|
167
|
-
|
|
168
|
-
.unacked-active & {
|
|
169
|
-
bottom: calc(-1 * var(--blink-width-dynamic));
|
|
170
|
-
}
|
|
171
208
|
}
|
|
172
209
|
|
|
173
210
|
&.left {
|
|
@@ -177,7 +214,7 @@
|
|
|
177
214
|
top: calc(
|
|
178
215
|
-1 * var(--ui-components-button-border-radius) - var(--thickness)
|
|
179
216
|
);
|
|
180
|
-
left:
|
|
217
|
+
left: calc(-1 * var(--flap-grow));
|
|
181
218
|
clip-path: polygon(
|
|
182
219
|
0 0,
|
|
183
220
|
0 100%,
|
|
@@ -186,10 +223,6 @@
|
|
|
186
223
|
var(--thickness) 50%
|
|
187
224
|
);
|
|
188
225
|
|
|
189
|
-
.unacked-active & {
|
|
190
|
-
left: calc(-1 * var(--blink-width-dynamic));
|
|
191
|
-
}
|
|
192
|
-
|
|
193
226
|
.top & {
|
|
194
227
|
top: unset;
|
|
195
228
|
bottom: calc(
|
|
@@ -212,7 +245,7 @@
|
|
|
212
245
|
top: calc(
|
|
213
246
|
-1 * var(--ui-components-button-border-radius) - var(--thickness)
|
|
214
247
|
);
|
|
215
|
-
right:
|
|
248
|
+
right: calc(-1 * var(--flap-grow));
|
|
216
249
|
clip-path: polygon(
|
|
217
250
|
100% 0,
|
|
218
251
|
100% 100%,
|
|
@@ -234,10 +267,6 @@
|
|
|
234
267
|
calc(100% - var(--thickness)) 50%
|
|
235
268
|
);
|
|
236
269
|
}
|
|
237
|
-
|
|
238
|
-
.unacked-active & {
|
|
239
|
-
right: calc(-1 * var(--blink-width-dynamic));
|
|
240
|
-
}
|
|
241
270
|
}
|
|
242
271
|
}
|
|
243
272
|
|
|
@@ -315,8 +344,34 @@
|
|
|
315
344
|
}
|
|
316
345
|
}
|
|
317
346
|
|
|
318
|
-
|
|
319
|
-
|
|
347
|
+
/* Grows the flap outward with the outline, never toward the content: shifted
|
|
348
|
+
copies leave the inner edge where it is (an outline would cross it). */
|
|
349
|
+
.flap.small,
|
|
350
|
+
.flap.large {
|
|
351
|
+
box-shadow:
|
|
352
|
+
var(--flap-grow) 0 0 0 var(--bg-color),
|
|
353
|
+
0 calc(-1 * var(--flap-grow)) 0 0 var(--bg-color),
|
|
354
|
+
0 var(--flap-grow) 0 0 var(--bg-color),
|
|
355
|
+
var(--flap-grow) calc(-1 * var(--flap-grow)) 0 0 var(--bg-color),
|
|
356
|
+
var(--flap-grow) var(--flap-grow) 0 0 var(--bg-color);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
.flap.bottom {
|
|
360
|
+
box-shadow:
|
|
361
|
+
0 var(--flap-grow) 0 0 var(--bg-color),
|
|
362
|
+
calc(-1 * var(--flap-grow)) 0 0 0 var(--bg-color),
|
|
363
|
+
var(--flap-grow) 0 0 0 var(--bg-color),
|
|
364
|
+
calc(-1 * var(--flap-grow)) var(--flap-grow) 0 0 var(--bg-color),
|
|
365
|
+
var(--flap-grow) var(--flap-grow) 0 0 var(--bg-color);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
.flap.top {
|
|
369
|
+
box-shadow:
|
|
370
|
+
0 calc(-1 * var(--flap-grow)) 0 0 var(--bg-color),
|
|
371
|
+
calc(-1 * var(--flap-grow)) 0 0 0 var(--bg-color),
|
|
372
|
+
var(--flap-grow) 0 0 0 var(--bg-color),
|
|
373
|
+
calc(-1 * var(--flap-grow)) calc(-1 * var(--flap-grow)) 0 0 var(--bg-color),
|
|
374
|
+
var(--flap-grow) calc(-1 * var(--flap-grow)) 0 0 var(--bg-color);
|
|
320
375
|
}
|
|
321
376
|
|
|
322
377
|
::slotted([slot="label"]) {
|
|
@@ -331,3 +386,21 @@
|
|
|
331
386
|
display: block;
|
|
332
387
|
flex-shrink: 0;
|
|
333
388
|
}
|
|
389
|
+
|
|
390
|
+
.dash {
|
|
391
|
+
/* Overridden inline per render from the measured thickness. */
|
|
392
|
+
--dash-pad: 0px;
|
|
393
|
+
position: absolute;
|
|
394
|
+
top: calc(-1 * var(--dash-pad));
|
|
395
|
+
left: calc(-1 * var(--dash-pad));
|
|
396
|
+
overflow: visible;
|
|
397
|
+
pointer-events: none;
|
|
398
|
+
fill: none;
|
|
399
|
+
stroke: var(--bg-color);
|
|
400
|
+
stroke-dasharray: 12 6;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
.dash path {
|
|
404
|
+
/* Animated on the one path: a wider second path would drift its dashes. */
|
|
405
|
+
stroke-width: calc(var(--thickness) + var(--blink-width-dynamic));
|
|
406
|
+
}
|
|
@@ -1,45 +1,114 @@
|
|
|
1
1
|
import {describe, expect, it} from 'vitest';
|
|
2
2
|
import './alert-frame.js';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ObcAlertFrame,
|
|
5
|
+
ObcAlertFrameFlashEffect,
|
|
6
|
+
ObcAlertFrameMode,
|
|
7
|
+
} from './alert-frame.js';
|
|
4
8
|
import {render} from 'vitest-browser-lit';
|
|
5
9
|
import {html} from 'lit';
|
|
10
|
+
import {AlertType, FlashingSpeed} from '../../types.js';
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
function durations(el: HTMLElement): number[] {
|
|
13
|
+
return el
|
|
14
|
+
.getAnimations()
|
|
15
|
+
.map((a) => (a.effect as KeyframeEffect).getTiming().duration as number);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
describe('obc-alert-frame flashing lifecycle', () => {
|
|
19
|
+
async function setup(
|
|
20
|
+
mode: ObcAlertFrameMode,
|
|
21
|
+
status: AlertType = AlertType.Alarm,
|
|
22
|
+
flashingSpeed: FlashingSpeed = FlashingSpeed.Default
|
|
23
|
+
) {
|
|
9
24
|
const screen = render(
|
|
10
|
-
html`<obc-alert-frame
|
|
25
|
+
html`<obc-alert-frame
|
|
26
|
+
.mode=${mode}
|
|
27
|
+
.status=${status}
|
|
28
|
+
.flashingSpeed=${flashingSpeed}
|
|
29
|
+
></obc-alert-frame>`
|
|
11
30
|
);
|
|
12
|
-
const el = screen.
|
|
31
|
+
const el = screen.container.querySelector(
|
|
13
32
|
'obc-alert-frame'
|
|
14
33
|
) as ObcAlertFrame;
|
|
15
34
|
await el.updateComplete;
|
|
16
35
|
return el;
|
|
17
36
|
}
|
|
18
37
|
|
|
19
|
-
it('
|
|
38
|
+
it('flashes fast while an alarm is unacked-active', async () => {
|
|
20
39
|
const el = await setup(ObcAlertFrameMode.unackedActive);
|
|
21
40
|
|
|
22
|
-
expect(el
|
|
41
|
+
expect(durations(el)).toEqual([800]);
|
|
42
|
+
expect(el.resolvedFlashingSpeed).toBe(FlashingSpeed.Fast);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('flashes slow for a warning and very slow for level-low', async () => {
|
|
46
|
+
expect(
|
|
47
|
+
durations(await setup(ObcAlertFrameMode.unackedActive, AlertType.Warning))
|
|
48
|
+
).toEqual([1600]);
|
|
49
|
+
expect(
|
|
50
|
+
durations(
|
|
51
|
+
await setup(ObcAlertFrameMode.unackedActive, AlertType.LevelLow)
|
|
52
|
+
)
|
|
53
|
+
).toEqual([3200]);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('never flashes a caution', async () => {
|
|
57
|
+
expect(
|
|
58
|
+
durations(await setup(ObcAlertFrameMode.unackedActive, AlertType.Caution))
|
|
59
|
+
).toEqual([]);
|
|
60
|
+
expect(
|
|
61
|
+
durations(
|
|
62
|
+
await setup(ObcAlertFrameMode.unackedRectified, AlertType.Caution)
|
|
63
|
+
)
|
|
64
|
+
).toEqual([]);
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('flashes very slow while rectified', async () => {
|
|
68
|
+
const el = await setup(ObcAlertFrameMode.unackedRectified);
|
|
69
|
+
|
|
70
|
+
expect(durations(el)).toEqual([3200]);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('honours an explicit flashingSpeed', async () => {
|
|
74
|
+
expect(
|
|
75
|
+
durations(
|
|
76
|
+
await setup(
|
|
77
|
+
ObcAlertFrameMode.unackedActive,
|
|
78
|
+
AlertType.Alarm,
|
|
79
|
+
FlashingSpeed.Slow
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
).toEqual([1600]);
|
|
83
|
+
expect(
|
|
84
|
+
durations(
|
|
85
|
+
await setup(
|
|
86
|
+
ObcAlertFrameMode.unackedActive,
|
|
87
|
+
AlertType.Alarm,
|
|
88
|
+
FlashingSpeed.Fixed
|
|
89
|
+
)
|
|
90
|
+
)
|
|
91
|
+
).toEqual([]);
|
|
23
92
|
});
|
|
24
93
|
|
|
25
|
-
it('does not
|
|
94
|
+
it('does not flash in acked-active', async () => {
|
|
26
95
|
const el = await setup(ObcAlertFrameMode.ackedActive);
|
|
27
96
|
|
|
28
97
|
expect(el.getAnimations()).toHaveLength(0);
|
|
29
98
|
});
|
|
30
99
|
|
|
31
100
|
describe('mode transitions', () => {
|
|
32
|
-
it('starts
|
|
101
|
+
it('starts flashing when mode becomes unacked-active', async () => {
|
|
33
102
|
const el = await setup(ObcAlertFrameMode.ackedActive);
|
|
34
103
|
expect(el.getAnimations()).toHaveLength(0);
|
|
35
104
|
|
|
36
105
|
el.mode = ObcAlertFrameMode.unackedActive;
|
|
37
106
|
await el.updateComplete;
|
|
38
107
|
|
|
39
|
-
expect(el
|
|
108
|
+
expect(durations(el)).toEqual([800]);
|
|
40
109
|
});
|
|
41
110
|
|
|
42
|
-
it('stops
|
|
111
|
+
it('stops flashing when mode leaves unacked-active', async () => {
|
|
43
112
|
const el = await setup(ObcAlertFrameMode.unackedActive);
|
|
44
113
|
expect(el.getAnimations().length).toBeGreaterThan(0);
|
|
45
114
|
|
|
@@ -49,13 +118,13 @@ describe('obc-alert-frame blinking lifecycle', () => {
|
|
|
49
118
|
expect(el.getAnimations()).toHaveLength(0);
|
|
50
119
|
});
|
|
51
120
|
|
|
52
|
-
it('
|
|
121
|
+
it('switches to the very-slow tempo when mode becomes unacked-rectified', async () => {
|
|
53
122
|
const el = await setup(ObcAlertFrameMode.unackedActive);
|
|
54
123
|
|
|
55
124
|
el.mode = ObcAlertFrameMode.unackedRectified;
|
|
56
125
|
await el.updateComplete;
|
|
57
126
|
|
|
58
|
-
expect(el
|
|
127
|
+
expect(durations(el)).toEqual([3200]);
|
|
59
128
|
});
|
|
60
129
|
|
|
61
130
|
it('does not accumulate animations across repeated updates', async () => {
|
|
@@ -72,7 +141,7 @@ describe('obc-alert-frame blinking lifecycle', () => {
|
|
|
72
141
|
});
|
|
73
142
|
|
|
74
143
|
describe('reconnection', () => {
|
|
75
|
-
it('resumes
|
|
144
|
+
it('resumes flashing after disconnect and reconnect', async () => {
|
|
76
145
|
const el = await setup(ObcAlertFrameMode.unackedActive);
|
|
77
146
|
const parent = el.parentElement!;
|
|
78
147
|
expect(el.getAnimations().length).toBeGreaterThan(0);
|
|
@@ -81,14 +150,14 @@ describe('obc-alert-frame blinking lifecycle', () => {
|
|
|
81
150
|
expect(el.getAnimations()).toHaveLength(0);
|
|
82
151
|
|
|
83
152
|
// Reconnect without touching any property. firstUpdated() will not run
|
|
84
|
-
// again, so this only passes if
|
|
153
|
+
// again, so this only passes if the controller re-syncs on connect.
|
|
85
154
|
parent.appendChild(el);
|
|
86
155
|
await el.updateComplete;
|
|
87
156
|
|
|
88
157
|
expect(el.getAnimations().length).toBeGreaterThan(0);
|
|
89
158
|
});
|
|
90
159
|
|
|
91
|
-
it('does not resume
|
|
160
|
+
it('does not resume flashing on reconnect when mode is not unacked-active', async () => {
|
|
92
161
|
const el = await setup(ObcAlertFrameMode.ackedActive);
|
|
93
162
|
const parent = el.parentElement!;
|
|
94
163
|
|
|
@@ -99,7 +168,7 @@ describe('obc-alert-frame blinking lifecycle', () => {
|
|
|
99
168
|
expect(el.getAnimations()).toHaveLength(0);
|
|
100
169
|
});
|
|
101
170
|
|
|
102
|
-
it('does not
|
|
171
|
+
it('does not flash after disconnection when mode became unacked-active while detached', async () => {
|
|
103
172
|
const el = await setup(ObcAlertFrameMode.ackedActive);
|
|
104
173
|
const parent = el.parentElement!;
|
|
105
174
|
|
|
@@ -119,4 +188,94 @@ describe('obc-alert-frame blinking lifecycle', () => {
|
|
|
119
188
|
expect(el.getAnimations().length).toBeGreaterThan(0);
|
|
120
189
|
});
|
|
121
190
|
});
|
|
191
|
+
|
|
192
|
+
it('eases the outline width between phases in the outline-eased effect', async () => {
|
|
193
|
+
const el = await setup(ObcAlertFrameMode.unackedActive);
|
|
194
|
+
el.flashEffect = ObcAlertFrameFlashEffect.OutlineEased;
|
|
195
|
+
await el.updateComplete;
|
|
196
|
+
const wrapper = el.shadowRoot!.querySelector('.wrapper') as HTMLElement;
|
|
197
|
+
const [flash] = el.getAnimations();
|
|
198
|
+
flash.pause();
|
|
199
|
+
flash.currentTime = 100;
|
|
200
|
+
await new Promise((r) => requestAnimationFrame(r));
|
|
201
|
+
await Promise.all(wrapper.getAnimations().map((a) => a.finished));
|
|
202
|
+
expect(getComputedStyle(wrapper).outlineWidth).toBe('4px');
|
|
203
|
+
|
|
204
|
+
flash.currentTime = 500;
|
|
205
|
+
// A style read starts the transition synchronously; waiting a frame lets
|
|
206
|
+
// a slow runner finish the 50 ms and drop it from getAnimations().
|
|
207
|
+
void getComputedStyle(wrapper).outlineWidth;
|
|
208
|
+
const transition = wrapper
|
|
209
|
+
.getAnimations()
|
|
210
|
+
.find(
|
|
211
|
+
(a) => (a as CSSTransition).transitionProperty === 'outline-width'
|
|
212
|
+
) as CSSTransition | undefined;
|
|
213
|
+
expect(transition).toBeDefined();
|
|
214
|
+
expect((transition!.effect as KeyframeEffect).getTiming().duration).toBe(
|
|
215
|
+
50
|
|
216
|
+
);
|
|
217
|
+
transition!.pause();
|
|
218
|
+
transition!.currentTime = 25;
|
|
219
|
+
const midway = parseFloat(getComputedStyle(wrapper).outlineWidth);
|
|
220
|
+
expect(midway).toBeGreaterThan(2);
|
|
221
|
+
expect(midway).toBeLessThan(4);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
describe('rectified dash', () => {
|
|
225
|
+
it('draws the 12/6 dash as one svg path whose stroke width flashes', async () => {
|
|
226
|
+
const el = await setup(ObcAlertFrameMode.unackedRectified);
|
|
227
|
+
await new Promise((r) => requestAnimationFrame(r));
|
|
228
|
+
await el.updateComplete;
|
|
229
|
+
|
|
230
|
+
const root = el.shadowRoot!;
|
|
231
|
+
const wrapper = root.querySelector('.wrapper') as HTMLElement;
|
|
232
|
+
expect(getComputedStyle(wrapper).outlineStyle).toBe('none');
|
|
233
|
+
const paths = root.querySelectorAll('svg.dash path');
|
|
234
|
+
expect(paths).toHaveLength(1);
|
|
235
|
+
const path = paths[0];
|
|
236
|
+
expect(getComputedStyle(path).strokeDasharray).toBe('12px, 6px');
|
|
237
|
+
const d = path.getAttribute('d');
|
|
238
|
+
expect(d).toMatch(/^M[\d.-]+ [\d.-]+ H/);
|
|
239
|
+
|
|
240
|
+
// The geometry must not change between phases, or the dashes drift.
|
|
241
|
+
const [anim] = el.getAnimations();
|
|
242
|
+
anim.pause();
|
|
243
|
+
anim.currentTime = 100;
|
|
244
|
+
expect(getComputedStyle(path).strokeWidth).toBe('4px');
|
|
245
|
+
anim.currentTime = 3000;
|
|
246
|
+
expect(getComputedStyle(path).strokeWidth).toBe('2px');
|
|
247
|
+
expect(path.getAttribute('d')).toBe(d);
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
it('re-measures when a sharp edge or the thickness changes', async () => {
|
|
251
|
+
const el = await setup(ObcAlertFrameMode.unackedRectified);
|
|
252
|
+
// The palette is not loaded here; give the corners a radius to lose.
|
|
253
|
+
el.style.setProperty('--ui-components-button-border-radius', '6px');
|
|
254
|
+
await new Promise((r) => requestAnimationFrame(r));
|
|
255
|
+
await el.updateComplete;
|
|
256
|
+
const path = () => el.shadowRoot!.querySelector('svg.dash path')!;
|
|
257
|
+
const rounded = path().getAttribute('d')!;
|
|
258
|
+
expect(rounded).toContain('A');
|
|
259
|
+
|
|
260
|
+
el.sharpEdgeTopLeft = true;
|
|
261
|
+
await el.updateComplete;
|
|
262
|
+
await el.updateComplete;
|
|
263
|
+
|
|
264
|
+
const sharp = path().getAttribute('d')!;
|
|
265
|
+
expect(sharp).not.toBe(rounded);
|
|
266
|
+
expect(sharp.startsWith('M3 3 H')).toBe(true);
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
it('removes the svg when the mode leaves unacked-rectified', async () => {
|
|
270
|
+
const el = await setup(ObcAlertFrameMode.unackedRectified);
|
|
271
|
+
await new Promise((r) => requestAnimationFrame(r));
|
|
272
|
+
await el.updateComplete;
|
|
273
|
+
expect(el.shadowRoot!.querySelector('svg.dash')).not.toBeNull();
|
|
274
|
+
|
|
275
|
+
el.mode = ObcAlertFrameMode.ackedActive;
|
|
276
|
+
await el.updateComplete;
|
|
277
|
+
|
|
278
|
+
expect(el.shadowRoot!.querySelector('svg.dash')).toBeNull();
|
|
279
|
+
});
|
|
280
|
+
});
|
|
122
281
|
});
|
|
@@ -6,7 +6,9 @@ import {
|
|
|
6
6
|
ObcAlertFrameStatus,
|
|
7
7
|
AlertFrameTextSize,
|
|
8
8
|
ObcAlertFrameMode,
|
|
9
|
+
ObcAlertFrameFlashEffect,
|
|
9
10
|
} from './alert-frame.js';
|
|
11
|
+
import {AlertType, FlashingSpeed} from '../../types.js';
|
|
10
12
|
import './alert-frame.js';
|
|
11
13
|
import '../../icons/icon-placeholder.js';
|
|
12
14
|
import {html} from 'lit';
|
|
@@ -20,6 +22,8 @@ const meta: Meta<typeof ObcAlertFrame> = {
|
|
|
20
22
|
thickness: ObcAlertFrameThickness.Small,
|
|
21
23
|
status: ObcAlertFrameStatus.Alarm,
|
|
22
24
|
mode: ObcAlertFrameMode.ackedActive,
|
|
25
|
+
flashingSpeed: FlashingSpeed.Default,
|
|
26
|
+
flashEffect: ObcAlertFrameFlashEffect.Outline,
|
|
23
27
|
demoWidth: 200,
|
|
24
28
|
showIcon: true,
|
|
25
29
|
showAlertCategoryIcon: true,
|
|
@@ -37,6 +41,16 @@ const meta: Meta<typeof ObcAlertFrame> = {
|
|
|
37
41
|
type: 'select',
|
|
38
42
|
},
|
|
39
43
|
},
|
|
44
|
+
flashingSpeed: {
|
|
45
|
+
options: Object.values(FlashingSpeed),
|
|
46
|
+
control: {type: 'select'},
|
|
47
|
+
if: {arg: 'mode', neq: ObcAlertFrameMode.ackedActive},
|
|
48
|
+
},
|
|
49
|
+
flashEffect: {
|
|
50
|
+
options: Object.values(ObcAlertFrameFlashEffect),
|
|
51
|
+
control: {type: 'select'},
|
|
52
|
+
if: {arg: 'mode', neq: ObcAlertFrameMode.ackedActive},
|
|
53
|
+
},
|
|
40
54
|
thickness: {
|
|
41
55
|
options: Object.values(ObcAlertFrameThickness),
|
|
42
56
|
control: {
|
|
@@ -64,6 +78,8 @@ const meta: Meta<typeof ObcAlertFrame> = {
|
|
|
64
78
|
.type=${args.type}
|
|
65
79
|
.thickness=${args.thickness}
|
|
66
80
|
.mode=${args.mode}
|
|
81
|
+
.flashingSpeed=${args.flashingSpeed}
|
|
82
|
+
.flashEffect=${args.flashEffect}
|
|
67
83
|
.status=${args.status}
|
|
68
84
|
.textSize=${args.textSize}
|
|
69
85
|
.showIcon=${args.showIcon}
|
|
@@ -273,3 +289,48 @@ export const CriticalUnacked: Story = {
|
|
|
273
289
|
showAlertCategoryIcon: true,
|
|
274
290
|
},
|
|
275
291
|
};
|
|
292
|
+
|
|
293
|
+
export const FlashComparison: Story = {
|
|
294
|
+
tags: ['skip-test'],
|
|
295
|
+
render: () => {
|
|
296
|
+
const statuses = [
|
|
297
|
+
AlertType.LevelCritical,
|
|
298
|
+
AlertType.Alarm,
|
|
299
|
+
AlertType.Warning,
|
|
300
|
+
AlertType.Caution,
|
|
301
|
+
AlertType.LevelLow,
|
|
302
|
+
];
|
|
303
|
+
const modes = [
|
|
304
|
+
ObcAlertFrameMode.unackedActive,
|
|
305
|
+
ObcAlertFrameMode.unackedRectified,
|
|
306
|
+
];
|
|
307
|
+
return html`<style>
|
|
308
|
+
.flash-grid {
|
|
309
|
+
display: grid;
|
|
310
|
+
grid-template-columns: repeat(2, 200px);
|
|
311
|
+
gap: 24px;
|
|
312
|
+
padding: 16px;
|
|
313
|
+
}
|
|
314
|
+
</style>
|
|
315
|
+
${Object.values(ObcAlertFrameFlashEffect).map(
|
|
316
|
+
(effect) =>
|
|
317
|
+
html`<h4>${effect}</h4>
|
|
318
|
+
<div class="flash-grid">
|
|
319
|
+
${statuses.flatMap((status) =>
|
|
320
|
+
modes.map(
|
|
321
|
+
(mode) =>
|
|
322
|
+
html`<obc-alert-frame
|
|
323
|
+
.type=${ObcAlertFrameType.Regular}
|
|
324
|
+
.status=${status}
|
|
325
|
+
.mode=${mode}
|
|
326
|
+
.flashEffect=${effect}
|
|
327
|
+
wrapContent
|
|
328
|
+
>
|
|
329
|
+
<div style="width: 200px; height: 48px"></div>
|
|
330
|
+
</obc-alert-frame>`
|
|
331
|
+
)
|
|
332
|
+
)}
|
|
333
|
+
</div>`
|
|
334
|
+
)}`;
|
|
335
|
+
},
|
|
336
|
+
};
|