@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.
Files changed (38) hide show
  1. package/bundle/openbridge-webcomponents.bundle.js +12321 -11895
  2. package/bundle/openbridge-webcomponents.bundle.js.map +1 -1
  3. package/custom-elements.json +227 -3
  4. package/dist/building-blocks/readout-block/readout-block.css.js +53 -19
  5. package/dist/building-blocks/readout-block/readout-block.css.js.map +1 -1
  6. package/dist/building-blocks/readout-block/readout-block.d.ts +55 -0
  7. package/dist/building-blocks/readout-block/readout-block.d.ts.map +1 -1
  8. package/dist/building-blocks/readout-block/readout-block.js +57 -2
  9. package/dist/building-blocks/readout-block/readout-block.js.map +1 -1
  10. package/dist/navigation-instruments/readout/readout-shared.d.ts +23 -0
  11. package/dist/navigation-instruments/readout/readout-shared.d.ts.map +1 -1
  12. package/dist/navigation-instruments/readout/readout-shared.js +8 -0
  13. package/dist/navigation-instruments/readout/readout-shared.js.map +1 -1
  14. package/dist/navigation-instruments/readout/readout.css.js +138 -31
  15. package/dist/navigation-instruments/readout/readout.css.js.map +1 -1
  16. package/dist/navigation-instruments/readout/readout.d.ts +63 -3
  17. package/dist/navigation-instruments/readout/readout.d.ts.map +1 -1
  18. package/dist/navigation-instruments/readout/readout.js +127 -27
  19. package/dist/navigation-instruments/readout/readout.js.map +1 -1
  20. package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js +64 -1
  21. package/dist/navigation-instruments/readout-list-item/readout-list-item.css.js.map +1 -1
  22. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts +77 -2
  23. package/dist/navigation-instruments/readout-list-item/readout-list-item.d.ts.map +1 -1
  24. package/dist/navigation-instruments/readout-list-item/readout-list-item.js +100 -23
  25. package/dist/navigation-instruments/readout-list-item/readout-list-item.js.map +1 -1
  26. package/package.json +1 -1
  27. package/src/building-blocks/readout-block/readout-block.css +49 -20
  28. package/src/building-blocks/readout-block/readout-block.stories.ts +54 -0
  29. package/src/building-blocks/readout-block/readout-block.ts +101 -2
  30. package/src/navigation-instruments/instrument-field/instrument-field.stories.ts +1150 -180
  31. package/src/navigation-instruments/readout/readout-shared.spec.ts +50 -0
  32. package/src/navigation-instruments/readout/readout-shared.ts +33 -0
  33. package/src/navigation-instruments/readout/readout.css +124 -32
  34. package/src/navigation-instruments/readout/readout.stories.ts +536 -19
  35. package/src/navigation-instruments/readout/readout.ts +184 -31
  36. package/src/navigation-instruments/readout-list-item/readout-list-item.css +55 -1
  37. package/src/navigation-instruments/readout-list-item/readout-list-item.stories.ts +341 -0
  38. package/src/navigation-instruments/readout-list-item/readout-list-item.ts +169 -25
@@ -9,15 +9,20 @@ import {
9
9
  ReadoutListItemDataQuality,
10
10
  ReadoutListItemBorder,
11
11
  ReadoutListItemSetpointInteraction,
12
+ ReadoutAdviceCategory,
13
+ ReadoutSourceState,
12
14
  ObcTextboxFontWeight,
13
15
  type ReadoutListItemClickable,
14
16
  type ReadoutValueOptions,
15
17
  type ReadoutSetpointOptions,
16
18
  type ReadoutAdviceOptions,
19
+ type ReadoutLabelOptions,
17
20
  type ReadoutReserverOptions,
18
21
  type ReadoutSrcOptions,
19
22
  ReadoutValueType,
20
23
  } from './readout-list-item.js';
24
+ import {ObcTextboxSize} from '../../components/textbox/textbox.js';
25
+ import '../../icons/icon-input-right.js';
21
26
  import type {AlertFrameConfig} from '../../components/alert-frame/alert-frame.js';
