@bytebrand/fe-ui-core-autobahn 1.0.119 → 1.0.120

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytebrand/fe-ui-core-autobahn",
3
- "version": "1.0.119",
3
+ "version": "1.0.120",
4
4
  "description": "auto.de md3 (Autobahn) design system — UI primitives, cards, chrome, VDP modules, theme CSS and locales. Ships raw TypeScript source (like fe-ui-core before it); each consumer's bundler compiles it.",
5
5
  "main": "index.ts",
6
6
  "license": "UNLICENSED",
package/vdp/index.ts CHANGED
@@ -71,7 +71,7 @@ export type {
71
71
  } from './VdpModules';
72
72
 
73
73
  // View-model types + the spec-table helper.
74
- export { defaultVdpSpecs } from './types';
74
+ export { defaultVdpSpecs, isZeroSpecValue } from './types';
75
75
  export type {
76
76
  VehicleDetail,
77
77
  VehicleCondition,
package/vdp/types.ts CHANGED
@@ -20,6 +20,39 @@ export type { AutobahnPhev };
20
20
  /** One row of the Fahrzeugdaten spec table: [kebab-case lucide icon, label, value]. */
21
21
  export type VdpSpec = readonly [icon: string, label: string, value: string];
22
22
 
23
+ // ---------------------------------------------------------------------------
24
+ // Zero-value spec visibility (CDP ticket "Hide meaningless zero-value vehicle
25
+ // attributes") — the single shared rule behind whether a Fahrzeugdaten row
26
+ // renders when its underlying measurement is 0.
27
+ //
28
+ // Most numeric vehicle attributes (Leergewicht, Hubraum, Drehmoment, …) are
29
+ // physical measurements that are never legitimately 0 — a 0 there means "no
30
+ // data", not "the car weighs nothing", and rendering "0 kg" actively damages
31
+ // trust in the data (the reported bug). The DEFAULT for a numeric spec is
32
+ // therefore to hide the row entirely rather than show a fabricated-looking
33
+ // zero.
34
+ //
35
+ // That default must NOT apply blindly to every field, per two carve-outs:
36
+ // - some fields have a real, meaningful zero (0 Vorbesitzer = never owned,
37
+ // 0 km = brand-new car) — callers opt these OUT of hiding explicitly;
38
+ // - the Pkw-EnVKV legally-required consumption/emissions figures (cons,
39
+ // co2, co2class, and by the same regulatory family Verbrauch innerorts/
40
+ // außerorts) must never be suppressed by this generic rule — their own
41
+ // compliance/data-quality logic decides what renders, so callers building
42
+ // those rows must never run them through this check at all.
43
+ //
44
+ // isZeroSpecValue operates on the already-FORMATTED display string (not the
45
+ // raw number) because callers combine both string-typed values (decorated
46
+ // getters that already bake in a unit, e.g. "0 kg") and plain numbers
47
+ // (`${n} Sitze`) into the same VdpSpec value slot — checking the rendered
48
+ // string is the one place both shapes agree. It matches a leading zero
49
+ // magnitude (optionally with an all-zero decimal, "0,0"/"0.0") followed by
50
+ // whitespace (a unit) or end-of-string, so "0 kg"/"0,0 l/100 km"/"0" all
51
+ // count as zero but "10 kg"/"0.5 l" (a real non-zero measurement) do not.
52
+ export function isZeroSpecValue(formatted: string): boolean {
53
+ return /^-?0([.,]0+)?(\s|$)/.test(formatted.trim());
54
+ }
55
+
23
56
  /**
24
57
  * Grouped equipment: each entry is a section title mapped to its item labels,
25
58
  * e.g. { Komfort: ['Klimaautomatik', …], Sicherheit: [...] }. Replaces the design
@@ -200,20 +233,27 @@ export interface VehicleDetail {
200
233
  * Build the design's twelve-row Fahrzeugdaten table from the typed fields. Used
201
234
  * when a VehicleDetail carries no explicit `specs`. Pure — produces the same rows
202
235
  * and order as the spec's ScreenVDP `specs` array.
236
+ *
237
+ * `allowZero: true` marks fields where 0 is a real, meaningful value (or isn't a
238
+ * zero-able numeric at all) — everything else gets the isZeroSpecValue default
239
+ * (hide the row rather than render a fabricated-looking "0 X"). cons/co2class
240
+ * are Pkw-EnVKV legally-required and are marked allowZero for that reason, not
241
+ * because 0 is plausible there — see isZeroSpecValue's own comment.
203
242
  */
204
243
  export function defaultVdpSpecs(v: VehicleDetail): VdpSpec[] {
205
- return [
206
- ['gauge', 'Kilometerstand', `${v.km.toLocaleString('de-DE')} km`],
207
- ['calendar', 'Erstzulassung', v.reg],
208
- ['zap', 'Leistung', v.power],
209
- ['fuel', 'Kraftstoff', v.fuel],
210
- ['cog', 'Getriebe', v.gear],
211
- ['users', 'Sitze', `${v.seats} Sitze`],
212
- ['door-open', 'Türen', `${v.doors} Türen`],
213
- ['user', 'Halter', `${v.owners}. Hand`],
214
- ['palette', 'Außenfarbe', v.color],
215
- ['car-front', 'Karosserie', v.body],
216
- ['droplet', 'Verbrauch komb.', v.cons],
217
- ['leaf', 'CO₂ · Klasse', `${v.co2} · ${v.co2class}`],
244
+ const rows: ReadonlyArray<readonly [spec: VdpSpec, allowZero: boolean]> = [
245
+ [['gauge', 'Kilometerstand', `${v.km.toLocaleString('de-DE')} km`], true], // Neuwagen: 0 km is valid
246
+ [['calendar', 'Erstzulassung', v.reg], true],
247
+ [['zap', 'Leistung', v.power], true],
248
+ [['fuel', 'Kraftstoff', v.fuel], true],
249
+ [['cog', 'Getriebe', v.gear], true],
250
+ [['users', 'Sitze', `${v.seats} Sitze`], false],
251
+ [['door-open', 'Türen', `${v.doors} Türen`], false],
252
+ [['user', 'Halter', `${v.owners}. Hand`], true], // 0 Vorbesitzer is valid
253
+ [['palette', 'Außenfarbe', v.color], true],
254
+ [['car-front', 'Karosserie', v.body], true],
255
+ [['droplet', 'Verbrauch komb.', v.cons], true], // Pkw-EnVKV — exempt from this rule
256
+ [['leaf', 'CO₂ · Klasse', `${v.co2} · ${v.co2class}`], true], // Pkw-EnVKV — exempt
218
257
  ];
258
+ return rows.filter(([spec, allowZero]) => allowZero || !isZeroSpecValue(spec[2])).map(([spec]) => spec);
219
259
  }