@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.87 → 2.0.0-next.89

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 (40) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +17409 -16824
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +755 -44
  4. package/dist/building-blocks/readout-block/readout-block.css.js +229 -0
  5. package/dist/building-blocks/readout-block/readout-block.css.js.map +1 -0
  6. package/dist/building-blocks/readout-block/readout-block.d.ts +146 -0
  7. package/dist/building-blocks/readout-block/readout-block.d.ts.map +1 -0
  8. package/dist/building-blocks/readout-block/readout-block.js +273 -0
  9. package/dist/building-blocks/readout-block/readout-block.js.map +1 -0
  10. package/dist/navigation-instruments/gauge-radial/gauge-radial.css.js +58 -32
  11. package/dist/navigation-instruments/gauge-radial/gauge-radial.css.js.map +1 -1
  12. package/dist/navigation-instruments/gauge-radial/gauge-radial.d.ts +28 -0
  13. package/dist/navigation-instruments/gauge-radial/gauge-radial.d.ts.map +1 -1
  14. package/dist/navigation-instruments/gauge-radial/gauge-radial.js +25 -2
  15. package/dist/navigation-instruments/gauge-radial/gauge-radial.js.map +1 -1
  16. package/dist/navigation-instruments/readout-list/readout-list.css.js +24 -0
  17. package/dist/navigation-instruments/readout-list/readout-list.css.js.map +1 -0
  18. package/dist/navigation-instruments/readout-list/readout-list.d.ts +70 -0
  19. package/dist/navigation-instruments/readout-list/readout-list.d.ts.map +1 -0
  20. package/dist/navigation-instruments/readout-list/readout-list.js +154 -0
  21. package/dist/navigation-instruments/readout-list/readout-list.js.map +1 -0
  22. package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js +80 -145
  23. package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js.map +1 -1
  24. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts +25 -26
  25. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
  26. package/dist/navigation-instruments/readout-list-item/readout-list-item.js +66 -118
  27. package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
  28. package/package.json +1 -1
  29. package/src/building-blocks/readout-block/readout-block.css +192 -0
  30. package/src/building-blocks/readout-block/readout-block.stories.ts +346 -0
  31. package/src/building-blocks/readout-block/readout-block.ts +355 -0
  32. package/src/navigation-instruments/gauge-radial/gauge-radial.css +53 -30
  33. package/src/navigation-instruments/gauge-radial/gauge-radial.stories.ts +50 -0
  34. package/src/navigation-instruments/gauge-radial/gauge-radial.ts +35 -0
  35. package/src/navigation-instruments/readout-list/readout-list.css +13 -0
  36. package/src/navigation-instruments/readout-list/readout-list.stories.ts +275 -0
  37. package/src/navigation-instruments/readout-list/readout-list.ts +216 -0
  38. package/src/navigation-instruments/readout-list-item/readout-list-item.css +75 -128
  39. package/src/navigation-instruments/readout-list-item/readout-list-item.stories.ts +18 -17
  40. package/src/navigation-instruments/readout-list-item/readout-list-item.ts +84 -140