22
27
  import {
23
28
  ObcAlertFrameMode,
@@ -61,6 +66,13 @@ type ReadoutListItemStoryArgs = {
61
66
  'options.value.hintedZeros': boolean;
62
67
  'options.setpoint.interaction': ReadoutListItemSetpointInteraction;
63
68
  'options.setpoint.touching': boolean;
69
+ 'options.advice.category': ReadoutAdviceCategory;
70
+ 'options.advice.active': boolean;
71
+ 'options.label.size': ObcTextboxSize | typeof NONE;
72
+ 'options.label.spaceReserver': string;
73
+ 'options.src.state': ReadoutSourceState;
74
+ 'options.src.deviation'?: number;
75
+ 'options.src.spaceReserver': string;
64
76
  'options.unit.spaceReserver': string;
65
77
  };
66
78
 
@@ -83,6 +95,7 @@ type StoryOptions = {
83
95
  value?: ReadoutValueOptions;
84
96
  setpoint?: ReadoutSetpointOptions;
85
97
  advice?: ReadoutAdviceOptions;
98
+ label?: ReadoutLabelOptions;
86
99
  unit?: ReadoutReserverOptions;
87
100
  src?: ReadoutSrcOptions;
88
101
  };
@@ -182,6 +195,7 @@ function renderItem(config: ReadoutItemConfig) {
182
195
  .valueOptions=${o.value}
183
196
  .setpointOptions=${o.setpoint}
184
197
  .adviceOptions=${o.advice}
198
+ .labelOptions=${o.label}
185
199
  .unitOptions=${o.unit}
186
200
  .srcOptions=${o.src}
187
201
  .showDebugOverlay=${config.showDebugOverlay ?? false}
@@ -272,6 +286,12 @@ const defaultArgs: ReadoutListItemStoryArgs = {
272
286
  'options.setpoint.interaction':
273
287
  ReadoutListItemSetpointInteraction.alwaysVisible,
274
288
  'options.setpoint.touching': false,
289
+ 'options.advice.category': ReadoutAdviceCategory.regular,
290
+ 'options.advice.active': false,
291
+ 'options.label.size': NONE,
292
+ 'options.label.spaceReserver': '',
293
+ 'options.src.state': ReadoutSourceState.regular,
294
+ 'options.src.spaceReserver': '',
275
295
  'options.unit.spaceReserver': '',
276
296
  };
277
297
 
@@ -301,6 +321,22 @@ function argsToOptions(args: ReadoutListItemStoryArgs): StoryOptions {
301
321
  interaction: args['options.setpoint.interaction'],
302
322
  touching: args['options.setpoint.touching'],
303
323
  },
324
+ advice: {
325
+ category: args['options.advice.category'],
326
+ active: args['options.advice.active'],
327
+ },
328
+ label: {
329
+ size:
330
+ args['options.label.size'] === NONE
331
+ ? undefined
332
+ : args['options.label.size'],
333
+ spaceReserver: args['options.label.spaceReserver'] || undefined,
334
+ },
335
+ src: {
336
+ state: args['options.src.state'],
337
+ deviation: args['options.src.deviation'],
338
+ spaceReserver: args['options.src.spaceReserver'] || undefined,
339
+ },
304
340
  unit: {spaceReserver: args['options.unit.spaceReserver'] || undefined},
305
341
  };
306
342
  }
@@ -442,6 +478,47 @@ const meta = {
442
478
  if: {arg: 'hasSetpoint', truthy: true},
443
479
  table: {category: 'Setpoint'},
444
480
  },
