@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.88 → 2.0.0-next.90
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/bundle/openbridge-webcomponents.bundle.js +17477 -16780
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +742 -43
- package/dist/building-blocks/readout-block/readout-block.css.js +229 -0
- package/dist/building-blocks/readout-block/readout-block.css.js.map +1 -0
- package/dist/building-blocks/readout-block/readout-block.d.ts +146 -0
- package/dist/building-blocks/readout-block/readout-block.d.ts.map +1 -0
- package/dist/building-blocks/readout-block/readout-block.js +273 -0
- package/dist/building-blocks/readout-block/readout-block.js.map +1 -0
- package/dist/navigation-instruments/readout-list/readout-list.css.js +26 -0
- package/dist/navigation-instruments/readout-list/readout-list.css.js.map +1 -0
- package/dist/navigation-instruments/readout-list/readout-list.d.ts +70 -0
- package/dist/navigation-instruments/readout-list/readout-list.d.ts.map +1 -0
- package/dist/navigation-instruments/readout-list/readout-list.js +154 -0
- package/dist/navigation-instruments/readout-list/readout-list.js.map +1 -0
- package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js +139 -124
- package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts +57 -26
- 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 +139 -125
- package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
- package/package.json +1 -1
- package/src/building-blocks/readout-block/readout-block.css +192 -0
- package/src/building-blocks/readout-block/readout-block.stories.ts +347 -0
- package/src/building-blocks/readout-block/readout-block.ts +355 -0
- package/src/navigation-instruments/readout-list/readout-list.css +15 -0
- package/src/navigation-instruments/readout-list/readout-list.stories.ts +358 -0
- package/src/navigation-instruments/readout-list/readout-list.ts +216 -0
- package/src/navigation-instruments/readout-list-item/readout-list-item.css +141 -120
- package/src/navigation-instruments/readout-list-item/readout-list-item.stories.ts +145 -29
- package/src/navigation-instruments/readout-list-item/readout-list-item.ts +169 -146
|
@@ -7,6 +7,55 @@
|
|
|
7
7
|
width: 100%;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/* Bridge the list-item's public colour custom properties onto the block's, so
|
|
11
|
+
consumers keep theming the value / setpoint / advice / hinted-zero colours via
|
|
12
|
+
`--obc-readout-list-item-*` even though they now render inside obc-readout-block. */
|
|
13
|
+
obc-readout-block {
|
|
14
|
+
--obc-readout-block-value-color: var(
|
|
15
|
+
--obc-readout-list-item-value-color,
|
|
16
|
+
var(--element-neutral-color)
|
|
17
|
+
);
|
|
18
|
+
--obc-readout-block-value-enhanced-color: var(
|
|
19
|
+
--obc-readout-list-item-value-enhanced-color,
|
|
20
|
+
var(--element-neutral-enhanced-color)
|
|
21
|
+
);
|
|
22
|
+
--obc-readout-block-setpoint-color: var(
|
|
23
|
+
--obc-readout-list-item-setpoint-color,
|
|
24
|
+
var(--element-neutral-color)
|
|
25
|
+
);
|
|
26
|
+
--obc-readout-block-setpoint-enhanced-color: var(
|
|
27
|
+
--obc-readout-list-item-setpoint-enhanced-color,
|
|
28
|
+
var(--instrument-enhanced-secondary-color)
|
|
29
|
+
);
|
|
30
|
+
--obc-readout-block-setpoint-touching-outline-color: var(
|
|
31
|
+
--obc-readout-list-item-setpoint-touching-outline-color,
|
|
32
|
+
var(--element-neutral-enhanced-color)
|
|
33
|
+
);
|
|
34
|
+
--obc-readout-block-setpoint-touching-color: var(
|
|
35
|
+
--obc-readout-list-item-setpoint-touching-color,
|
|
36
|
+
var(--base-blue-100)
|
|
37
|
+
);
|
|
38
|
+
--obc-readout-block-advice-color: var(
|
|
39
|
+
--obc-readout-list-item-advice-color,
|
|
40
|
+
var(--element-neutral-color)
|
|
41
|
+
);
|
|
42
|
+
--obc-readout-block-hinted-color: var(
|
|
43
|
+
--obc-readout-list-item-hinted-color,
|
|
44
|
+
var(--element-inactive-color)
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/* Size the consumer-provided block icons forwarded into obc-readout-block's
|
|
49
|
+
`icon` slot (the block sizes the forwarded slot element; this sizes the
|
|
50
|
+
consumer's icon to fill it). */
|
|
51
|
+
::slotted([slot="value-icon"]),
|
|
52
|
+
::slotted([slot="setpoint-icon"]),
|
|
53
|
+
::slotted([slot="advice-icon"]) {
|
|
54
|
+
display: block;
|
|
55
|
+
inline-size: 100%;
|
|
56
|
+
block-size: 100%;
|
|
57
|
+
}
|
|
58
|
+
|
|
10
59
|
/* ---------- Root / surface ----------
|
|
11
60
|
* `.root` is the touch target (a <button> when clickable, otherwise a <div>).
|
|
12
61
|
* `.surface` is the visible box that carries padding, corner radius, the
|
|
@@ -140,115 +189,84 @@
|
|
|
140
189
|
align-items: flex-end;
|
|
141
190
|
}
|
|
142
191
|
|
|
143
|
-
/* ----------
|
|
144
|
-
|
|
192
|
+
/* ---------- Value reading (value + degree + unit) ----------
|
|
193
|
+
* Groups the value block, its degree column and the trailing unit so the value
|
|
194
|
+
* alert frame can wrap all three. Layout-neutral: it adds no gap, so the content
|
|
195
|
+
* sits exactly where it did when these were siblings of `.value-area`. */
|
|
196
|
+
.value-reading {
|
|
197
|
+
position: relative;
|
|
145
198
|
display: inline-flex;
|
|
146
199
|
align-items: flex-end;
|
|
147
200
|
}
|
|
148
201
|
|
|
149
|
-
/*
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
.
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
color: inherit;
|
|
162
|
-
/* Centre the icon against the block's text rather than bottom-aligning it (the
|
|
163
|
-
block is flex-end). Matters for the value block, whose text is taller than
|
|
164
|
-
the icon, so the value icon lines up with the number like the smaller
|
|
165
|
-
setpoint/advice icons do. */
|
|
166
|
-
align-self: center;
|
|
202
|
+
/* ---------- Value data quality (low-integrity / invalid) ----------
|
|
203
|
+
* The value's per-block data-quality chip, applied to the whole reading (value +
|
|
204
|
+
* degree + unit) rather than hugging the value alone — the same logic as the
|
|
205
|
+
* value alert frame, minus its custom padding. Same look as the block/source
|
|
206
|
+
* chip (1px outline, check radius, alert-quality colours). Uses `outline` (not
|
|
207
|
+
* `border`) so it never shifts the value's width / cross-row column alignment.
|
|
208
|
+
* Setpoint/advice keep their own in-block chip; the row-level data quality on
|
|
209
|
+
* `.surface` is unchanged. */
|
|
210
|
+
.value-reading.data-low-integrity,
|
|
211
|
+
.value-reading.data-invalid {
|
|
212
|
+
outline: 1px solid;
|
|
213
|
+
border-radius: var(--global-border-radius-border-radius-check);
|
|
167
214
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
.block-icon ::slotted(*) {
|
|
172
|
-
display: block;
|
|
173
|
-
inline-size: 100%;
|
|
174
|
-
block-size: 100%;
|
|
215
|
+
.value-reading.data-low-integrity {
|
|
216
|
+
background: var(--alert-low-integrity-background-color);
|
|
217
|
+
outline-color: var(--alert-low-integrity-border-color);
|
|
175
218
|
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
color: var(
|
|
179
|
-
--obc-readout-list-item-hinted-color,
|
|
180
|
-
var(--element-inactive-color)
|
|
181
|
-
);
|
|
219
|
+
.value-reading.data-invalid {
|
|
220
|
+
background: var(--alert-invalid-background-color);
|
|
221
|
+
outline-color: var(--alert-invalid-border-color);
|
|
182
222
|
}
|
|
183
223
|
|
|
184
|
-
/* ----------
|
|
185
|
-
*
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
.
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
.
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
.block-setpoint.touching {
|
|
231
|
-
--_touching-outline: var(
|
|
232
|
-
--obc-readout-list-item-setpoint-touching-outline-color,
|
|
233
|
-
var(--element-neutral-enhanced-color)
|
|
234
|
-
);
|
|
235
|
-
}
|
|
236
|
-
.block-setpoint.touching .block-icon {
|
|
237
|
-
color: var(
|
|
238
|
-
--obc-readout-list-item-setpoint-touching-color,
|
|
239
|
-
var(--base-blue-100)
|
|
240
|
-
);
|
|
241
|
-
filter: drop-shadow(1px 0 0 var(--_touching-outline))
|
|
242
|
-
drop-shadow(-1px 0 0 var(--_touching-outline))
|
|
243
|
-
drop-shadow(0 1px 0 var(--_touching-outline))
|
|
244
|
-
drop-shadow(0 -1px 0 var(--_touching-outline));
|
|
245
|
-
}
|
|
246
|
-
.block-advice {
|
|
247
|
-
color: var(
|
|
248
|
-
--obc-readout-list-item-advice-color,
|
|
249
|
-
var(--element-neutral-color)
|
|
250
|
-
);
|
|
251
|
-
}
|
|
224
|
+
/* ---------- Value alert overlay ----------
|
|
225
|
+
* A pure overlay around the value reading: it reserves no space, so toggling the
|
|
226
|
+
* frame never changes the row height or breaks cross-row column alignment. The
|
|
227
|
+
* box is offset outward by (padding − stroke/2) on each axis so the alert-frame's
|
|
228
|
+
* outline (drawn outside its box) lands CENTRED on the 4px/2px padding line
|
|
229
|
+
* (half inside / half outside), matching Figma 58:10120. */
|
|
230
|
+
.value-alert-overlay {
|
|
231
|
+
--_obc-readout-value-frame-padding-horizontal: 4px;
|
|
232
|
+
--_obc-readout-value-frame-padding-vertical: 2px;
|
|
233
|
+
/* Must match obc-alert-frame's ACTUAL outline width so the stroke stays centred
|
|
234
|
+
on the 4px/2px line. `thickness-small` is hard-coded to 2px in
|
|
235
|
+
alert-frame.css (it does NOT use the themed stroke-width token), so use a
|
|
236
|
+
literal 2px here; `thickness-large` is handled below. */
|
|
237
|
+
--_obc-readout-value-frame-stroke: 2px;
|
|
238
|
+
position: absolute;
|
|
239
|
+
inset-inline: calc(
|
|
240
|
+
-1 *
|
|
241
|
+
(
|
|
242
|
+
var(--_obc-readout-value-frame-padding-horizontal) -
|
|
243
|
+
var(--_obc-readout-value-frame-stroke) / 2
|
|
244
|
+
)
|
|
245
|
+
);
|
|
246
|
+
inset-block: calc(
|
|
247
|
+
-1 *
|
|
248
|
+
(
|
|
249
|
+
var(--_obc-readout-value-frame-padding-vertical) -
|
|
250
|
+
var(--_obc-readout-value-frame-stroke) / 2
|
|
251
|
+
)
|
|
252
|
+
);
|
|
253
|
+
/* Display-only: never intercept clicks on a clickable row. */
|
|
254
|
+
pointer-events: none;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/* thickness=large: obc-alert-frame's large outline uses the alert-frame border
|
|
258
|
+
weight token, so the overlay's outward offset must use the same width to keep
|
|
259
|
+
the stroke centred on the padding line. */
|
|
260
|
+
.value-alert-overlay.thickness-large {
|
|
261
|
+
--_obc-readout-value-frame-stroke: var(
|
|
262
|
+
--global-size-spacing-border-weight-alertframe
|
|
263
|
+
);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/* The readout building blocks (advice / setpoint / value) now render inside
|
|
267
|
+
`obc-readout-block`; their layout / colour / hinted-zero / data-quality CSS
|
|
268
|
+
lives there. The list-item only bridges the public colour vars (see top) and
|
|
269
|
+
keeps the surrounding row layout below. */
|
|
252
270
|
|
|
253
271
|
.label {
|
|
254
272
|
color: var(
|
|
@@ -266,23 +284,19 @@
|
|
|
266
284
|
);
|
|
267
285
|
}
|
|
268
286
|
|
|
269
|
-
/* ----------
|
|
287
|
+
/* ---------- Source data quality ----------
|
|
270
288
|
* Independent of (and nests inside) the row-level data-quality frame. Uses
|
|
271
|
-
* `outline` (not `border`) so the chip never shifts the
|
|
272
|
-
* value
|
|
273
|
-
.block.data-low-integrity,
|
|
274
|
-
.block.data-invalid,
|
|
289
|
+
* `outline` (not `border`) so the chip never shifts the source's width. (The
|
|
290
|
+
* per-block value/setpoint/advice chips live in `obc-readout-block`.) */
|
|
275
291
|
.source.data-low-integrity,
|
|
276
292
|
.source.data-invalid {
|
|
277
293
|
outline: 1px solid;
|
|
278
294
|
border-radius: var(--global-border-radius-border-radius-check);
|
|
279
295
|
}
|
|
280
|
-
.block.data-low-integrity,
|
|
281
296
|
.source.data-low-integrity {
|
|
282
297
|
background: var(--alert-low-integrity-background-color);
|
|
283
298
|
outline-color: var(--alert-low-integrity-border-color);
|
|
284
299
|
}
|
|
285
|
-
.block.data-invalid,
|
|
286
300
|
.source.data-invalid {
|
|
287
301
|
background: var(--alert-invalid-background-color);
|
|
288
302
|
outline-color: var(--alert-invalid-border-color);
|
|
@@ -407,10 +421,6 @@
|
|
|
407
421
|
--instrument-components-readout-new-list-item-regular-value-container-gap
|
|
408
422
|
);
|
|
409
423
|
}
|
|
410
|
-
.size-small .block {
|
|
411
|
-
gap: var(--instrument-components-readout-new-general-regular-icon-gap);
|
|
412
|
-
}
|
|
413
|
-
.size-small .block-icon,
|
|
414
424
|
.size-small .leading-icon {
|
|
415
425
|
inline-size: var(
|
|
416
426
|
--instrument-components-readout-new-general-regular-icon-size
|
|
@@ -443,10 +453,6 @@
|
|
|
443
453
|
--instrument-components-readout-new-list-item-medium-value-container-gap
|
|
444
454
|
);
|
|
445
455
|
}
|
|
446
|
-
.size-medium .block {
|
|
447
|
-
gap: var(--instrument-components-readout-new-general-medium-icon-gap);
|
|
448
|
-
}
|
|
449
|
-
.size-medium .block-icon,
|
|
450
456
|
.size-medium .leading-icon {
|
|
451
457
|
inline-size: var(
|
|
452
458
|
--instrument-components-readout-new-general-medium-icon-size
|
|
@@ -474,10 +480,6 @@
|
|
|
474
480
|
.size-large .value-cluster {
|
|
475
481
|
gap: var(--instrument-components-readout-new-list-item-large-value-gap);
|
|
476
482
|
}
|
|
477
|
-
.size-large .block {
|
|
478
|
-
gap: var(--instrument-components-readout-new-general-large-icon-gap);
|
|
479
|
-
}
|
|
480
|
-
.size-large .block-icon,
|
|
481
483
|
.size-large .leading-icon {
|
|
482
484
|
inline-size: var(--instrument-components-readout-new-general-large-icon-size);
|
|
483
485
|
block-size: var(--instrument-components-readout-new-general-large-icon-size);
|
|
@@ -517,3 +519,22 @@
|
|
|
517
519
|
);
|
|
518
520
|
--_obc-readout-list-item-data-border: var(--alert-invalid-border-color);
|
|
519
521
|
}
|
|
522
|
+
|
|
523
|
+
/* ---------- Debug overlay ----------
|
|
524
|
+
* `showDebugOverlay` outlines each readout building block (red), the degree
|
|
525
|
+
* columns (blue) and the degree spacer (green) so reserver widths / alignment
|
|
526
|
+
* are visible. A development aid (mirrors the donut chart's `showDebugOverlay`);
|
|
527
|
+
* off by default. */
|
|
528
|
+
:host([showDebugOverlay]) obc-readout-block::part(block) {
|
|
529
|
+
outline: 1px solid rgba(220, 0, 0, 0.7);
|
|
530
|
+
outline-offset: -1px;
|
|
531
|
+
}
|
|
532
|
+
:host([showDebugOverlay]) obc-readout-block::part(degree),
|
|
533
|
+
:host([showDebugOverlay]) .degree-column {
|
|
534
|
+
outline: 1px solid rgba(0, 0, 220, 0.7);
|
|
535
|
+
outline-offset: -1px;
|
|
536
|
+
}
|
|
537
|
+
:host([showDebugOverlay]) .degree-spacer {
|
|
538
|
+
outline: 1px solid rgba(0, 160, 0, 0.8);
|
|
539
|
+
outline-offset: -1px;
|
|
540
|
+
}
|
|
@@ -99,6 +99,7 @@ type ReadoutItemConfig = {
|
|
|
99
99
|
options?: StoryOptions;
|
|
100
100
|
hasLeadingIcon?: boolean;
|
|
101
101
|
hasValueIcon?: boolean;
|
|
102
|
+
showDebugOverlay?: boolean;
|
|
102
103
|
};
|
|
103
104
|
|
|
104
105
|
type ShowcaseCase = {label: string; config: ReadoutItemConfig};
|
|
@@ -179,6 +180,7 @@ function renderItem(config: ReadoutItemConfig) {
|
|
|
179
180
|
.adviceOptions=${o.advice}
|
|
180
181
|
.unitOptions=${o.unit}
|
|
181
182
|
.srcOptions=${o.src}
|
|
183
|
+
.showDebugOverlay=${config.showDebugOverlay ?? false}
|
|
182
184
|
>
|
|
183
185
|
${config.hasLeadingIcon
|
|
184
186
|
? html`<obi-placeholder slot="leading-icon"></obi-placeholder>`
|
|
@@ -1260,7 +1262,7 @@ export const PerBlockState: Story = {
|
|
|
1260
1262
|
value: {
|
|
1261
1263
|
alert: {
|
|
1262
1264
|
status: AlertType.Warning,
|
|
1263
|
-
mode: ObcAlertFrameMode.
|
|
1265
|
+
mode: ObcAlertFrameMode.ackedActive,
|
|
1264
1266
|
type: ObcAlertFrameType.Regular,
|
|
1265
1267
|
},
|
|
1266
1268
|
},
|
|
@@ -1294,7 +1296,7 @@ export const PerBlockState: Story = {
|
|
|
1294
1296
|
value: {
|
|
1295
1297
|
alert: {
|
|
1296
1298
|
status: AlertType.Warning,
|
|
1297
|
-
mode: ObcAlertFrameMode.
|
|
1299
|
+
mode: ObcAlertFrameMode.ackedActive,
|
|
1298
1300
|
type: ObcAlertFrameType.Regular,
|
|
1299
1301
|
},
|
|
1300
1302
|
},
|
|
@@ -1320,7 +1322,7 @@ export const PerBlockState: Story = {
|
|
|
1320
1322
|
dataQuality: ReadoutListItemDataQuality.lowIntegrity,
|
|
1321
1323
|
alert: {
|
|
1322
1324
|
status: AlertType.Warning,
|
|
1323
|
-
mode: ObcAlertFrameMode.
|
|
1325
|
+
mode: ObcAlertFrameMode.ackedActive,
|
|
1324
1326
|
type: ObcAlertFrameType.SmallSideFlip,
|
|
1325
1327
|
showAlertCategoryIcon: true,
|
|
1326
1328
|
},
|
|
@@ -1335,7 +1337,7 @@ export const PerBlockState: Story = {
|
|
|
1335
1337
|
dataQuality: ReadoutListItemDataQuality.invalid,
|
|
1336
1338
|
alert: {
|
|
1337
1339
|
status: AlertType.Alarm,
|
|
1338
|
-
mode: ObcAlertFrameMode.
|
|
1340
|
+
mode: ObcAlertFrameMode.ackedActive,
|
|
1339
1341
|
type: ObcAlertFrameType.LargeSideFlip,
|
|
1340
1342
|
showAlertCategoryIcon: true,
|
|
1341
1343
|
},
|
|
@@ -1394,6 +1396,94 @@ export const Alarm: Story = {
|
|
|
1394
1396
|
}),
|
|
1395
1397
|
};
|
|
1396
1398
|
|
|
1399
|
+
// The value alert frame now wraps the whole reading — value + degree + unit — and
|
|
1400
|
+
// is drawn as a pure overlay (4px/2px padding, stroke centred on that line), so
|
|
1401
|
+
// toggling it changes neither the row height nor the value/unit column positions.
|
|
1402
|
+
// Each combo is shown unframed then framed so the constant geometry is obvious;
|
|
1403
|
+
// the per-item outline marks the layout box (which the frame never grows).
|
|
1404
|
+
const VALUE_FRAME: AlertFrameConfig = {
|
|
1405
|
+
status: AlertType.Warning,
|
|
1406
|
+
mode: ObcAlertFrameMode.ackedActive,
|
|
1407
|
+
type: ObcAlertFrameType.Regular,
|
|
1408
|
+
};
|
|
1409
|
+
|
|
1410
|
+
const VALUE_FRAME_COMBOS: {label: string; config: ReadoutItemConfig}[] = [
|
|
1411
|
+
{label: 'value + unit', config: {value: 123, unit: 'kn'}},
|
|
1412
|
+
{
|
|
1413
|
+
label: 'value + degree + unit',
|
|
1414
|
+
config: {value: 287, unit: 'T', options: {hasDegree: true}},
|
|
1415
|
+
},
|
|
1416
|
+
{
|
|
1417
|
+
label: 'value + unit + setpoint',
|
|
1418
|
+
config: {value: 123, unit: 'kn', hasSetpoint: true, setpoint: 120},
|
|
1419
|
+
},
|
|
1420
|
+
{
|
|
1421
|
+
label: 'value + unit + advice + setpoint',
|
|
1422
|
+
config: {
|
|
1423
|
+
value: 123,
|
|
1424
|
+
unit: 'kn',
|
|
1425
|
+
hasSetpoint: true,
|
|
1426
|
+
setpoint: 120,
|
|
1427
|
+
hasAdvice: true,
|
|
1428
|
+
advice: 118,
|
|
1429
|
+
},
|
|
1430
|
+
},
|
|
1431
|
+
];
|
|
1432
|
+
|
|
1433
|
+
export const ValueAlertFrame: Story = {
|
|
1434
|
+
render: () => html`
|
|
1435
|
+
<style>
|
|
1436
|
+
.rli-vf {
|
|
1437
|
+
display: flex;
|
|
1438
|
+
flex-direction: column;
|
|
1439
|
+
gap: 12px;
|
|
1440
|
+
width: 380px;
|
|
1441
|
+
}
|
|
1442
|
+
.rli-vf-row {
|
|
1443
|
+
display: flex;
|
|
1444
|
+
align-items: center;
|
|
1445
|
+
gap: 12px;
|
|
1446
|
+
}
|
|
1447
|
+
.rli-vf-tag {
|
|
1448
|
+
width: 180px;
|
|
1449
|
+
flex: none;
|
|
1450
|
+
font: 10px/1.2 var(--global-typography-ui-label-font-family, sans-serif);
|
|
1451
|
+
text-transform: uppercase;
|
|
1452
|
+
letter-spacing: 0.06em;
|
|
1453
|
+
color: var(--element-neutral-color, #777);
|
|
1454
|
+
}
|
|
1455
|
+
.rli-vf-item {
|
|
1456
|
+
flex: 1;
|
|
1457
|
+
outline: 1px solid rgba(0, 0, 0, 0.12);
|
|
1458
|
+
}
|
|
1459
|
+
</style>
|
|
1460
|
+
<div class="rli-vf">
|
|
1461
|
+
${VALUE_FRAME_COMBOS.flatMap((combo) =>
|
|
1462
|
+
[false, true].map(
|
|
1463
|
+
(framed) => html`
|
|
1464
|
+
<div class="rli-vf-row">
|
|
1465
|
+
<div class="rli-vf-tag">
|
|
1466
|
+
${combo.label} ${framed ? '· framed' : '· plain'}
|
|
1467
|
+
</div>
|
|
1468
|
+
<div class="rli-vf-item">
|
|
1469
|
+
${renderItem({
|
|
1470
|
+
...combo.config,
|
|
1471
|
+
label: 'Heading',
|
|
1472
|
+
options: {
|
|
1473
|
+
...combo.config.options,
|
|
1474
|
+
size: ReadoutListItemSize.medium,
|
|
1475
|
+
value: framed ? {alert: VALUE_FRAME} : undefined,
|
|
1476
|
+
},
|
|
1477
|
+
})}
|
|
1478
|
+
</div>
|
|
1479
|
+
</div>
|
|
1480
|
+
`
|
|
1481
|
+
)
|
|
1482
|
+
)}
|
|
1483
|
+
</div>
|
|
1484
|
+
`,
|
|
1485
|
+
};
|
|
1486
|
+
|
|
1397
1487
|
// Each row drops a different part; the per-row outline makes it obvious that the
|
|
1398
1488
|
// row height and the bottom baseline stay constant regardless of what's missing.
|
|
1399
1489
|
const MISSING_PARTS_ROWS: {title: string; config: ReadoutItemConfig}[] = [
|
|
@@ -1498,9 +1588,11 @@ export const MissingParts: Story = {
|
|
|
1498
1588
|
* value digit edges, not both. Aligning the value edges would need either a
|
|
1499
1589
|
* constant degree reserve (which widens the smaller rows' `°` — visually
|
|
1500
1590
|
* undesirable) or pinning the value edge and letting the unit column stagger;
|
|
1501
|
-
* left for the designer.
|
|
1502
|
-
* `invalid` chip
|
|
1503
|
-
*
|
|
1591
|
+
* left for the designer. Several rows also carry per-block / row state — a value
|
|
1592
|
+
* `invalid` chip (Battery), a value alert frame (Fuel), a `low-integrity` advice
|
|
1593
|
+
* chip (Pressure), and a whole-row `low-integrity` + `invalid` setpoint + a
|
|
1594
|
+
* row-level alert frame with a badge-icon flap (Distance) — to confirm none of
|
|
1595
|
+
* them shift the aligned columns.
|
|
1504
1596
|
*/
|
|
1505
1597
|
type AlignmentRow = {
|
|
1506
1598
|
label: string;
|
|
@@ -1521,6 +1613,9 @@ type AlignmentRow = {
|
|
|
1521
1613
|
hasValueIcon?: boolean;
|
|
1522
1614
|
valueDataQuality?: ReadoutListItemDataQuality;
|
|
1523
1615
|
valueAlert?: AlertFrameConfig;
|
|
1616
|
+
setpointDataQuality?: ReadoutListItemDataQuality;
|
|
1617
|
+
adviceDataQuality?: ReadoutListItemDataQuality;
|
|
1618
|
+
alert?: AlertFrameConfig;
|
|
1524
1619
|
};
|
|
1525
1620
|
|
|
1526
1621
|
const ALIGNMENT_ROWS: AlignmentRow[] = [
|
|
@@ -1546,6 +1641,8 @@ const ALIGNMENT_ROWS: AlignmentRow[] = [
|
|
|
1546
1641
|
setpoint: 1015,
|
|
1547
1642
|
hasAdvice: true,
|
|
1548
1643
|
advice: 1008,
|
|
1644
|
+
// per-block advice low-integrity — the advice chip must not shift the columns
|
|
1645
|
+
adviceDataQuality: ReadoutListItemDataQuality.lowIntegrity,
|
|
1549
1646
|
},
|
|
1550
1647
|
// negative value + fraction + low-integrity data quality
|
|
1551
1648
|
{
|
|
@@ -1555,7 +1652,10 @@ const ALIGNMENT_ROWS: AlignmentRow[] = [
|
|
|
1555
1652
|
fractionDigits: 1,
|
|
1556
1653
|
dataQuality: ReadoutListItemDataQuality.lowIntegrity,
|
|
1557
1654
|
},
|
|
1558
|
-
// long unit + advice + setpoint (the "miles" row)
|
|
1655
|
+
// long unit + advice + setpoint (the "miles" row) — also a "kitchen sink of
|
|
1656
|
+
// state": whole row low-integrity, an invalid setpoint chip, and a row-level
|
|
1657
|
+
// alert frame with a badge-icon flap, all at once, to prove none of them shift
|
|
1658
|
+
// the aligned columns.
|
|
1559
1659
|
{
|
|
1560
1660
|
label: 'Distance',
|
|
1561
1661
|
value: 4.2,
|
|
@@ -1565,6 +1665,14 @@ const ALIGNMENT_ROWS: AlignmentRow[] = [
|
|
|
1565
1665
|
setpoint: 4.5,
|
|
1566
1666
|
hasAdvice: true,
|
|
1567
1667
|
advice: 4,
|
|
1668
|
+
dataQuality: ReadoutListItemDataQuality.lowIntegrity,
|
|
1669
|
+
setpointDataQuality: ReadoutListItemDataQuality.invalid,
|
|
1670
|
+
alert: {
|
|
1671
|
+
status: AlertType.Warning,
|
|
1672
|
+
mode: ObcAlertFrameMode.ackedActive,
|
|
1673
|
+
type: ObcAlertFrameType.SmallSideFlip,
|
|
1674
|
+
showAlertCategoryIcon: true,
|
|
1675
|
+
},
|
|
1568
1676
|
},
|
|
1569
1677
|
// kitchen sink: value + setpoint + advice + leading icon + value icon
|
|
1570
1678
|
{
|
|
@@ -1610,7 +1718,7 @@ const ALIGNMENT_ROWS: AlignmentRow[] = [
|
|
|
1610
1718
|
unit: '%',
|
|
1611
1719
|
valueAlert: {
|
|
1612
1720
|
status: AlertType.Warning,
|
|
1613
|
-
mode: ObcAlertFrameMode.
|
|
1721
|
+
mode: ObcAlertFrameMode.ackedActive,
|
|
1614
1722
|
type: ObcAlertFrameType.Regular,
|
|
1615
1723
|
},
|
|
1616
1724
|
},
|
|
@@ -1649,24 +1757,12 @@ const alignmentStyle = `
|
|
|
1649
1757
|
text-transform: uppercase; letter-spacing: 0.06em; color: var(--element-neutral-color, #777);
|
|
1650
1758
|
}
|
|
1651
1759
|
.rli-align-col {
|
|
1652
|
-
display: flex; flex-direction: column; gap:
|
|
1760
|
+
display: flex; flex-direction: column; gap: 8px; width: 480px;
|
|
1653
1761
|
padding: 8px; border: 1px dashed var(--border-divider-color, #ccc); border-radius: 8px;
|
|
1654
1762
|
}
|
|
1655
|
-
/* Debug aid (temporary): outline each readout building block (red) and the
|
|
1656
|
-
degree column (blue) so reserver widths / alignment are visible. Scoped to
|
|
1657
|
-
this story only via .rli-align-wrap — safe to delete when no longer needed. */
|
|
1658
|
-
.rli-align-wrap obc-readout-list-item::part(block) {
|
|
1659
|
-
outline: 1px solid rgba(220, 0, 0, 0.7); outline-offset: -1px;
|
|
1660
|
-
}
|
|
1661
|
-
.rli-align-wrap obc-readout-list-item::part(degree) {
|
|
1662
|
-
outline: 1px solid rgba(0, 0, 220, 0.7); outline-offset: -1px;
|
|
1663
|
-
}
|
|
1664
|
-
.rli-align-wrap obc-readout-list-item::part(degree-spacer) {
|
|
1665
|
-
outline: 1px solid rgba(0, 160, 0, 0.8); outline-offset: -1px;
|
|
1666
|
-
}
|
|
1667
1763
|
`;
|
|
1668
1764
|
|
|
1669
|
-
function renderAlignmentColumn(aligned: boolean) {
|
|
1765
|
+
function renderAlignmentColumn(aligned: boolean, showDebugOverlay: boolean) {
|
|
1670
1766
|
return html`
|
|
1671
1767
|
<div class="rli-align-col">
|
|
1672
1768
|
${ALIGNMENT_ROWS.map((row) =>
|
|
@@ -1681,12 +1777,14 @@ function renderAlignmentColumn(aligned: boolean) {
|
|
|
1681
1777
|
advice: row.advice,
|
|
1682
1778
|
hasLeadingIcon: row.hasLeadingIcon,
|
|
1683
1779
|
hasValueIcon: row.hasValueIcon,
|
|
1780
|
+
showDebugOverlay,
|
|
1684
1781
|
options: {
|
|
1685
1782
|
size: row.size ?? ReadoutListItemSize.small,
|
|
1686
1783
|
hasDegree: row.hasDegree ?? false,
|
|
1687
1784
|
fractionDigits: row.fractionDigits ?? 0,
|
|
1688
1785
|
priority: row.priority,
|
|
1689
1786
|
dataQuality: row.dataQuality,
|
|
1787
|
+
alert: row.alert,
|
|
1690
1788
|
hasLeadingIcon: row.hasLeadingIcon,
|
|
1691
1789
|
value: {
|
|
1692
1790
|
hasIcon: row.hasValueIcon,
|
|
@@ -1698,6 +1796,16 @@ function renderAlignmentColumn(aligned: boolean) {
|
|
|
1698
1796
|
// independent of each row's own fractionDigits.
|
|
1699
1797
|
...(aligned ? {spaceReserver: VALUE_RESERVER} : {}),
|
|
1700
1798
|
},
|
|
1799
|
+
// Setpoint / advice carry their per-block data quality in both
|
|
1800
|
+
// columns; the shared reserver is added only in the aligned column.
|
|
1801
|
+
setpoint: {
|
|
1802
|
+
dataQuality: row.setpointDataQuality,
|
|
1803
|
+
...(aligned ? {spaceReserver: VALUE_RESERVER} : {}),
|
|
1804
|
+
},
|
|
1805
|
+
advice: {
|
|
1806
|
+
dataQuality: row.adviceDataQuality,
|
|
1807
|
+
...(aligned ? {spaceReserver: VALUE_RESERVER} : {}),
|
|
1808
|
+
},
|
|
1701
1809
|
...(aligned
|
|
1702
1810
|
? {
|
|
1703
1811
|
// Non-degree rows reserve the degree column so their digits
|
|
@@ -1705,8 +1813,6 @@ function renderAlignmentColumn(aligned: boolean) {
|
|
|
1705
1813
|
hasDegreeSpacer: !(row.hasDegree ?? false),
|
|
1706
1814
|
maxDigits: MAX_INTEGER_DIGITS,
|
|
1707
1815
|
unit: {spaceReserver: LONGEST_UNIT},
|
|
1708
|
-
setpoint: {spaceReserver: VALUE_RESERVER},
|
|
1709
|
-
advice: {spaceReserver: VALUE_RESERVER},
|
|
1710
1816
|
}
|
|
1711
1817
|
: {}),
|
|
1712
1818
|
},
|
|
@@ -1716,8 +1822,18 @@ function renderAlignmentColumn(aligned: boolean) {
|
|
|
1716
1822
|
`;
|
|
1717
1823
|
}
|
|
1718
1824
|
|
|
1719
|
-
export const ColumnAlignment:
|
|
1720
|
-
|
|
1825
|
+
export const ColumnAlignment: StoryObj<
|
|
1826
|
+
ReadoutListItemStoryArgs & {showDebugOverlay: boolean}
|
|
1827
|
+
> = {
|
|
1828
|
+
args: {showDebugOverlay: true},
|
|
1829
|
+
argTypes: {
|
|
1830
|
+
showDebugOverlay: {
|
|
1831
|
+
name: 'Show Debug Overlay',
|
|
1832
|
+
control: {type: 'boolean'},
|
|
1833
|
+
table: {category: 'Debug'},
|
|
1834
|
+
},
|
|
1835
|
+
},
|
|
1836
|
+
render: (args) => html`
|
|
1721
1837
|
<style>
|
|
1722
1838
|
${alignmentStyle}
|
|
1723
1839
|
</style>
|
|
@@ -1726,13 +1842,13 @@ export const ColumnAlignment: Story = {
|
|
|
1726
1842
|
<h3 class="rli-align-section-title">
|
|
1727
1843
|
Without reservers — columns drift
|
|
1728
1844
|
</h3>
|
|
1729
|
-
${renderAlignmentColumn(false)}
|
|
1845
|
+
${renderAlignmentColumn(false, args.showDebugOverlay)}
|
|
1730
1846
|
</section>
|
|
1731
1847
|
<section class="rli-align-section">
|
|
1732
1848
|
<h3 class="rli-align-section-title">
|
|
1733
1849
|
With shared reservers — unit column & value right edge aligned
|
|
1734
1850
|
</h3>
|
|
1735
|
-
${renderAlignmentColumn(true)}
|
|
1851
|
+
${renderAlignmentColumn(true, args.showDebugOverlay)}
|
|
1736
1852
|
</section>
|
|
1737
1853
|
</div>
|
|
1738
1854
|
`,
|