@@ -0,0 +1,192 @@
1
+ * {
2
+ box-sizing: border-box;
3
+ }
4
+
5
+ :host {
6
+ display: inline-flex;
7
+ align-items: flex-end;
8
+ }
9
+
10
+ /* ---------- Readout building block (advice / setpoint / value) ---------- */
11
+ .block {
12
+ display: inline-flex;
13
+ align-items: flex-end;
14
+ }
15
+
16
+ /* Number + its (setpoint/advice) degree glyph, hugging with no gap — the
17
+ `.block` gap only separates the icon from this group. */
18
+ .block-content {
19
+ display: inline-flex;
20
+ align-items: flex-end;
21
+ }
22
+
23
+ .block-icon {
24
+ display: inline-flex;
25
+ align-items: center;
26
+ justify-content: center;
27
+ flex: none;
28
+ color: inherit;
29
+ /* Centre the icon against the block's text rather than bottom-aligning it (the
30
+ block is flex-end). Matters for the value block, whose text is taller than
31
+ the icon, so the value icon lines up with the number like the smaller
32
+ setpoint/advice icons do. */
33
+ align-self: center;
34
+ }
35
+
36
+ .block-icon obi-input-right,
37
+ .block-icon obi-notification-advice,
38
+ .block-icon ::slotted(*) {
39
+ display: block;
40
+ inline-size: 100%;
41
+ block-size: 100%;
42
+ }
43
+
44
+ .hinted-zero {
45
+ color: var(--obc-readout-block-hinted-color, var(--element-inactive-color));
46
+ }
47
+
48
+ /* ---------- Text colours (overridable via custom properties) ----------
49
+ * obc-textbox does not set its own colour, so it inherits these. */
50
+ .block-value {
51
+ color: var(--obc-readout-block-value-color, var(--element-neutral-color));
52
+ }
53
+ .block-value.tone-enhanced {
54
+ color: var(
55
+ --obc-readout-block-value-enhanced-color,
56
+ var(--element-neutral-enhanced-color)
57
+ );
58
+ }
59
+ /* The setpoint shares the value's colour state: neutral by default, enhanced
60
+ (blue) only when the row is enhanced — never a blue setpoint next to a grey
61
+ value. `--instrument-enhanced-secondary-color` is the same #2d548b as the
62
+ value's `--element-neutral-enhanced-color`. */
63
+ .block-setpoint {
64
+ color: var(--obc-readout-block-setpoint-color, var(--element-neutral-color));
65
+ /* Flip-flop emphasis + pop-up fade animate at 100ms. */
66
+ transition:
67
+ opacity 100ms ease,
68
+ color 100ms ease;
69
+ }
70
+ .block-setpoint.tone-enhanced {
71
+ color: var(
72
+ --obc-readout-block-setpoint-enhanced-color,
73
+ var(--instrument-enhanced-secondary-color)
74
+ );
75
+ }
76
+ /* Pop-up: fade the setpoint out once value === setpoint, keeping its space so
77
+ the value stays column-aligned. */
78
+ .block-setpoint.is-hiding {
79
+ opacity: 0;
80
+ }
81
+ .block-setpoint.is-hidden {
82
+ opacity: 0;
83
+ visibility: hidden;
84
+ }
85
+ /* Touching / focus state: the setpoint triangle takes the marker's focus look — a
86
+ pale fill (--base-blue-100) with a dark 1px edge (--element-neutral-enhanced),
87
+ mirroring `svghelpers/setpoint.ts` focus (fill base-blue-100 + 2px stroke).
88
+ The glyph icon is `fill: currentColor` and can't take a CSS `stroke`, so the
89
+ edge is layered drop-shadows. The setpoint number keeps its normal, readable
90
+ colour. */
91
+ .block-setpoint.touching {
92
+ --_touching-outline: var(
93
+ --obc-readout-block-setpoint-touching-outline-color,
94
+ var(--element-neutral-enhanced-color)
95
+ );
96
+ }
97
+ .block-setpoint.touching .block-icon {
98
+ color: var(--obc-readout-block-setpoint-touching-color, var(--base-blue-100));
99
+ filter: drop-shadow(1px 0 0 var(--_touching-outline))
100
+ drop-shadow(-1px 0 0 var(--_touching-outline))
101
+ drop-shadow(0 1px 0 var(--_touching-outline))
102
+ drop-shadow(0 -1px 0 var(--_touching-outline));
103
+ }
104
+ .block-advice {
105
+ color: var(--obc-readout-block-advice-color, var(--element-neutral-color));
106
+ }
107
+
108
+ /* ---------- Per-block data quality ----------
109
+ * Uses `outline` (not `border`) so the chip never shifts the block's width — the
110
+ * value stays column-aligned across rows. */
111
+ .block.data-low-integrity,
112
+ .block.data-invalid {
113
+ outline: 1px solid;
114
+ border-radius: var(--global-border-radius-border-radius-check);
115
+ }
116
+ .block.data-low-integrity {
117
+ background: var(--alert-low-integrity-background-color);
118
+ outline-color: var(--alert-low-integrity-border-color);
119
+ }
120
+ .block.data-invalid {
121
+ background: var(--alert-invalid-background-color);
122
+ outline-color: var(--alert-invalid-border-color);
123
+ }
124
+
125
+ /* ---------- Degree column ----------
126
+ * A cap-height `°` column whose width scales with the number size; it inherits
127
+ * the block's colour. */
128
+ .degree-column {
129
+ flex: none;
130
+ display: inline-flex;
131
+ align-items: flex-end;
132
+ justify-content: center;
133
+ inline-size: var(--_obc-readout-block-degree-width, 0);
134
+ overflow: clip;
135
+ }
136
+ .degree-column.degree-inherit {
137
+ color: inherit;
138
+ }
139
+ .degree-column.degree-xs {
140
+ --_obc-readout-block-degree-width: var(
141
+ --global-typography-instrument-value-small-degree-unit-width
142
+ );
143
+ }
144
+ .degree-column.degree-s {
145
+ --_obc-readout-block-degree-width: var(
146
+ --global-typography-instrument-value-regular-degree-unit-width
147
+ );
148
+ }
149
+ .degree-column.degree-m {
150
+ --_obc-readout-block-degree-width: var(
151
+ --global-typography-instrument-value-medium-degree-unit-width
152
+ );
153
+ }
154
+ .degree-column.degree-l,
155
+ .degree-column.degree-xl {
156
+ --_obc-readout-block-degree-width: var(
157
+ --global-typography-instrument-value-large-degree-unit-width
158
+ );
159
+ }
160
+
161
+ /* ---------- Size tiers ----------
162
+ * Public small/medium/large map to the design token regular/medium/large
163
+ * tiers. */
164
+ .block.size-small {
165
+ gap: var(--instrument-components-readout-new-general-regular-icon-gap);
166
+ }
167
+ .size-small .block-icon {
168
+ inline-size: var(
169
+ --instrument-components-readout-new-general-regular-icon-size
170
+ );
171
+ block-size: var(
172
+ --instrument-components-readout-new-general-regular-icon-size
173
+ );
174
+ }
175
+
176
+ .block.size-medium {
177
+ gap: var(--instrument-components-readout-new-general-medium-icon-gap);
178
+ }
179
+ .size-medium .block-icon {
180
+ inline-size: var(
181
+ --instrument-components-readout-new-general-medium-icon-size
182
+ );
183
+ block-size: var(--instrument-components-readout-new-general-medium-icon-size);
184
+ }
185
+
186
+ .block.size-large {
187
+ gap: var(--instrument-components-readout-new-general-large-icon-gap);
188
+ }
189
+ .size-large .block-icon {
190
+ inline-size: var(--instrument-components-readout-new-general-large-icon-size);
191
+ block-size: var(--instrument-components-readout-new-general-large-icon-size);
192
+ }
@@ -0,0 +1,346 @@
1
+ import type {Meta, StoryObj} from '@storybook/web-components-vite';
2
+ import {html, nothing} from 'lit';
3
+ import {
4
+ ReadoutBlockVariant,
5
+ ReadoutBlockSize,
6
+ ReadoutBlockDataQuality,
7
+ ObcTextboxFontWeight,
8
+ ObcTextboxAlignment,
9
+ } from './readout-block.js';
10
+ import './readout-block.js';
11
+ import '../../icons/icon-placeholder.js';
12
+ import {
13
+ ObcAlertFrameMode,
14
+ ObcAlertFrameType,
15
+ } from '../../components/alert-frame/alert-frame.js';
16
+ import {AlertType} from '../../types.js';
17
+
18
+ const NONE = 'none';
19
+
20
+ type BlockArgs = {
21
+ variant: ReadoutBlockVariant;
22
+ value: number;
23
+ size: ReadoutBlockSize;
24
+ enhanced: boolean;
25
+ weight: ObcTextboxFontWeight;
26
+ hasDegree: boolean;
27
+ hasIcon: boolean;
28
+ fractionDigits: number;
29
+ maxDigits: number;
30
+ hintedZeros: boolean;
31
+ spaceReserver: string;
32
+ off: boolean;
33
+ offText: string;
34
+ alignment: ObcTextboxAlignment;
35
+ dataQuality: ReadoutBlockDataQuality | typeof NONE;
36
+ };
37
+
38
+ // A faithful single-block render. The block inherits its colour from the host
39
+ // context (the list-item normally drives it), so standalone it shows the neutral
40
+ // default tone; `enhanced` switches to the accent tone.
41
+ function renderBlock(args: Partial<BlockArgs>) {
42
+ return html`
43
+ <obc-readout-block
44
+ .variant=${args.variant ?? ReadoutBlockVariant.value}
45
+ .value=${args.value ?? null}
46
+ .size=${args.size ?? ReadoutBlockSize.small}
47
+ .enhanced=${args.enhanced ?? false}
48
+ .weight=${args.weight ?? ObcTextboxFontWeight.regular}
49
+ .hasDegree=${args.hasDegree ?? false}
50
+ .hasIcon=${args.hasIcon ?? false}
51
+ .fractionDigits=${args.fractionDigits ?? 0}
52
+ .maxDigits=${args.maxDigits ?? 0}
53
+ .hintedZeros=${args.hintedZeros ?? false}
54
+ .spaceReserver=${args.spaceReserver || undefined}
55
+ .off=${args.off ?? false}
56
+ .offText=${args.offText ?? 'OFF'}
57
+ .alignment=${args.alignment ?? ObcTextboxAlignment.Right}
58
+ .dataQuality=${args.dataQuality === NONE ? undefined : args.dataQuality}
59
+ >
60
+ ${args.hasIcon
61
+ ? html`<obi-placeholder slot="icon"></obi-placeholder>`
62
+ : nothing}
63
+ </obc-readout-block>
64
+ `;
65
+ }
66
+
67
+ const themedDecorator = (story: () => unknown) => html`
68
+ <div
69
+ data-obc-theme="day"
70
+ style="background: var(--container-background-color); padding: 24px; display: inline-block;"
71
+ >
72
+ ${story()}
73
+ </div>
74
+ `;
75
+
76
+ const showcaseStyle = `
77
+ .rb-grid { display: flex; flex-wrap: wrap; gap: 24px; align-items: flex-end; }
78
+ .rb-card {
79
+ display: flex; flex-direction: column; gap: 8px; align-items: flex-start;
80
+ padding: 12px; border-radius: 8px; background: rgba(0, 0, 0, 0.03);
81
+ }
82
+ .rb-card-title {
83
+ font: 10px/1.2 var(--global-typography-ui-label-font-family, sans-serif);
84
+ text-transform: uppercase; letter-spacing: 0.06em; color: var(--element-neutral-color, #777);
85
+ }
86
+ .rb-cell { outline: 1px dashed rgba(0, 0, 0, 0.12); }
87
+ `;
88
+
89
+ type ShowcaseCard = {title: string; args: Partial<BlockArgs>};
90
+
91
+ function renderShowcase(cards: ShowcaseCard[]) {
92
+ return html`
93
+ <style>
94
+ ${showcaseStyle}
95
+ </style>
96
+ <div class="rb-grid">
97
+ ${cards.map(
98
+ (card) => html`
99
+ <div class="rb-card">
100
+ <div class="rb-card-title">${card.title}</div>
101
+ <div class="rb-cell">${renderBlock(card.args)}</div>
102
+ </div>
103
+ `
104
+ )}
105
+ </div>
106
+ `;
107
+ }
108
+
109
+ const meta = {
110
+ title: 'Building Blocks/Readout Block',
111
+ tags: ['autodocs', '6.0', 'wip'],
112
+ component: 'obc-readout-block',
113
+ decorators: [themedDecorator],
114
+ parameters: {
115
+ docs: {
116
+ description: {
117
+ component:
118
+ 'The most atomic readout primitive — a single cap-height, ' +
119
+ 'width-reservable numeric segment (value / setpoint / advice). It is the ' +
120
+ 'building block used inside `obc-readout-list-item` (and, in a future ' +
121
+ 'refactor, inside `obc-readout`); it is not normally used on its own. ' +
122
+ 'Colour is inherited from the host context, so standalone it shows the ' +
123
+ 'neutral tone.',
124
+ },
125
+ },
126
+ },
127
+ render: (args) => renderBlock(args),
128
+ args: {
129
+ variant: ReadoutBlockVariant.value,
130
+ value: 123,
131
+ size: ReadoutBlockSize.small,
132
+ enhanced: false,
133
+ weight: ObcTextboxFontWeight.regular,
134
+ hasDegree: false,
135
+ hasIcon: false,
136
+ fractionDigits: 0,
137
+ maxDigits: 0,
138
+ hintedZeros: false,
139
+ spaceReserver: '',
140
+ off: false,
141
+ offText: 'OFF',
142
+ alignment: ObcTextboxAlignment.Right,
143
+ dataQuality: NONE,
144
+ },
145
+ argTypes: {
146
+ variant: {
147
+ control: {type: 'select'},
148
+ options: Object.values(ReadoutBlockVariant),
149
+ },
150
+ size: {
151
+ control: {type: 'select'},
152
+ options: Object.values(ReadoutBlockSize),
153
+ },
154
+ weight: {
155
+ control: {type: 'select'},
156
+ options: Object.values(ObcTextboxFontWeight),
157
+ },
158
+ alignment: {
159
+ control: {type: 'select'},
160
+ options: Object.values(ObcTextboxAlignment),
161
+ },
162
+ fractionDigits: {control: {type: 'number', min: 0, step: 1}},
163
+ maxDigits: {control: {type: 'number', min: 0, step: 1}},
164
+ spaceReserver: {control: {type: 'text'}},
165
+ offText: {control: {type: 'text'}},
166
+ dataQuality: {
167
+ control: {type: 'select'},
168
+ options: [NONE, ...Object.values(ReadoutBlockDataQuality)],
169
+ },
170
+ },
171
+ } satisfies Meta<BlockArgs>;
172
+
173
+ export default meta;
174
+ type Story = StoryObj<BlockArgs>;
175
+
176
+ export const Playground: Story = {};
177
+
178
+ export const Variants: Story = {
179
+ render: () =>
180
+ renderShowcase([
181
+ {title: 'value', args: {variant: ReadoutBlockVariant.value, value: 123}},
182
+ {
183
+ title: 'setpoint',
184
+ args: {variant: ReadoutBlockVariant.setpoint, value: 120},
185
+ },
186
+ {
187
+ title: 'advice',
188
+ args: {variant: ReadoutBlockVariant.advice, value: 118},
189
+ },
190
+ ]),
191
+ };
192
+
193
+ export const Sizes: Story = {
194
+ render: () =>
195
+ renderShowcase(
196
+ [
197
+ ReadoutBlockSize.small,
198
+ ReadoutBlockSize.medium,
199
+ ReadoutBlockSize.large,
200
+ ].map((size) => ({
201
+ title: size,
202
+ args: {size, value: 123, hasDegree: true},
203
+ }))
204
+ ),
205
+ };
206
+
207
+ export const Tone: Story = {
208
+ render: () =>
209
+ renderShowcase([
210
+ {title: 'regular', args: {value: 123, enhanced: false}},
211
+ {title: 'enhanced', args: {value: 123, enhanced: true}},
212
+ ]),
213
+ };
214
+
215
+ export const Weight: Story = {
216
+ render: () =>
217
+ renderShowcase(
218
+ [
219
+ ObcTextboxFontWeight.regular,
220
+ ObcTextboxFontWeight.semibold,
221
+ ObcTextboxFontWeight.bold,
222
+ ].map((weight) => ({title: weight, args: {value: 123, weight}}))
223
+ ),
224
+ };
225
+
226
+ export const Degree: Story = {
227
+ render: () =>
228
+ renderShowcase([
229
+ {title: 'no degree', args: {value: 287}},
230
+ {title: 'degree', args: {value: 287, hasDegree: true}},
231
+ ]),
232
+ };
233
+
234
+ /**
235
+ * `off` renders `offText` (default `"OFF"`) in place of the value.
236
+ */
237
+ export const OffText: Story = {
238
+ render: () =>
239
+ renderShowcase([
240
+ {title: 'OFF (default)', args: {off: true}},
241
+ {title: 'custom', args: {off: true, offText: 'unavailable'}},
242
+ ]),
243
+ };
244
+
245
+ /**
246
+ * Hinted zeros pad the integer part up to `maxDigits` as muted leading zeros.
247
+ * When enabled they take priority over `spaceReserver` (they already fill to
248
+ * `maxDigits`, so an explicit reserver is ignored).
249
+ */
250
+ export const HintedZeros: Story = {
251
+ render: () =>
252
+ renderShowcase([
253
+ {title: 'value 8, maxDigits 4', args: {value: 8, maxDigits: 4}},
254
+ {
255
+ title: 'hinted zeros',
256
+ args: {value: 8, maxDigits: 4, hintedZeros: true},
257
+ },
258
+ {
259
+ title: 'hinted zeros + fraction',
260
+ args: {value: 8, maxDigits: 4, fractionDigits: 1, hintedZeros: true},
261
+ },
262
+ {
263
+ title: 'hinted wins over reserver',
264
+ args: {
265
+ value: 8,
266
+ maxDigits: 4,
267
+ hintedZeros: true,
268
+ spaceReserver: '00000000',
269
+ },
270
+ },
271
+ ]),
272
+ };
273
+
274
+ /**
275
+ * `maxDigits` reserves INTEGER digits only — independent of `fractionDigits`
276
+ * (the decimal point and fraction digits never count toward `maxDigits`).
277
+ */
278
+ export const MaxDigitsAndFractionDigits: Story = {
279
+ render: () =>
280
+ renderShowcase([
281
+ {title: 'maxDigits 4', args: {value: 12, maxDigits: 4}},
282
+ {
283
+ title: 'maxDigits 4, frac 1',
284
+ args: {value: 12, maxDigits: 4, fractionDigits: 1},
285
+ },
286
+ {
287
+ title: 'maxDigits 4, frac 2',
288
+ args: {value: 12.5, maxDigits: 4, fractionDigits: 2},
289
+ },
290
+ ]),
291
+ };
292
+
293
+ export const Alignment: Story = {
294
+ render: () =>
295
+ renderShowcase(
296
+ [
297
+ ObcTextboxAlignment.Left,
298
+ ObcTextboxAlignment.Center,
299
+ ObcTextboxAlignment.Right,
300
+ ].map((alignment) => ({
301
+ title: alignment,
302
+ // A wide reserver makes the alignment within the reserved width visible.
303
+ args: {value: 12, alignment, spaceReserver: '00000'},
304
+ }))
305
+ ),
306
+ };
307
+
308
+ export const DataQuality: Story = {
309
+ render: () =>
310
+ renderShowcase([
311
+ {title: 'nominal', args: {value: 123}},
312
+ {
313
+ title: 'low-integrity',
314
+ args: {value: 123, dataQuality: ReadoutBlockDataQuality.lowIntegrity},
315
+ },
316
+ {
317
+ title: 'invalid',
318
+ args: {value: 123, dataQuality: ReadoutBlockDataQuality.invalid},
319
+ },
320
+ {title: 'null (dash)', args: {value: undefined}},
321
+ ]),
322
+ };
323
+
324
+ export const Alert: Story = {
325
+ render: () => html`
326
+ <style>
327
+ ${showcaseStyle}
328
+ </style>
329
+ <div class="rb-grid">
330
+ <div class="rb-card">
331
+ <div class="rb-card-title">value alert (warning)</div>
332
+ <div class="rb-cell">
333
+ <obc-readout-block
334
+ .variant=${ReadoutBlockVariant.value}
335
+ .value=${123}
336
+ .alert=${{
337
+ status: AlertType.Warning,
338
+ mode: ObcAlertFrameMode.unackedActive,
339
+ type: ObcAlertFrameType.Regular,
340
+ }}
341
+ ></obc-readout-block>
342
+ </div>
343
+ </div>
344
+ </div>
345
+ `,
346
+ };