481
+ 'options.advice.category': {
482
+ name: 'Advice Category',
483
+ control: {type: 'select'},
484
+ options: Object.values(ReadoutAdviceCategory),
485
+ if: {arg: 'hasAdvice', truthy: true},
486
+ table: {category: 'Advice'},
487
+ },
488
+ 'options.advice.active': {
489
+ name: 'Advice Active (triggered)',
490
+ if: {arg: 'hasAdvice', truthy: true},
491
+ table: {category: 'Advice'},
492
+ },
493
+ 'options.label.size': {
494
+ name: 'Label Size',
495
+ description:
496
+ 'Dense list rows default to xs; the design defines xs and s.',
497
+ control: {type: 'select'},
498
+ options: [NONE, ObcTextboxSize.xs, ObcTextboxSize.s],
499
+ table: {category: 'Label'},
500
+ },
501
+ 'options.label.spaceReserver': {
502
+ name: 'Label Space Reserver',
503
+ control: {type: 'text'},
504
+ table: {category: 'Label'},
505
+ },
506
+ 'options.src.state': {
507
+ name: 'Source State',
508
+ control: {type: 'select'},
509
+ options: Object.values(ReadoutSourceState),
510
+ table: {category: 'Source'},
511
+ },
512
+ 'options.src.deviation': {
513
+ name: 'Source Deviation (Δ)',
514
+ control: {type: 'number'},
515
+ table: {category: 'Source'},
516
+ },
517
+ 'options.src.spaceReserver': {
518
+ name: 'Source Space Reserver',
519
+ control: {type: 'text'},
520
+ table: {category: 'Source'},
521
+ },
445
522
  'options.unit.spaceReserver': {
446
523
  name: 'Unit Space Reserver',
447
524
  control: {type: 'text'},
@@ -949,6 +1026,30 @@ export const SetpointPopUpAnimated: Story = {
949
1026
  tags: ['skip-test'],
950
1027
  };
951
1028
 
1029
+ export const SetpointAlwaysVisibleAnimated: Story = {
1030
+ ...animatedInteractionStory({
1031
+ name: 'Always-Visible (Animated)',
1032
+ interaction: ReadoutListItemSetpointInteraction.alwaysVisible,
1033
+ intro:
1034
+ 'Always-visible (the default, Figma "Primary secondary"): the setpoint stays at the secondary size in both states — nothing resizes or hides as the value reaches the setpoint (120); only the touch highlight shows during the sweep. Contrast with flip-flop / pop-up. Press Play, or use the buttons.',
1035
+ awayLabel: 'Away (124)',
1036
+ reachLabel: 'Reach setpoint (120)',
1037
+ }),
1038
+ tags: ['skip-test'],
1039
+ };
1040
+
1041
+ export const SetpointEqualSizeAnimated: Story = {
1042
+ ...animatedInteractionStory({
1043
+ name: 'Equal-Size (Animated)',
1044
+ interaction: ReadoutListItemSetpointInteraction.equalSize,
1045
+ intro:
1046
+ 'Equal-size (Figma 6.1 "Equal size"): value and setpoint share the primary size in both states — like always-visible, nothing resizes or hides as the value reaches the setpoint (120); only the touch highlight shows during the sweep. Press Play, or use the buttons.',
1047
+ awayLabel: 'Away (124)',
1048
+ reachLabel: 'Reach setpoint (120)',
1049
+ }),
1050
+ tags: ['skip-test'],
1051
+ };
1052
+
952
1053
  // Demo durations (s) for the synced azimuth-thruster flow below — the vessel
953
1054
  // response after "confirm": thrust catches up faster than the heavier angle.
954
1055
  const SYNC_THRUST_DURATION = 2;
@@ -1973,3 +2074,243 @@ export const ColumnAlignment: StoryObj<
1973
2074
  </div>
1974
2075
  `,
1975
2076
  };
2077
+
2078
+ /**
2079
+ * Figma 6.1 "Equal size": value and setpoint always share the primary size —
2080
+ * the fourth interaction beside primary-secondary (`always-visible`),
2081
+ * flip-flop and pop-up. Static in both states; only flip-flop / pop-up
2082
+ * resize or hide at runtime — see the `SetpointEqualSizeAnimated` story for
2083
+ * the in-motion contrast. `touching` keeps the setpoint at the primary size
2084
+ * (it only adds the SemiBold focus weight and marker highlight), and the
2085
+ * marker arrow follows the block's rendered size, so an equal-size setpoint
2086
+ * carries the full-size arrow. The sizing rule lives in
2087
+ * `readoutSetpointSize()` (`readout-shared.ts`, unit-tested), shared with
2088
+ * `obc-readout`.
2089
+ */
2090
+ export const SetpointEqualSize: Story = {
2091
+ render: () =>
2092
+ renderShowcase([
2093
+ {
2094
+ title: 'Equal Size — Off/At Setpoint × Size',
2095
+ columns: 2,
2096
+ cases: [
2097
+ ReadoutListItemSize.small,
2098
+ ReadoutListItemSize.medium,
2099
+ ReadoutListItemSize.large,
2100
+ ].flatMap((size) =>
2101
+ [123, 120].map((value) => ({
2102
+ label: `${size} / ${value === 120 ? 'at' : 'off'} setpoint`,
2103
+ config: {
2104
+ value,
2105
+ hasSetpoint: true,
2106
+ setpoint: 120,
2107
+ options: {
2108
+ size,
2109
+ priority: ReadoutListItemPriority.enhanced,
2110
+ setpoint: {
2111
+ interaction: ReadoutListItemSetpointInteraction.equalSize,
2112
+ },
2113
+ },
2114
+ },
2115
+ }))
2116
+ ),
2117
+ },
2118
+ ]),
2119
+ };
2120
+
2121
+ /**
2122
+ * Advice semantic categories in a row context (Figma 6.1). The full per-block
2123
+ * matrix lives in the Readout Block `AdviceCategories` story.
2124
+ */
2125
+ export const AdviceCategories: Story = {
2126
+ render: () =>
2127
+ renderShowcase([
2128
+ {
2129
+ title: 'Advice categories — resting vs active',
2130
+ columns: 2,
2131
+ cases: Object.values(ReadoutAdviceCategory).flatMap((category) =>
2132
+ [false, true].map((active) => ({
2133
+ label: `${category}${active ? ' / active' : ''}`,
2134
+ config: {
2135
+ hasAdvice: true,
2136
+ options: {advice: {category, active}},
2137
+ },
2138
+ }))
2139
+ ),
2140
+ },
2141
+ ]),
2142
+ };
2143
+
2144
+ /**
2145
+ * Source states + deviation (Figma 6.1 Readout-block-source): `enhanced`
2146
+ * renders the amplified chip, `caution` / `warning` the alert chip;
2147
+ * `deviation` adds the Δ line under the source name. Outline-based, so a live
2148
+ * state change never shifts the row.
2149
+ */
2150
+ export const SourceStates: Story = {
2151
+ render: () =>
2152
+ renderShowcase([
2153
+ {
2154
+ title: 'Trailing source — state × deviation',
2155
+ columns: 2,
2156
+ cases: Object.values(ReadoutSourceState).flatMap((state) =>
2157
+ [undefined, 0.5].map((deviation) => ({
2158
+ label: `${state}${deviation !== undefined ? ' / Δ' : ''}`,
2159
+ config: {
2160
+ src: 'GPS 1',
2161
+ options: {src: {state, deviation}},
2162
+ },
2163
+ }))
2164
+ ),
2165
+ },
2166
+ {
2167
+ title: 'Leading source — state chip in the label stack',
2168
+ columns: 1,
2169
+ cases: [
2170
+ {
2171
+ label: 'leading-src / warning / Δ',
2172
+ config: {
2173
+ src: 'GPS 1',
2174
+ options: {
2175
+ stacking: ReadoutListItemStacking.leadingSrc,
2176
+ src: {state: ReadoutSourceState.warning, deviation: 0.5},
2177
+ },
2178
+ },
2179
+ },
2180
+ ],
2181
+ },
2182
+ ]),
2183
+ };
2184
+
2185
+ /**
2186
+ * `labelOptions`: dense rows default the label to `xs`; `size: 's'` opts a
2187
+ * row into the larger title (Figma 6.1 gives large stand-alone readouts `s`
2188
+ * by default — rows stay dense). The label is SemiBold only on enhanced rows.
2189
+ */
2190
+ export const LabelSize: Story = {
2191
+ render: () =>
2192
+ renderShowcase([
2193
+ {
2194
+ title: 'Label size — default (xs) vs s override × priority',
2195
+ columns: 2,
2196
+ cases: [undefined, ObcTextboxSize.s].flatMap((size) =>
2197
+ [
2198
+ ReadoutListItemPriority.regular,
2199
+ ReadoutListItemPriority.enhanced,
2200
+ ].map((priority) => ({
2201
+ label: `${size ?? 'default xs'} / ${priority}`,
2202
+ config: {
2203
+ options: {
2204
+ priority,
2205
+ label: size ? {size} : undefined,
2206
+ },
2207
+ },
2208
+ }))
2209
+ ),
2210
+ },
2211
+ ]),
2212
+ };
2213
+
2214
+ /**
2215
+ * TODO(designer): open question from the 6.1 review — while a pop-up setpoint
2216
+ * is hidden at-setpoint, should the reading keep a setpoint arrow so it still
2217
+ * reads as "a value you are in control of"? The existing `value-icon` slot
2218
+ * already expresses that today, demonstrated here; no new API until decided.
2219
+ */
2220
+ export const SetpointPopUpWithValueArrow: Story = {
2221
+ render: () => html`
2222
+ <style>
2223
+ ${showcaseStyle}
2224
+ </style>
2225
+ <div class="rli-sections">
2226
+ <p
2227
+ style="margin: 0; font: 12px/1.5 var(--global-typography-ui-label-font-family, inherit); color: var(--element-neutral-color, #777);"
2228
+ >
2229
+ Pop-up at setpoint, with an <code>obi-input-right</code> slotted into
2230
+ <code>value-icon</code> so the collapsed reading keeps the in-control
2231
+ marker.
2232
+ </p>
2233
+ <obc-readout-list-item
2234
+ .label=${'HDG'}
2235
+ .unit=${'/min'}
2236
+ .src=${'Source'}
2237
+ .value=${10}
2238
+ .hasSetpoint=${true}
2239
+ .setpoint=${10}
2240
+ .priority=${ReadoutListItemPriority.enhanced}
2241
+ .setpointOptions=${{
2242
+ interaction: ReadoutListItemSetpointInteraction.popUp,
2243
+ }}
2244
+ .valueOptions=${{hasIcon: true}}
2245
+ >
2246
+ <obi-input-right slot="value-icon"></obi-input-right>
2247
+ </obc-readout-list-item>
2248
+ </div>
2249
+ `,
2250
+ };
2251
+
2252
+ /**
2253
+ * Figma 6.1 bird's-eye matrix — a static expansion of the Readout-list-item
2254
+ * sheet (node 46544-270931): Size (3) × Priority (2) × Reference priority /
2255
+ * interaction (4, one section each) × State (4) = the sheet's 96 variants,
2256
+ * reviewable at a glance without touching controls. Degree is on throughout,
2257
+ * matching the sheet's instances. Note the list item keeps its own per-row
2258
+ * degree convention (setpoint / advice carry the degree too) — the
2259
+ * degree-on-the-actual-value-only rule from the 6.1 review applies to
2260
+ * `obc-readout` only.
2261
+ */
2262
+ export const FigmaMatrix: Story = {
2263
+ render: () =>
2264
+ renderShowcase(
2265
+ Object.values(ReadoutListItemSetpointInteraction).map((interaction) => ({
2266
+ title: `${interaction}`,
2267
+ columns: 8,
2268
+ cases: [
2269
+ ReadoutListItemSize.small,
2270
+ ReadoutListItemSize.medium,
2271
+ ReadoutListItemSize.large,
2272
+ ].flatMap((size) =>
2273
+ [
2274
+ ReadoutListItemPriority.regular,
2275
+ ReadoutListItemPriority.enhanced,
2276
+ ].flatMap((priority) =>
2277
+ (
2278
+ [
2279
+ {key: 'off setpoint', value: 123},
2280
+ {key: 'at setpoint', value: 120},
2281
+ {
2282
+ key: 'low-integrity',
2283
+ value: 123,
2284
+ dataQuality: ReadoutListItemDataQuality.lowIntegrity,
2285
+ },
2286
+ {
2287
+ key: 'invalid',
2288
+ value: 123,
2289
+ dataQuality: ReadoutListItemDataQuality.invalid,
2290
+ },
2291
+ ] as {
2292
+ key: string;
2293
+ value: number;
2294
+ dataQuality?: ReadoutListItemDataQuality;
2295
+ }[]
2296
+ ).map((state) => ({
2297
+ label: `${size} / ${priority} / ${state.key}`,
2298
+ config: {
2299
+ value: state.value,
2300
+ hasSetpoint: true,
2301
+ setpoint: 120,
2302
+ hasAdvice: true,
2303
+ options: {
2304
+ size,
2305
+ priority,
2306
+ hasDegree: true,
2307
+ dataQuality: state.dataQuality,
2308
+ setpoint: {interaction},
2309
+ },
2310
+ },
2311
+ }))
2312
+ )
2313
+ ),
2314
+ }))
2315
+ ),
2316
+ };