@oicl/openbridge-webcomponents-full-bundle 2.0.0-next.128 → 2.0.0-next.129
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 +12321 -11895
- package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
- package/custom-elements.json +227 -3
- package/dist/building-blocks/readout-block/readout-block.css.js +53 -19
- package/dist/building-blocks/readout-block/readout-block.css.js.map +1 -1
- package/dist/building-blocks/readout-block/readout-block.d.ts +55 -0
- package/dist/building-blocks/readout-block/readout-block.d.ts.map +1 -1
- package/dist/building-blocks/readout-block/readout-block.js +57 -2
- package/dist/building-blocks/readout-block/readout-block.js.map +1 -1
- package/dist/navigation-instruments/readout/readout-shared.d.ts +23 -0
- package/dist/navigation-instruments/readout/readout-shared.d.ts.map +1 -1
- package/dist/navigation-instruments/readout/readout-shared.js +8 -0
- package/dist/navigation-instruments/readout/readout-shared.js.map +1 -1
- package/dist/navigation-instruments/readout/readout.css.js +138 -31
- package/dist/navigation-instruments/readout/readout.css.js.map +1 -1
- package/dist/navigation-instruments/readout/readout.d.ts +63 -3
- package/dist/navigation-instruments/readout/readout.d.ts.map +1 -1
- package/dist/navigation-instruments/readout/readout.js +127 -27
- package/dist/navigation-instruments/readout/readout.js.map +1 -1
- package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js +64 -1
- 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 +77 -2
- 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 +100 -23
- 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 +49 -20
- package/src/building-blocks/readout-block/readout-block.stories.ts +54 -0
- package/src/building-blocks/readout-block/readout-block.ts +101 -2
- package/src/navigation-instruments/instrument-field/instrument-field.stories.ts +1150 -180
- package/src/navigation-instruments/readout/readout-shared.spec.ts +50 -0
- package/src/navigation-instruments/readout/readout-shared.ts +33 -0
- package/src/navigation-instruments/readout/readout.css +124 -32
- package/src/navigation-instruments/readout/readout.stories.ts +536 -19
- package/src/navigation-instruments/readout/readout.ts +184 -31
- package/src/navigation-instruments/readout-list-item/readout-list-item.css +55 -1
- package/src/navigation-instruments/readout-list-item/readout-list-item.stories.ts +341 -0
- package/src/navigation-instruments/readout-list-item/readout-list-item.ts +169 -25
|
@@ -1,245 +1,1215 @@
|
|
|
1
1
|
import type {Meta, StoryObj} from '@storybook/web-components-vite';
|
|
2
|
-
import {
|
|
2
|
+
import {html, nothing, type TemplateResult} from 'lit';
|
|
3
3
|
import './instrument-field.js';
|
|
4
|
-
import {
|
|
5
|
-
import '
|
|
4
|
+
import {InstrumentFieldSize} from './instrument-field.js';
|
|
5
|
+
import '../readout/readout.js';
|
|
6
|
+
import {
|
|
7
|
+
ReadoutSize,
|
|
8
|
+
ReadoutPriority,
|
|
9
|
+
ReadoutDirection,
|
|
10
|
+
ReadoutAlignment,
|
|
11
|
+
ReadoutSetpointInteraction,
|
|
12
|
+
} from '../readout/readout.js';
|
|
13
|
+
import '../readout-list-item/readout-list-item.js';
|
|
14
|
+
import {
|
|
15
|
+
ReadoutListItemSize,
|
|
16
|
+
ReadoutListItemPriority,
|
|
17
|
+
ReadoutListItemStacking,
|
|
18
|
+
} from '../readout-list-item/readout-list-item.js';
|
|
6
19
|
|
|
7
|
-
|
|
8
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Migration reference: every `<obc-instrument-field>` story rendered next to
|
|
22
|
+
* its closest `<obc-readout>` configuration.
|
|
23
|
+
*
|
|
24
|
+
* The deprecated `<obc-instrument-field>` is on the left, the closest
|
|
25
|
+
* `<obc-readout>` configuration on the right, and a verdict underneath saying
|
|
26
|
+
* whether the two match, differ in a named way, or cannot be reconciled today.
|
|
27
|
+
* Verdicts were re-evaluated against the Figma 6.1 review (#1145): several
|
|
28
|
+
* gaps from the original comparison (#1107) are now closed — `equal-size`
|
|
29
|
+
* covers the legacy equal-sized setpoint layouts, and
|
|
30
|
+
* `labelOptions.spaceReserver` closes the label-alignment gap.
|
|
31
|
+
*
|
|
32
|
+
* These are manual-mode stories: the args panel is deliberately not wired
|
|
33
|
+
* because the point is a fixed, comparable pair, not a playground. Use the
|
|
34
|
+
* `Instruments/Readout` entry for interactive controls.
|
|
35
|
+
*/
|
|
36
|
+
const meta = {
|
|
37
|
+
title: 'Instruments/Instrument Field (deprecated)',
|
|
9
38
|
tags: ['autodocs', '6.0', 'deprecated'],
|
|
10
39
|
component: 'obc-instrument-field',
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
40
|
+
parameters: {
|
|
41
|
+
docs: {
|
|
42
|
+
description: {
|
|
43
|
+
component: `# Instrument Field → Readout
|
|
44
|
+
|
|
45
|
+
\`<obc-instrument-field>\` is deprecated in favour of \`<obc-readout>\`. Each story
|
|
46
|
+
below shows the legacy component next to its closest \`<obc-readout>\`
|
|
47
|
+
configuration and states how close the result is, so external consumers have a
|
|
48
|
+
recipe for migrating. Verdicts follow the Figma 6.1 review (#1145).
|
|
49
|
+
|
|
50
|
+
## Verdicts
|
|
51
|
+
|
|
52
|
+
| Badge | Meaning |
|
|
53
|
+
|-------|---------|
|
|
54
|
+
| **Fully covered** | The readout API expresses the case. Only the shared restyle below differs. |
|
|
55
|
+
| **Differs** | Reproducible, but with a case-specific difference on top of the restyle. |
|
|
56
|
+
| **Not reachable** | Cannot be produced with \`<obc-readout>\` as it stands. |
|
|
57
|
+
|
|
58
|
+
Nothing is pixel-identical: \`<obc-readout>\` is the OB 6.1 redraw of the same
|
|
59
|
+
information, so **Fully covered** means "no API gap", not "same pixels".
|
|
60
|
+
|
|
61
|
+
## Shared restyle differences
|
|
62
|
+
|
|
63
|
+
These apply to *every* story below and are not repeated in each verdict.
|
|
64
|
+
|
|
65
|
+
1. **Typography** — \`obc-instrument-field\` sizes text by \`font-size\`; the readout
|
|
66
|
+
stack sizes it by cap height through \`obc-textbox\`. The tiers line up by
|
|
67
|
+
design, not by measurement.
|
|
68
|
+
2. **Label size & weight** — per the 6.1 review, large readouts render the
|
|
69
|
+
label at textbox \`s\` (bigger than the legacy tag) and labels are SemiBold
|
|
70
|
+
only on \`enhanced\`-priority readouts. The legacy \`tag\` is always regular
|
|
71
|
+
weight, so the weights agree at \`priority="regular"\` and differ (SemiBold)
|
|
72
|
+
at \`priority="enhanced"\`. \`labelOptions.size: 'xs'\` opts back into the
|
|
73
|
+
dense label.
|
|
74
|
+
3. **Setpoint marker** — the \`obi-input-right\` chevron replaces the legacy
|
|
75
|
+
inline triangle. Since 6.1 the marker's size follows the setpoint block's
|
|
76
|
+
rendered size (16px beside an \`s\` setpoint, 24px beside \`l\`).
|
|
77
|
+
4. **Setpoint emphasis** — \`<obc-readout>\` defaults to primary-secondary (the
|
|
78
|
+
setpoint one tier below the value). The 6.1 \`equal-size\` interaction now
|
|
79
|
+
reproduces the legacy layouts that rendered both at the same size:
|
|
80
|
+
|
|
81
|
+
| Legacy layout | Legacy setpoint/value | Readout equivalent |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| vertical + \`regular\` | 16px / 16px | \`size="small"\` + \`equal-size\` |
|
|
84
|
+
| vertical + \`enhanced\` | 16px / 34px | \`size="large"\` (default) |
|
|
85
|
+
| horizontal + \`regular\` | 16px / 16px | not reachable — see *Horizontal Regular* |
|
|
86
|
+
| horizontal + \`enhanced\` | 34px / 34px | \`size="large"\` + \`equal-size\` |
|
|
87
|
+
|
|
88
|
+
5. **Hinted zeros** — legacy paints them \`--border-outline-color\`; per the 6.1
|
|
89
|
+
review the readout uses the lighter \`--element-disabled-color\` and always
|
|
90
|
+
regular weight.
|
|
91
|
+
6. **Vertical source** — legacy renders the source directly under the label
|
|
92
|
+
with no divider, and since 6.1 the vertical readout does the same (only the
|
|
93
|
+
horizontal direction separates the source with a vertical rule).
|
|
94
|
+
|
|
95
|
+
## Property mapping
|
|
96
|
+
|
|
97
|
+
| \`<obc-instrument-field>\` | \`<obc-readout>\` |
|
|
98
|
+
|---|---|
|
|
99
|
+
| \`size="regular"\` | \`size="small"\` |
|
|
100
|
+
| \`size="enhanced"\` | \`size="large"\` |
|
|
101
|
+
| — | \`size="medium"\` (new intermediate tier) |
|
|
102
|
+
| \`tag\` | \`label\` |
|
|
103
|
+
| \`unit\`, \`src\`, \`value\`, \`setpoint\`, \`hasSetpoint\`, \`fractionDigits\` | same names |
|
|
104
|
+
| \`hasSrc\` | derived from a non-blank \`src\` |
|
|
105
|
+
| *(default)* | \`priority="enhanced"\` |
|
|
106
|
+
| \`neutralColor\` | \`priority="regular"\` |
|
|
107
|
+
| \`showZeroPadding\` | \`valueOptions.hintedZeros\` |
|
|
108
|
+
| \`maxDigits\` | \`maxDigits\` — **different semantics**, see *Max Digits With Decimals* |
|
|
109
|
+
| \`horizontal\` | \`direction="horizontal"\` |
|
|
110
|
+
| \`center\` | \`alignment="center"\` |
|
|
111
|
+
| \`labelOnly\` | \`hasValue={false}\` |
|
|
112
|
+
| *(equal-sized setpoint layouts)* | \`setpointOptions.interaction="equal-size"\` |
|
|
113
|
+
| \`autoHideSetpoint\` | \`setpointOptions.interaction="pop-up"\` |
|
|
114
|
+
| \`autoHideDeadband\` | *no equivalent* — see *Auto Hide Deadband* |
|
|
115
|
+
| \`--obc-instrument-field-source-width\` | \`srcOptions.spaceReserver\` |
|
|
116
|
+
| \`--obc-instrument-field-tag-width\` | \`labelOptions.spaceReserver\` (new in 6.1) |
|
|
117
|
+
| \`off-value\` slot | \`offText\` (plain string only) |
|
|
118
|
+
|
|
119
|
+
The colour mapping is exact rather than approximate:
|
|
120
|
+
\`--element-neutral-enhanced-color\` (readout, enhanced) and
|
|
121
|
+
\`--instrument-enhanced-secondary-color\` (instrument-field, default) resolve to
|
|
122
|
+
the same value in every theme.`,
|
|
123
|
+
},
|
|
19
124
|
},
|
|
20
125
|
},
|
|
21
|
-
} satisfies Meta
|
|
126
|
+
} satisfies Meta;
|
|
22
127
|
|
|
23
128
|
export default meta;
|
|
24
|
-
type Story = StoryObj
|
|
129
|
+
type Story = StoryObj;
|
|
130
|
+
|
|
131
|
+
/** How completely `<obc-readout>` reproduces the legacy story. */
|
|
132
|
+
enum Verdict {
|
|
133
|
+
match = 'match',
|
|
134
|
+
differs = 'differs',
|
|
135
|
+
gap = 'gap',
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const VERDICT_LABEL: Record<Verdict, string> = {
|
|
139
|
+
[Verdict.match]: 'Fully covered',
|
|
140
|
+
[Verdict.differs]: 'Differs',
|
|
141
|
+
[Verdict.gap]: 'Not reachable',
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
const comparisonStyle = `
|
|
145
|
+
.cmp {
|
|
146
|
+
border: 1px solid var(--border-divider-color);
|
|
147
|
+
border-radius: 8px;
|
|
148
|
+
overflow: hidden;
|
|
149
|
+
max-width: 900px;
|
|
150
|
+
}
|
|
151
|
+
.cmp-head {
|
|
152
|
+
display: flex; align-items: center; gap: 10px;
|
|
153
|
+
padding: 10px 12px;
|
|
154
|
+
border-bottom: 1px solid var(--border-divider-color);
|
|
155
|
+
}
|
|
156
|
+
.cmp-name {
|
|
157
|
+
font: 600 12px/1.2 var(--global-typography-font-family, inherit);
|
|
158
|
+
letter-spacing: 0.06em; text-transform: uppercase;
|
|
159
|
+
color: var(--element-active-color);
|
|
160
|
+
}
|
|
161
|
+
.cmp-badge {
|
|
162
|
+
font: 600 10px/1 var(--global-typography-font-family, inherit);
|
|
163
|
+
letter-spacing: 0.06em; text-transform: uppercase;
|
|
164
|
+
padding: 4px 8px; border-radius: 10px;
|
|
165
|
+
border: 1px solid currentColor;
|
|
166
|
+
}
|
|
167
|
+
.cmp-badge.match { color: var(--alert-success-color); }
|
|
168
|
+
.cmp-badge.differs { color: var(--alert-caution-color); }
|
|
169
|
+
.cmp-badge.gap { color: var(--alert-alarm-color); }
|
|
170
|
+
.cmp-cols { display: grid; grid-template-columns: 1fr 1fr; }
|
|
171
|
+
.cmp-col { padding: 12px; display: flex; flex-direction: column; gap: 8px; }
|
|
172
|
+
.cmp-col + .cmp-col { border-left: 1px solid var(--border-divider-color); }
|
|
173
|
+
.cmp-tag {
|
|
174
|
+
font: 10px/1.2 ui-monospace, monospace;
|
|
175
|
+
color: var(--element-neutral-color);
|
|
176
|
+
}
|
|
177
|
+
.cmp-stage {
|
|
178
|
+
display: flex; align-items: center; justify-content: center;
|
|
179
|
+
min-height: 92px; padding: 8px;
|
|
180
|
+
border-radius: 6px;
|
|
181
|
+
background: var(--container-background-color);
|
|
182
|
+
}
|
|
183
|
+
.cmp-alt { margin-top: 4px; }
|
|
184
|
+
.cmp-notes {
|
|
185
|
+
padding: 12px;
|
|
186
|
+
border-top: 1px solid var(--border-divider-color);
|
|
187
|
+
font: 12px/1.6 var(--global-typography-font-family, inherit);
|
|
188
|
+
color: var(--element-neutral-color);
|
|
189
|
+
}
|
|
190
|
+
.cmp-notes p { margin: 0 0 8px; }
|
|
191
|
+
.cmp-notes p:last-child { margin-bottom: 0; }
|
|
192
|
+
.cmp-notes code {
|
|
193
|
+
font: 11px/1.4 ui-monospace, monospace;
|
|
194
|
+
color: var(--element-active-color);
|
|
195
|
+
}
|
|
196
|
+
`;
|
|
197
|
+
|
|
198
|
+
function renderComparison(config: {
|
|
199
|
+
name: string;
|
|
200
|
+
verdict: Verdict;
|
|
201
|
+
legacy: TemplateResult;
|
|
202
|
+
modern: TemplateResult;
|
|
203
|
+
/** A second reference render when another configuration is the real answer. */
|
|
204
|
+
modernAlt?: {tag: string; content: TemplateResult};
|
|
205
|
+
notes: TemplateResult;
|
|
206
|
+
}): TemplateResult {
|
|
207
|
+
return html`
|
|
208
|
+
<style>
|
|
209
|
+
${comparisonStyle}
|
|
210
|
+
</style>
|
|
211
|
+
<div class="cmp">
|
|
212
|
+
<div class="cmp-head">
|
|
213
|
+
<span class="cmp-name">${config.name}</span>
|
|
214
|
+
<span class="cmp-badge ${config.verdict}"
|
|
215
|
+
>${VERDICT_LABEL[config.verdict]}</span
|
|
216
|
+
>
|
|
217
|
+
</div>
|
|
218
|
+
<div class="cmp-cols">
|
|
219
|
+
<div class="cmp-col">
|
|
220
|
+
<span class="cmp-tag"><obc-instrument-field> (deprecated)</span>
|
|
221
|
+
<div class="cmp-stage">${config.legacy}</div>
|
|
222
|
+
</div>
|
|
223
|
+
<div class="cmp-col">
|
|
224
|
+
<span class="cmp-tag"><obc-readout></span>
|
|
225
|
+
<div class="cmp-stage">${config.modern}</div>
|
|
226
|
+
${config.modernAlt
|
|
227
|
+
? html`
|
|
228
|
+
<span class="cmp-tag cmp-alt">${config.modernAlt.tag}</span>
|
|
229
|
+
<div class="cmp-stage">${config.modernAlt.content}</div>
|
|
230
|
+
`
|
|
231
|
+
: nothing}
|
|
232
|
+
</div>
|
|
233
|
+
</div>
|
|
234
|
+
<div class="cmp-notes">${config.notes}</div>
|
|
235
|
+
</div>
|
|
236
|
+
`;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// The original stories inherited `setpoint: 0` and `value: 0` from the old
|
|
240
|
+
// file-level `args`. Both sides below bind the *effective* values explicitly
|
|
241
|
+
// so each pair reproduces what that story actually rendered.
|
|
25
242
|
|
|
26
243
|
export const Primary: Story = {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
244
|
+
render: () =>
|
|
245
|
+
renderComparison({
|
|
246
|
+
name: 'Primary',
|
|
247
|
+
verdict: Verdict.match,
|
|
248
|
+
legacy: html`
|
|
249
|
+
<obc-instrument-field
|
|
250
|
+
hasSetpoint
|
|
251
|
+
.setpoint=${123}
|
|
252
|
+
.value=${123}
|
|
253
|
+
tag="HDG"
|
|
254
|
+
unit="DEG"
|
|
255
|
+
></obc-instrument-field>
|
|
256
|
+
`,
|
|
257
|
+
modern: html`
|
|
258
|
+
<obc-readout
|
|
259
|
+
.size=${ReadoutSize.small}
|
|
260
|
+
.priority=${ReadoutPriority.enhanced}
|
|
261
|
+
hasSetpoint
|
|
262
|
+
.setpoint=${123}
|
|
263
|
+
.value=${123}
|
|
264
|
+
.setpointOptions=${{
|
|
265
|
+
interaction: ReadoutSetpointInteraction.equalSize,
|
|
266
|
+
}}
|
|
267
|
+
label="HDG"
|
|
268
|
+
unit="DEG"
|
|
269
|
+
></obc-readout>
|
|
270
|
+
`,
|
|
271
|
+
notes: html`
|
|
272
|
+
<p>
|
|
273
|
+
Same structure — setpoint over value, then label and unit on one row.
|
|
274
|
+
<code>size="regular"</code> maps to <code>size="small"</code>, and the
|
|
275
|
+
legacy default (<code>neutralColor</code> unset) maps to
|
|
276
|
+
<code>priority="enhanced"</code>.
|
|
277
|
+
</p>
|
|
278
|
+
<p>
|
|
279
|
+
The legacy <code>regular</code> layout renders setpoint and value at
|
|
280
|
+
the same 16px, and since 6.1
|
|
281
|
+
<code>setpointOptions.interaction="equal-size"</code> reproduces that
|
|
282
|
+
exactly (used here). Omit it and the readout defaults to
|
|
283
|
+
primary-secondary — the setpoint one tier below the value.
|
|
284
|
+
</p>
|
|
285
|
+
`,
|
|
286
|
+
}),
|
|
34
287
|
};
|
|
35
288
|
|
|
36
289
|
export const UndefinedSetpoint: Story = {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
290
|
+
render: () =>
|
|
291
|
+
renderComparison({
|
|
292
|
+
name: 'Undefined Setpoint',
|
|
293
|
+
verdict: Verdict.match,
|
|
294
|
+
legacy: html`
|
|
295
|
+
<obc-instrument-field
|
|
296
|
+
hasSetpoint
|
|
297
|
+
.setpoint=${undefined}
|
|
298
|
+
.value=${undefined}
|
|
299
|
+
tag="HDG"
|
|
300
|
+
unit="DEG"
|
|
301
|
+
></obc-instrument-field>
|
|
302
|
+
`,
|
|
303
|
+
modern: html`
|
|
304
|
+
<obc-readout
|
|
305
|
+
.size=${ReadoutSize.small}
|
|
306
|
+
.priority=${ReadoutPriority.enhanced}
|
|
307
|
+
hasSetpoint
|
|
308
|
+
.setpoint=${undefined}
|
|
309
|
+
.value=${null}
|
|
310
|
+
.setpointOptions=${{
|
|
311
|
+
interaction: ReadoutSetpointInteraction.equalSize,
|
|
312
|
+
}}
|
|
313
|
+
label="HDG"
|
|
314
|
+
unit="DEG"
|
|
315
|
+
></obc-readout>
|
|
316
|
+
`,
|
|
317
|
+
notes: html`
|
|
318
|
+
<p>
|
|
319
|
+
Both render the unavailable dash for value and setpoint. Note the
|
|
320
|
+
spelling — the two properties differ: a missing
|
|
321
|
+
<code>value</code> is <code>null</code> (its type is
|
|
322
|
+
<code>number | string | null</code>), while a missing
|
|
323
|
+
<code>setpoint</code> stays <code>undefined</code> (declared
|
|
324
|
+
<code>setpoint?: number</code>; it does not accept <code>null</code>).
|
|
325
|
+
</p>
|
|
326
|
+
<p>
|
|
327
|
+
Both emit a single dash here because the legacy
|
|
328
|
+
<code>maxDigits</code> default is 1 with padding off. The glyphs
|
|
329
|
+
differ deliberately: legacy renders the ASCII hyphen, while
|
|
330
|
+
<code>obc-readout</code> renders the digit-width U+2012 figure dash
|
|
331
|
+
(#1105), so its placeholder aligns with the digits it stands in for.
|
|
332
|
+
With padding on they also diverge in count: legacy widens the run to
|
|
333
|
+
<code>maxDigits</code> (<code>---</code>) while
|
|
334
|
+
<code>obc-readout</code> always renders one dash —
|
|
335
|
+
<code>readoutNumericFormatOptions()</code> hardcodes
|
|
336
|
+
<code>showZeroPadding: false</code>. The reserved width is unchanged
|
|
337
|
+
either way, so nothing shifts. The contracts live in
|
|
338
|
+
<code>docs/agents/readout-components.md</code>.
|
|
339
|
+
</p>
|
|
340
|
+
`,
|
|
341
|
+
}),
|
|
44
342
|
};
|
|
45
343
|
|
|
46
344
|
export const Enhanced: Story = {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
345
|
+
render: () =>
|
|
346
|
+
renderComparison({
|
|
347
|
+
name: 'Enhanced',
|
|
348
|
+
verdict: Verdict.match,
|
|
349
|
+
legacy: html`
|
|
350
|
+
<obc-instrument-field
|
|
351
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
352
|
+
hasSetpoint
|
|
353
|
+
.setpoint=${0}
|
|
354
|
+
.value=${10}
|
|
355
|
+
tag="HDG"
|
|
356
|
+
unit="/min"
|
|
357
|
+
></obc-instrument-field>
|
|
358
|
+
`,
|
|
359
|
+
modern: html`
|
|
360
|
+
<obc-readout
|
|
361
|
+
.size=${ReadoutSize.large}
|
|
362
|
+
.priority=${ReadoutPriority.enhanced}
|
|
363
|
+
hasSetpoint
|
|
364
|
+
.setpoint=${0}
|
|
365
|
+
.value=${10}
|
|
366
|
+
label="HDG"
|
|
367
|
+
unit="/min"
|
|
368
|
+
></obc-readout>
|
|
369
|
+
`,
|
|
370
|
+
notes: html`
|
|
371
|
+
<p>
|
|
372
|
+
<code>size="enhanced"</code> maps to <code>size="large"</code>, and
|
|
373
|
+
this is the one legacy layout whose sizing agrees with the readout
|
|
374
|
+
default: a 16px setpoint above a 34px value is exactly
|
|
375
|
+
primary-secondary, so no <code>equal-size</code> is needed.
|
|
376
|
+
</p>
|
|
377
|
+
<p>
|
|
378
|
+
Since 6.1 the large readout also renders its label at textbox
|
|
379
|
+
<code>s</code> — visibly closer to the legacy enhanced tag than the
|
|
380
|
+
old <code>xs</code> label was. The setpoint reads
|
|
381
|
+
<code>0</code> rather than a dash — the original story inherited
|
|
382
|
+
<code>setpoint: 0</code> from the file-level args.
|
|
383
|
+
</p>
|
|
384
|
+
`,
|
|
385
|
+
}),
|
|
54
386
|
};
|
|
55
387
|
|
|
56
388
|
export const EnhancedWithSrc: Story = {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
389
|
+
render: () =>
|
|
390
|
+
renderComparison({
|
|
391
|
+
name: 'Enhanced With Src',
|
|
392
|
+
verdict: Verdict.match,
|
|
393
|
+
legacy: html`
|
|
394
|
+
<obc-instrument-field
|
|
395
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
396
|
+
hasSetpoint
|
|
397
|
+
.setpoint=${0}
|
|
398
|
+
.value=${10}
|
|
399
|
+
tag="HDG"
|
|
400
|
+
unit="/min"
|
|
401
|
+
hasSrc
|
|
402
|
+
src="GPS"
|
|
403
|
+
.maxDigits=${3}
|
|
404
|
+
></obc-instrument-field>
|
|
405
|
+
`,
|
|
406
|
+
modern: html`
|
|
407
|
+
<obc-readout
|
|
408
|
+
.size=${ReadoutSize.large}
|
|
409
|
+
.priority=${ReadoutPriority.enhanced}
|
|
410
|
+
hasSetpoint
|
|
411
|
+
.setpoint=${0}
|
|
412
|
+
.value=${10}
|
|
413
|
+
label="HDG"
|
|
414
|
+
unit="/min"
|
|
415
|
+
src="GPS"
|
|
416
|
+
.maxDigits=${3}
|
|
417
|
+
></obc-readout>
|
|
418
|
+
`,
|
|
419
|
+
notes: html`
|
|
420
|
+
<p>
|
|
421
|
+
<code>maxDigits: 3</code> reserves three digit widths on both sides.
|
|
422
|
+
Legacy renders the unfilled positions as transparent hint zeros;
|
|
423
|
+
<code>obc-readout-block</code> reserves them through
|
|
424
|
+
<code>obc-textbox</code>'s <code>length</code> slot instead. Same
|
|
425
|
+
result, no layout shift.
|
|
426
|
+
</p>
|
|
427
|
+
<p>
|
|
428
|
+
There is no <code>hasSrc</code> boolean —
|
|
429
|
+
<code>obc-readout</code> derives it from a non-blank <code>src</code>.
|
|
430
|
+
Since 6.1 the vertical readout renders the source without a divider,
|
|
431
|
+
exactly like the legacy layout (the original comparison still drew
|
|
432
|
+
one).
|
|
433
|
+
</p>
|
|
434
|
+
`,
|
|
435
|
+
}),
|
|
67
436
|
};
|
|
68
437
|
|
|
69
438
|
export const EnhancedZeroPadding: Story = {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
439
|
+
render: () =>
|
|
440
|
+
renderComparison({
|
|
441
|
+
name: 'Enhanced Zero Padding',
|
|
442
|
+
verdict: Verdict.differs,
|
|
443
|
+
legacy: html`
|
|
444
|
+
<obc-instrument-field
|
|
445
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
446
|
+
hasSetpoint
|
|
447
|
+
.setpoint=${0}
|
|
448
|
+
.value=${10}
|
|
449
|
+
tag="HDG"
|
|
450
|
+
unit="/min"
|
|
451
|
+
hasSrc
|
|
452
|
+
src="GPS"
|
|
453
|
+
showZeroPadding
|
|
454
|
+
.maxDigits=${3}
|
|
455
|
+
></obc-instrument-field>
|
|
456
|
+
`,
|
|
457
|
+
modern: html`
|
|
458
|
+
<obc-readout
|
|
459
|
+
.size=${ReadoutSize.large}
|
|
460
|
+
.priority=${ReadoutPriority.enhanced}
|
|
461
|
+
hasSetpoint
|
|
462
|
+
.setpoint=${0}
|
|
463
|
+
.value=${10}
|
|
464
|
+
label="HDG"
|
|
465
|
+
unit="/min"
|
|
466
|
+
src="GPS"
|
|
467
|
+
.maxDigits=${3}
|
|
468
|
+
.valueOptions=${{hintedZeros: true}}
|
|
469
|
+
></obc-readout>
|
|
470
|
+
`,
|
|
471
|
+
notes: html`
|
|
472
|
+
<p>
|
|
473
|
+
<code>showZeroPadding</code> maps to
|
|
474
|
+
<code>valueOptions.hintedZeros</code>, and both render
|
|
475
|
+
<code>010</code>. The hint styling is the 6.1-reviewed one: the
|
|
476
|
+
readout paints hints <code>--element-disabled-color</code> at regular
|
|
477
|
+
weight (legacy uses the darker <code>--border-outline-color</code>).
|
|
478
|
+
</p>
|
|
479
|
+
<p>
|
|
480
|
+
More importantly,
|
|
481
|
+
<strong><code>maxDigits</code> does not mean the same thing</strong>.
|
|
482
|
+
Legacy subtracts the whole formatted string — decimal point and
|
|
483
|
+
fraction digits included — from <code>maxDigits</code>, while
|
|
484
|
+
<code>obc-readout-block</code> counts integer digits only. The two
|
|
485
|
+
agree here because <code>fractionDigits</code> is 0; see
|
|
486
|
+
<em>Max Digits With Decimals</em> below for the divergence and the
|
|
487
|
+
translation rule.
|
|
488
|
+
</p>
|
|
489
|
+
`,
|
|
490
|
+
}),
|
|
81
491
|
};
|
|
82
492
|
|
|
83
493
|
export const NoSetpoint: Story = {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
494
|
+
render: () =>
|
|
495
|
+
renderComparison({
|
|
496
|
+
name: 'No Setpoint',
|
|
497
|
+
verdict: Verdict.match,
|
|
498
|
+
legacy: html`
|
|
499
|
+
<obc-instrument-field
|
|
500
|
+
.value=${10}
|
|
501
|
+
tag="HDG"
|
|
502
|
+
unit="/min"
|
|
503
|
+
></obc-instrument-field>
|
|
504
|
+
`,
|
|
505
|
+
modern: html`
|
|
506
|
+
<obc-readout
|
|
507
|
+
.size=${ReadoutSize.small}
|
|
508
|
+
.priority=${ReadoutPriority.enhanced}
|
|
509
|
+
.value=${10}
|
|
510
|
+
label="HDG"
|
|
511
|
+
unit="/min"
|
|
512
|
+
></obc-readout>
|
|
513
|
+
`,
|
|
514
|
+
notes: html`
|
|
515
|
+
<p>
|
|
516
|
+
Dropping <code>hasSetpoint</code> removes the setpoint block on both
|
|
517
|
+
sides; nothing else changes.
|
|
518
|
+
</p>
|
|
519
|
+
`,
|
|
520
|
+
}),
|
|
90
521
|
};
|
|
522
|
+
|
|
91
523
|
export const WithDecimals: Story = {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
524
|
+
render: () =>
|
|
525
|
+
renderComparison({
|
|
526
|
+
name: 'With Decimals',
|
|
527
|
+
verdict: Verdict.match,
|
|
528
|
+
legacy: html`
|
|
529
|
+
<obc-instrument-field
|
|
530
|
+
.value=${1.3}
|
|
531
|
+
.fractionDigits=${2}
|
|
532
|
+
tag="Offset"
|
|
533
|
+
unit="m"
|
|
534
|
+
></obc-instrument-field>
|
|
535
|
+
`,
|
|
536
|
+
modern: html`
|
|
537
|
+
<obc-readout
|
|
538
|
+
.size=${ReadoutSize.small}
|
|
539
|
+
.priority=${ReadoutPriority.enhanced}
|
|
540
|
+
.value=${1.3}
|
|
541
|
+
.fractionDigits=${2}
|
|
542
|
+
label="Offset"
|
|
543
|
+
unit="m"
|
|
544
|
+
></obc-readout>
|
|
545
|
+
`,
|
|
546
|
+
notes: html`
|
|
547
|
+
<p>
|
|
548
|
+
<code>fractionDigits: 2</code> formats identically
|
|
549
|
+
(<code>1.30</code>). Neither side pads: the legacy default
|
|
550
|
+
<code>maxDigits</code> of 1 is already shorter than the four-character
|
|
551
|
+
result, and <code>obc-readout</code> defaults
|
|
552
|
+
<code>maxDigits</code> to 0.
|
|
553
|
+
</p>
|
|
554
|
+
`,
|
|
555
|
+
}),
|
|
99
556
|
};
|
|
100
557
|
|
|
101
558
|
export const NeutralColor: Story = {
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
559
|
+
render: () =>
|
|
560
|
+
renderComparison({
|
|
561
|
+
name: 'Neutral Color',
|
|
562
|
+
verdict: Verdict.differs,
|
|
563
|
+
legacy: html`
|
|
564
|
+
<obc-instrument-field
|
|
565
|
+
neutralColor
|
|
566
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
567
|
+
.value=${63}
|
|
568
|
+
tag="Speed"
|
|
569
|
+
unit="KN"
|
|
570
|
+
></obc-instrument-field>
|
|
571
|
+
`,
|
|
572
|
+
modern: html`
|
|
573
|
+
<obc-readout
|
|
574
|
+
.size=${ReadoutSize.large}
|
|
575
|
+
.priority=${ReadoutPriority.regular}
|
|
576
|
+
.value=${63}
|
|
577
|
+
label="Speed"
|
|
578
|
+
unit="KN"
|
|
579
|
+
></obc-readout>
|
|
580
|
+
`,
|
|
581
|
+
notes: html`
|
|
582
|
+
<p>
|
|
583
|
+
<code>neutralColor</code> maps to <code>priority="regular"</code> and
|
|
584
|
+
the value colour matches exactly
|
|
585
|
+
(<code>--element-neutral-color</code>).
|
|
586
|
+
</p>
|
|
587
|
+
<p>
|
|
588
|
+
The difference is invisible here because this story has no setpoint.
|
|
589
|
+
When one is present the two disagree: legacy hardcodes the setpoint to
|
|
590
|
+
<code>--instrument-enhanced-secondary-color</code>, so
|
|
591
|
+
<code>neutralColor</code> yields a grey value beside a blue setpoint.
|
|
592
|
+
<code>obc-readout</code> refuses that combination by design — value
|
|
593
|
+
and setpoint are always both neutral or both enhanced. That is a
|
|
594
|
+
deliberate design correction, not an oversight, but it is a visual
|
|
595
|
+
change for anyone relying on it.
|
|
596
|
+
</p>
|
|
597
|
+
`,
|
|
598
|
+
}),
|
|
110
599
|
};
|
|
111
600
|
|
|
112
601
|
export const Horizontal: Story = {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
602
|
+
render: () =>
|
|
603
|
+
renderComparison({
|
|
604
|
+
name: 'Horizontal',
|
|
605
|
+
verdict: Verdict.match,
|
|
606
|
+
legacy: html`
|
|
607
|
+
<obc-instrument-field
|
|
608
|
+
horizontal
|
|
609
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
610
|
+
hasSetpoint
|
|
611
|
+
.setpoint=${123}
|
|
612
|
+
.value=${63}
|
|
613
|
+
tag="Speed"
|
|
614
|
+
unit="KN"
|
|
615
|
+
></obc-instrument-field>
|
|
616
|
+
`,
|
|
617
|
+
modern: html`
|
|
618
|
+
<obc-readout
|
|
619
|
+
.direction=${ReadoutDirection.horizontal}
|
|
620
|
+
.size=${ReadoutSize.large}
|
|
621
|
+
.priority=${ReadoutPriority.enhanced}
|
|
622
|
+
hasSetpoint
|
|
623
|
+
.setpoint=${123}
|
|
624
|
+
.value=${63}
|
|
625
|
+
.setpointOptions=${{
|
|
626
|
+
interaction: ReadoutSetpointInteraction.equalSize,
|
|
627
|
+
}}
|
|
628
|
+
label="Speed"
|
|
629
|
+
unit="KN"
|
|
630
|
+
></obc-readout>
|
|
631
|
+
`,
|
|
632
|
+
notes: html`
|
|
633
|
+
<p>
|
|
634
|
+
<code>horizontal</code> maps to <code>direction="horizontal"</code>,
|
|
635
|
+
and both stack the label over the unit beside the value.
|
|
636
|
+
<code>horizontal</code> + <code>enhanced</code> is the legacy layout
|
|
637
|
+
that renders the setpoint at the full 34px value size, and since 6.1
|
|
638
|
+
<code>setpointOptions.interaction="equal-size"</code> reproduces it —
|
|
639
|
+
<code>123</code> and <code>63</code> read as equals on both sides.
|
|
640
|
+
This closed the biggest sizing gap of the original comparison.
|
|
641
|
+
</p>
|
|
642
|
+
<p>
|
|
643
|
+
<code>obc-readout</code> draws no divider between the setpoint and the
|
|
644
|
+
value where the legacy component has one. The 6.1 review settled this
|
|
645
|
+
deliberately: "setpoint dividers are removed" — the only divider a
|
|
646
|
+
horizontal readout emits is the one before the source. A design
|
|
647
|
+
decision, not an API gap.
|
|
648
|
+
</p>
|
|
649
|
+
`,
|
|
650
|
+
}),
|
|
122
651
|
};
|
|
123
652
|
|
|
124
653
|
export const HorizontalWithSrc: Story = {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
654
|
+
render: () =>
|
|
655
|
+
renderComparison({
|
|
656
|
+
name: 'Horizontal With Src',
|
|
657
|
+
verdict: Verdict.match,
|
|
658
|
+
legacy: html`
|
|
659
|
+
<obc-instrument-field
|
|
660
|
+
horizontal
|
|
661
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
662
|
+
hasSetpoint
|
|
663
|
+
hasSrc
|
|
664
|
+
.setpoint=${123}
|
|
665
|
+
.value=${63}
|
|
666
|
+
tag="Speed"
|
|
667
|
+
unit="KN"
|
|
668
|
+
src="GPS"
|
|
669
|
+
></obc-instrument-field>
|
|
670
|
+
`,
|
|
671
|
+
modern: html`
|
|
672
|
+
<obc-readout
|
|
673
|
+
.direction=${ReadoutDirection.horizontal}
|
|
674
|
+
.size=${ReadoutSize.large}
|
|
675
|
+
.priority=${ReadoutPriority.enhanced}
|
|
676
|
+
hasSetpoint
|
|
677
|
+
.setpoint=${123}
|
|
678
|
+
.value=${63}
|
|
679
|
+
.setpointOptions=${{
|
|
680
|
+
interaction: ReadoutSetpointInteraction.equalSize,
|
|
681
|
+
}}
|
|
682
|
+
label="Speed"
|
|
683
|
+
unit="KN"
|
|
684
|
+
src="GPS"
|
|
685
|
+
></obc-readout>
|
|
686
|
+
`,
|
|
687
|
+
notes: html`
|
|
688
|
+
<p>
|
|
689
|
+
Adding the source brings a divider on both sides —
|
|
690
|
+
<code>obc-readout</code> draws one automatically before the source
|
|
691
|
+
segment ("Source-divider are there", 6.1 review), so the legacy
|
|
692
|
+
<code>src-divider</code> needs no counterpart.
|
|
693
|
+
</p>
|
|
694
|
+
<p>
|
|
695
|
+
As in <em>Horizontal</em>: <code>equal-size</code> restores the legacy
|
|
696
|
+
sizing, and the missing setpoint-to-value divider is the 6.1 design.
|
|
697
|
+
</p>
|
|
698
|
+
`,
|
|
699
|
+
}),
|
|
136
700
|
};
|
|
137
701
|
|
|
138
702
|
export const VerticalCenter: Story = {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
703
|
+
render: () =>
|
|
704
|
+
renderComparison({
|
|
705
|
+
name: 'Vertical Center',
|
|
706
|
+
verdict: Verdict.differs,
|
|
707
|
+
legacy: html`
|
|
708
|
+
<obc-instrument-field
|
|
709
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
710
|
+
center
|
|
711
|
+
.value=${1}
|
|
712
|
+
.maxDigits=${3}
|
|
713
|
+
showZeroPadding
|
|
714
|
+
neutralColor
|
|
715
|
+
tag="Speed"
|
|
716
|
+
unit="kn"
|
|
717
|
+
></obc-instrument-field>
|
|
718
|
+
`,
|
|
719
|
+
modern: html`
|
|
720
|
+
<obc-readout
|
|
721
|
+
.size=${ReadoutSize.large}
|
|
722
|
+
.priority=${ReadoutPriority.regular}
|
|
723
|
+
.alignment=${ReadoutAlignment.center}
|
|
724
|
+
.value=${1}
|
|
725
|
+
.maxDigits=${3}
|
|
726
|
+
.valueOptions=${{hintedZeros: true}}
|
|
727
|
+
label="Speed"
|
|
728
|
+
unit="kn"
|
|
729
|
+
></obc-readout>
|
|
730
|
+
`,
|
|
731
|
+
notes: html`
|
|
732
|
+
<p>
|
|
733
|
+
<code>center</code> maps to <code>alignment="center"</code>, but the
|
|
734
|
+
two centre different things. Legacy <code>center</code> applies
|
|
735
|
+
<code>justify-content: center</code> to the label row only and leaves
|
|
736
|
+
the value right-aligned; <code>alignment="center"</code> centres the
|
|
737
|
+
value cluster, the meta zone and the source together. The readout
|
|
738
|
+
result is the more consistent of the two.
|
|
739
|
+
</p>
|
|
740
|
+
<p>
|
|
741
|
+
Both render identically <em>here</em> because each component is
|
|
742
|
+
<code>fit-content</code> and the widest child is the value, so there
|
|
743
|
+
is no slack to centre within. The difference only appears once the
|
|
744
|
+
component is given more width than its content needs.
|
|
745
|
+
</p>
|
|
746
|
+
<p>
|
|
747
|
+
<code>alignment</code> is documented
|
|
748
|
+
<code>@availableWhen direction==vertical && stacking==stacked</code>,
|
|
749
|
+
yet the CSS applies it to any vertical readout — including the
|
|
750
|
+
<code>inline</code> stacking used here. The annotation is narrower
|
|
751
|
+
than the behaviour, so props tooling may hide a control that works.
|
|
752
|
+
</p>
|
|
753
|
+
`,
|
|
754
|
+
}),
|
|
149
755
|
};
|
|
150
756
|
|
|
151
757
|
export const HorizontalRegular: Story = {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
758
|
+
render: () =>
|
|
759
|
+
renderComparison({
|
|
760
|
+
name: 'Horizontal Regular',
|
|
761
|
+
verdict: Verdict.gap,
|
|
762
|
+
legacy: html`
|
|
763
|
+
<obc-instrument-field
|
|
764
|
+
horizontal
|
|
765
|
+
.size=${InstrumentFieldSize.regular}
|
|
766
|
+
hasSetpoint
|
|
767
|
+
hasSrc
|
|
768
|
+
.setpoint=${123}
|
|
769
|
+
.value=${63}
|
|
770
|
+
tag="Speed"
|
|
771
|
+
unit="KN"
|
|
772
|
+
src="GPS"
|
|
773
|
+
></obc-instrument-field>
|
|
774
|
+
`,
|
|
775
|
+
modern: html`
|
|
776
|
+
<obc-readout
|
|
777
|
+
.direction=${ReadoutDirection.horizontal}
|
|
778
|
+
.priority=${ReadoutPriority.enhanced}
|
|
779
|
+
hasSetpoint
|
|
780
|
+
.setpoint=${123}
|
|
781
|
+
.value=${63}
|
|
782
|
+
label="Speed"
|
|
783
|
+
unit="KN"
|
|
784
|
+
src="GPS"
|
|
785
|
+
></obc-readout>
|
|
786
|
+
`,
|
|
787
|
+
modernAlt: {
|
|
788
|
+
tag: '<obc-readout-list-item> (label-first alternative)',
|
|
789
|
+
content: html`
|
|
790
|
+
<obc-readout-list-item
|
|
791
|
+
.size=${ReadoutListItemSize.small}
|
|
792
|
+
.priority=${ReadoutListItemPriority.enhanced}
|
|
793
|
+
.stacking=${ReadoutListItemStacking.leadingUnit}
|
|
794
|
+
hasSetpoint
|
|
795
|
+
.setpoint=${123}
|
|
796
|
+
.value=${63}
|
|
797
|
+
label="Speed"
|
|
798
|
+
unit="KN"
|
|
799
|
+
src="GPS"
|
|
800
|
+
></obc-readout-list-item>
|
|
801
|
+
`,
|
|
802
|
+
},
|
|
803
|
+
notes: html`
|
|
804
|
+
<p>
|
|
805
|
+
This is the one arrangement <code>obc-readout</code> cannot produce.
|
|
806
|
+
At <code>horizontal</code> + <code>regular</code> the legacy component
|
|
807
|
+
moves the tag to the <strong>front</strong> of the row (tag │ setpoint
|
|
808
|
+
│ value │ unit │ src). <code>obc-readout</code> always emits the meta
|
|
809
|
+
zone after the value, in both directions.
|
|
810
|
+
</p>
|
|
811
|
+
<p>
|
|
812
|
+
The 6.1 review confirmed this stays a non-goal: in the new structure
|
|
813
|
+
the horizontal readout carries the large value size only, and the
|
|
814
|
+
label-first shape is <code>obc-readout-list-item</code>'s job —
|
|
815
|
+
<code>stacking="leading-unit"</code>, shown underneath. It is a
|
|
816
|
+
different component with a row-oriented API (label left, value right),
|
|
817
|
+
so it is a re-layout rather than a drop-in swap.
|
|
818
|
+
</p>
|
|
819
|
+
`,
|
|
820
|
+
}),
|
|
163
821
|
};
|
|
164
822
|
|
|
165
823
|
export const LabelOnly: Story = {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
824
|
+
render: () =>
|
|
825
|
+
renderComparison({
|
|
826
|
+
name: 'Label Only',
|
|
827
|
+
verdict: Verdict.match,
|
|
828
|
+
legacy: html`
|
|
829
|
+
<obc-instrument-field
|
|
830
|
+
labelOnly
|
|
831
|
+
horizontal
|
|
832
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
833
|
+
tag="Speed"
|
|
834
|
+
unit="KN"
|
|
835
|
+
></obc-instrument-field>
|
|
836
|
+
`,
|
|
837
|
+
modern: html`
|
|
838
|
+
<obc-readout
|
|
839
|
+
.hasValue=${false}
|
|
840
|
+
.direction=${ReadoutDirection.horizontal}
|
|
841
|
+
.size=${ReadoutSize.large}
|
|
842
|
+
label="Speed"
|
|
843
|
+
unit="KN"
|
|
844
|
+
></obc-readout>
|
|
845
|
+
`,
|
|
846
|
+
notes: html`
|
|
847
|
+
<p>
|
|
848
|
+
<code>labelOnly</code> maps to <code>hasValue={false}</code>. Both
|
|
849
|
+
drop the value and keep the label stacked over the unit. It must be
|
|
850
|
+
set as a property (<code>.hasValue=\${false}</code>): the field is
|
|
851
|
+
declared <code>attribute: false</code> because its default is
|
|
852
|
+
<code>true</code>.
|
|
853
|
+
</p>
|
|
854
|
+
<p>
|
|
855
|
+
For a value that is merely missing right now, keep
|
|
856
|
+
<code>hasValue</code> and pass <code>value={null}</code> instead — the
|
|
857
|
+
dash holds the block at full size, so the layout does not jump when
|
|
858
|
+
data arrives.
|
|
859
|
+
</p>
|
|
860
|
+
`,
|
|
861
|
+
}),
|
|
173
862
|
};
|
|
174
863
|
|
|
175
864
|
export const AutoHideSetpoint: Story = {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
865
|
+
render: () =>
|
|
866
|
+
renderComparison({
|
|
867
|
+
name: 'Auto Hide Setpoint',
|
|
868
|
+
verdict: Verdict.differs,
|
|
869
|
+
legacy: html`
|
|
870
|
+
<obc-instrument-field
|
|
871
|
+
autoHideSetpoint
|
|
872
|
+
.autoHideDeadband=${1}
|
|
873
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
874
|
+
hasSetpoint
|
|
875
|
+
.value=${10}
|
|
876
|
+
.setpoint=${10}
|
|
877
|
+
tag="HDG"
|
|
878
|
+
unit="/min"
|
|
879
|
+
hasSrc
|
|
880
|
+
src="GPS"
|
|
881
|
+
></obc-instrument-field>
|
|
882
|
+
`,
|
|
883
|
+
modern: html`
|
|
884
|
+
<obc-readout
|
|
885
|
+
.size=${ReadoutSize.large}
|
|
886
|
+
.priority=${ReadoutPriority.enhanced}
|
|
887
|
+
hasSetpoint
|
|
888
|
+
.value=${10}
|
|
889
|
+
.setpoint=${10}
|
|
890
|
+
.setpointOptions=${{
|
|
891
|
+
interaction: ReadoutSetpointInteraction.popUp,
|
|
892
|
+
}}
|
|
893
|
+
label="HDG"
|
|
894
|
+
unit="/min"
|
|
895
|
+
src="GPS"
|
|
896
|
+
></obc-readout>
|
|
897
|
+
`,
|
|
898
|
+
notes: html`
|
|
899
|
+
<p>
|
|
900
|
+
<code>autoHideSetpoint</code> maps to
|
|
901
|
+
<code>setpointOptions.interaction="pop-up"</code>. Both hide the
|
|
902
|
+
setpoint here and both keep its space, so nothing shifts. The 6.1
|
|
903
|
+
review confirmed this behaviour (value stays, setpoint fades); if the
|
|
904
|
+
collapsed reading should still carry the in-control arrow, slot an
|
|
905
|
+
<code>obi-input-right</code> into <code>value-icon</code> — see the
|
|
906
|
+
Readout <em>SetpointPopUpWithValueArrow</em> story.
|
|
907
|
+
</p>
|
|
908
|
+
<p>
|
|
909
|
+
The trigger differs. <code>autoHideDeadband</code> is a tolerance in
|
|
910
|
+
the value's own units, while pop-up compares the
|
|
911
|
+
<strong>rendered</strong> strings via
|
|
912
|
+
<code>isDisplayedAtSetpoint</code>. A deadband is therefore only
|
|
913
|
+
expressible through <code>fractionDigits</code> — at
|
|
914
|
+
<code>fractionDigits: 0</code> the readout hides within ±0.5. See
|
|
915
|
+
<em>Auto Hide Deadband</em> below for the case where they disagree.
|
|
916
|
+
</p>
|
|
917
|
+
`,
|
|
918
|
+
}),
|
|
188
919
|
};
|
|
189
920
|
|
|
190
921
|
export const Off: Story = {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
922
|
+
render: () =>
|
|
923
|
+
renderComparison({
|
|
924
|
+
name: 'Off',
|
|
925
|
+
verdict: Verdict.gap,
|
|
926
|
+
legacy: html`
|
|
927
|
+
<obc-instrument-field
|
|
928
|
+
off
|
|
929
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
930
|
+
></obc-instrument-field>
|
|
931
|
+
`,
|
|
932
|
+
modern: html`
|
|
933
|
+
<obc-readout
|
|
934
|
+
off
|
|
935
|
+
.size=${ReadoutSize.large}
|
|
936
|
+
.priority=${ReadoutPriority.enhanced}
|
|
937
|
+
></obc-readout>
|
|
938
|
+
`,
|
|
939
|
+
notes: html`
|
|
940
|
+
<p>
|
|
941
|
+
Both substitute the value with <code>OFF</code>, and the readout adds
|
|
942
|
+
<code>offText</code> to change the word. But the legacy
|
|
943
|
+
<code>off</code> state also dims the value, label and source to
|
|
944
|
+
<code>--element-inactive-color</code>, and nothing in the readout
|
|
945
|
+
stack does: <code>off</code> never reaches the root class list, and no
|
|
946
|
+
rule in <code>readout.css</code> or
|
|
947
|
+
<code>readout-block.css</code> styles it. The text stays at full value
|
|
948
|
+
colour — enhanced blue here rather than inactive grey. Unchanged by
|
|
949
|
+
the 6.1 review, which did not touch the off state.
|
|
950
|
+
</p>
|
|
951
|
+
<p>
|
|
952
|
+
The legacy <code>off-value</code> slot has no counterpart either;
|
|
953
|
+
<code>offText</code> takes a plain string only.
|
|
954
|
+
</p>
|
|
955
|
+
`,
|
|
956
|
+
}),
|
|
195
957
|
};
|
|
196
958
|
|
|
197
959
|
export const AlignMultiple: Story = {
|
|
198
|
-
render: () =>
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
960
|
+
render: () =>
|
|
961
|
+
renderComparison({
|
|
962
|
+
name: 'Align Multiple',
|
|
963
|
+
verdict: Verdict.match,
|
|
964
|
+
legacy: html`
|
|
965
|
+
<div
|
|
966
|
+
style="display: flex; flex-direction: column; align-items: end;
|
|
967
|
+
--obc-instrument-field-source-width: 60px;
|
|
968
|
+
--obc-instrument-field-tag-width: 5ch;"
|
|
969
|
+
>
|
|
970
|
+
<obc-instrument-field
|
|
971
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
972
|
+
horizontal
|
|
973
|
+
hasSetpoint
|
|
974
|
+
.setpoint=${360}
|
|
975
|
+
.value=${3}
|
|
976
|
+
.maxDigits=${3}
|
|
977
|
+
tag="HDG"
|
|
978
|
+
unit="DEG"
|
|
979
|
+
src="GPS"
|
|
980
|
+
hasSrc
|
|
981
|
+
></obc-instrument-field>
|
|
982
|
+
<obc-instrument-field
|
|
983
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
984
|
+
horizontal
|
|
985
|
+
hasSetpoint
|
|
986
|
+
.setpoint=${100}
|
|
987
|
+
.value=${100}
|
|
988
|
+
.maxDigits=${3}
|
|
989
|
+
tag="Depth"
|
|
990
|
+
unit="M"
|
|
991
|
+
hasSrc
|
|
992
|
+
src="GPS"
|
|
993
|
+
></obc-instrument-field>
|
|
994
|
+
<obc-instrument-field
|
|
995
|
+
.size=${InstrumentFieldSize.enhanced}
|
|
996
|
+
horizontal
|
|
997
|
+
hasSetpoint
|
|
998
|
+
.setpoint=${10}
|
|
999
|
+
.value=${9}
|
|
1000
|
+
.maxDigits=${3}
|
|
1001
|
+
tag="STW"
|
|
1002
|
+
unit="KN"
|
|
1003
|
+
hasSrc
|
|
1004
|
+
src="GYRO 2"
|
|
1005
|
+
></obc-instrument-field>
|
|
1006
|
+
</div>
|
|
1007
|
+
`,
|
|
1008
|
+
modern: html`
|
|
1009
|
+
<div style="display: flex; flex-direction: column; align-items: end;">
|
|
1010
|
+
<obc-readout
|
|
1011
|
+
.size=${ReadoutSize.large}
|
|
1012
|
+
.priority=${ReadoutPriority.enhanced}
|
|
1013
|
+
.direction=${ReadoutDirection.horizontal}
|
|
1014
|
+
hasSetpoint
|
|
1015
|
+
.setpointOptions=${{
|
|
1016
|
+
interaction: ReadoutSetpointInteraction.equalSize,
|
|
1017
|
+
}}
|
|
1018
|
+
.setpoint=${360}
|
|
1019
|
+
.value=${3}
|
|
1020
|
+
.maxDigits=${3}
|
|
1021
|
+
label="HDG"
|
|
1022
|
+
unit="DEG"
|
|
1023
|
+
src="GPS"
|
|
1024
|
+
.labelOptions=${{spaceReserver: 'Depth'}}
|
|
1025
|
+
.unitOptions=${{spaceReserver: 'DEG'}}
|
|
1026
|
+
.srcOptions=${{spaceReserver: 'GYRO 2'}}
|
|
1027
|
+
></obc-readout>
|
|
1028
|
+
<obc-readout
|
|
1029
|
+
.size=${ReadoutSize.large}
|
|
1030
|
+
.priority=${ReadoutPriority.enhanced}
|
|
1031
|
+
.direction=${ReadoutDirection.horizontal}
|
|
1032
|
+
hasSetpoint
|
|
1033
|
+
.setpointOptions=${{
|
|
1034
|
+
interaction: ReadoutSetpointInteraction.equalSize,
|
|
1035
|
+
}}
|
|
1036
|
+
.setpoint=${100}
|
|
1037
|
+
.value=${100}
|
|
1038
|
+
.maxDigits=${3}
|
|
1039
|
+
label="Depth"
|
|
1040
|
+
unit="M"
|
|
1041
|
+
src="GPS"
|
|
1042
|
+
.labelOptions=${{spaceReserver: 'Depth'}}
|
|
1043
|
+
.unitOptions=${{spaceReserver: 'DEG'}}
|
|
1044
|
+
.srcOptions=${{spaceReserver: 'GYRO 2'}}
|
|
1045
|
+
></obc-readout>
|
|
1046
|
+
<obc-readout
|
|
1047
|
+
.size=${ReadoutSize.large}
|
|
1048
|
+
.priority=${ReadoutPriority.enhanced}
|
|
1049
|
+
.direction=${ReadoutDirection.horizontal}
|
|
1050
|
+
hasSetpoint
|
|
1051
|
+
.setpointOptions=${{
|
|
1052
|
+
interaction: ReadoutSetpointInteraction.equalSize,
|
|
1053
|
+
}}
|
|
1054
|
+
.setpoint=${10}
|
|
1055
|
+
.value=${9}
|
|
1056
|
+
.maxDigits=${3}
|
|
1057
|
+
label="STW"
|
|
1058
|
+
unit="KN"
|
|
1059
|
+
src="GYRO 2"
|
|
1060
|
+
.labelOptions=${{spaceReserver: 'Depth'}}
|
|
1061
|
+
.unitOptions=${{spaceReserver: 'DEG'}}
|
|
1062
|
+
.srcOptions=${{spaceReserver: 'GYRO 2'}}
|
|
1063
|
+
></obc-readout>
|
|
1064
|
+
</div>
|
|
1065
|
+
`,
|
|
1066
|
+
notes: html`
|
|
1067
|
+
<p>
|
|
1068
|
+
Legacy aligns a column of fields with two CSS variables:
|
|
1069
|
+
<code>--obc-instrument-field-tag-width</code> and
|
|
1070
|
+
<code>--obc-instrument-field-source-width</code>.
|
|
1071
|
+
</p>
|
|
1072
|
+
<p>
|
|
1073
|
+
<code>obc-readout</code> replaces them with per-block reservers, all
|
|
1074
|
+
set to the longest expected string on every row:
|
|
1075
|
+
<code>labelOptions.spaceReserver</code> (new in 6.1 — this closed the
|
|
1076
|
+
"no label reserver" gap that made the original comparison
|
|
1077
|
+
unreachable), <code>unitOptions.spaceReserver</code> and
|
|
1078
|
+
<code>srcOptions.spaceReserver</code>. With all three set, every
|
|
1079
|
+
column lines up and the setpoint edge stays square.
|
|
1080
|
+
</p>
|
|
1081
|
+
<p>
|
|
1082
|
+
For dense rows prefer <code>obc-readout-list</code> +
|
|
1083
|
+
<code>obc-readout-list-item</code>, which compute these reservers
|
|
1084
|
+
across rows automatically.
|
|
1085
|
+
</p>
|
|
1086
|
+
`,
|
|
1087
|
+
}),
|
|
1088
|
+
};
|
|
1089
|
+
|
|
1090
|
+
// ---------------------------------------------------------------------------
|
|
1091
|
+
// Edge cases the original stories never exercised. The pairs above can look
|
|
1092
|
+
// identical while the underlying semantics differ; these two stories pin the
|
|
1093
|
+
// divergence down so migrating consumers are not surprised by it.
|
|
1094
|
+
// ---------------------------------------------------------------------------
|
|
1095
|
+
|
|
1096
|
+
export const MaxDigitsWithDecimals: Story = {
|
|
1097
|
+
render: () =>
|
|
1098
|
+
renderComparison({
|
|
1099
|
+
name: 'Max Digits With Decimals (edge case)',
|
|
1100
|
+
verdict: Verdict.differs,
|
|
1101
|
+
legacy: html`
|
|
206
1102
|
<obc-instrument-field
|
|
207
1103
|
.size=${InstrumentFieldSize.enhanced}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
.
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
unit="DEG"
|
|
215
|
-
src="GPS"
|
|
216
|
-
hasSrc
|
|
1104
|
+
.value=${1.5}
|
|
1105
|
+
.fractionDigits=${1}
|
|
1106
|
+
showZeroPadding
|
|
1107
|
+
.maxDigits=${4}
|
|
1108
|
+
tag="Offset"
|
|
1109
|
+
unit="m"
|
|
217
1110
|
></obc-instrument-field>
|
|
1111
|
+
`,
|
|
1112
|
+
modern: html`
|
|
1113
|
+
<obc-readout
|
|
1114
|
+
.size=${ReadoutSize.large}
|
|
1115
|
+
.priority=${ReadoutPriority.enhanced}
|
|
1116
|
+
.value=${1.5}
|
|
1117
|
+
.fractionDigits=${1}
|
|
1118
|
+
.maxDigits=${4}
|
|
1119
|
+
.valueOptions=${{hintedZeros: true}}
|
|
1120
|
+
label="Offset"
|
|
1121
|
+
unit="m"
|
|
1122
|
+
></obc-readout>
|
|
1123
|
+
`,
|
|
1124
|
+
modernAlt: {
|
|
1125
|
+
tag: '<obc-readout> with translated maxDigits (4 − 1 − 1 = 2)',
|
|
1126
|
+
content: html`
|
|
1127
|
+
<obc-readout
|
|
1128
|
+
.size=${ReadoutSize.large}
|
|
1129
|
+
.priority=${ReadoutPriority.enhanced}
|
|
1130
|
+
.value=${1.5}
|
|
1131
|
+
.fractionDigits=${1}
|
|
1132
|
+
.maxDigits=${2}
|
|
1133
|
+
.valueOptions=${{hintedZeros: true}}
|
|
1134
|
+
label="Offset"
|
|
1135
|
+
unit="m"
|
|
1136
|
+
></obc-readout>
|
|
1137
|
+
`,
|
|
1138
|
+
},
|
|
1139
|
+
notes: html`
|
|
1140
|
+
<p>
|
|
1141
|
+
The <em>Enhanced Zero Padding</em> pair looks identical only because
|
|
1142
|
+
its <code>fractionDigits</code> is 0. This story shows the divergence:
|
|
1143
|
+
legacy counts the <strong>whole formatted string</strong> against
|
|
1144
|
+
<code>maxDigits</code> (decimal point and fraction included), so
|
|
1145
|
+
<code>1.5</code> at <code>maxDigits: 4</code> pads to
|
|
1146
|
+
<code>01.5</code>. <code>obc-readout-block</code> counts
|
|
1147
|
+
<strong>integer digits only</strong>, so the same
|
|
1148
|
+
<code>maxDigits: 4</code> pads to <code>0001.5</code> (top right).
|
|
1149
|
+
</p>
|
|
1150
|
+
<p>
|
|
1151
|
+
To keep the rendering, translate the knob:
|
|
1152
|
+
<code
|
|
1153
|
+
>maxDigits<sub>readout</sub> = maxDigits<sub>legacy</sub> −
|
|
1154
|
+
fractionDigits − 1</code
|
|
1155
|
+
>
|
|
1156
|
+
(the −1 is the decimal point) — here <code>4 − 1 − 1 = 2</code>, shown
|
|
1157
|
+
underneath rendering <code>01.5</code> like the legacy side. Copying
|
|
1158
|
+
the number across unchanged over-pads.
|
|
1159
|
+
</p>
|
|
1160
|
+
`,
|
|
1161
|
+
}),
|
|
1162
|
+
};
|
|
1163
|
+
|
|
1164
|
+
export const AutoHideDeadband: Story = {
|
|
1165
|
+
render: () =>
|
|
1166
|
+
renderComparison({
|
|
1167
|
+
name: 'Auto Hide Deadband (edge case)',
|
|
1168
|
+
verdict: Verdict.gap,
|
|
1169
|
+
legacy: html`
|
|
218
1170
|
<obc-instrument-field
|
|
1171
|
+
autoHideSetpoint
|
|
1172
|
+
.autoHideDeadband=${5}
|
|
219
1173
|
.size=${InstrumentFieldSize.enhanced}
|
|
220
|
-
horizontal
|
|
221
1174
|
hasSetpoint
|
|
222
|
-
.
|
|
223
|
-
.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
unit="M"
|
|
227
|
-
hasSrc
|
|
228
|
-
src="GPS"
|
|
1175
|
+
.value=${8}
|
|
1176
|
+
.setpoint=${10}
|
|
1177
|
+
tag="HDG"
|
|
1178
|
+
unit="/min"
|
|
229
1179
|
></obc-instrument-field>
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
1180
|
+
`,
|
|
1181
|
+
modern: html`
|
|
1182
|
+
<obc-readout
|
|
1183
|
+
.size=${ReadoutSize.large}
|
|
1184
|
+
.priority=${ReadoutPriority.enhanced}
|
|
233
1185
|
hasSetpoint
|
|
1186
|
+
.value=${8}
|
|
234
1187
|
.setpoint=${10}
|
|
235
|
-
.
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
1188
|
+
.setpointOptions=${{
|
|
1189
|
+
interaction: ReadoutSetpointInteraction.popUp,
|
|
1190
|
+
}}
|
|
1191
|
+
label="HDG"
|
|
1192
|
+
unit="/min"
|
|
1193
|
+
></obc-readout>
|
|
1194
|
+
`,
|
|
1195
|
+
notes: html`
|
|
1196
|
+
<p>
|
|
1197
|
+
The <em>Auto Hide Setpoint</em> pair agrees because its value sits
|
|
1198
|
+
exactly at the setpoint. This story shows where the semantics diverge:
|
|
1199
|
+
with <code>value: 8</code>, <code>setpoint: 10</code> and
|
|
1200
|
+
<code>autoHideDeadband: 5</code> the legacy side hides the setpoint
|
|
1201
|
+
(|10 − 8| ≤ 5) while the pop-up readout keeps it visible — the
|
|
1202
|
+
rendered strings <code>8</code> and <code>10</code> differ, and
|
|
1203
|
+
<code>isDisplayedAtSetpoint</code> compares nothing else.
|
|
1204
|
+
</p>
|
|
1205
|
+
<p>
|
|
1206
|
+
A deadband wider than the display rounding has
|
|
1207
|
+
<strong>no readout equivalent</strong>: pop-up's tolerance is exactly
|
|
1208
|
+
±half of the last displayed digit (<code>fractionDigits: 0</code> →
|
|
1209
|
+
±0.5). Consumers who relied on a wide deadband must either accept the
|
|
1210
|
+
tighter rendered-string rule or pre-round the value they feed the
|
|
1211
|
+
readout.
|
|
1212
|
+
</p>
|
|
1213
|
+
`,
|
|
1214
|
+
}),
|
|
245
1215
|
};
|