@bytebrand/fe-ui-core-autobahn 1.0.97 → 1.0.99
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/cards/cardParts.tsx +12 -7
- package/locales/de/autobahn.json +2 -1
- package/locales/en/autobahn.json +2 -1
- package/package.json +1 -1
- package/theme/md3.css +6 -3
- package/utils/financeFormat.ts +7 -0
- package/vdp/VdpModules.tsx +22 -22
package/cards/cardParts.tsx
CHANGED
|
@@ -939,6 +939,8 @@ export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t, c
|
|
|
939
939
|
const finFirstInstallment =
|
|
940
940
|
car.finFirstInstallment != null ? car.finFirstInstallment.toLocaleString('de-DE') : _finFirstInstallment;
|
|
941
941
|
const finMonths = car.finMonths ?? _finMonths;
|
|
942
|
+
const leasFirstInstallment =
|
|
943
|
+
car.leaseFirstInstallment != null ? car.leaseFirstInstallment.toLocaleString('de-DE') : _leasFirstInstallment;
|
|
942
944
|
const leasMileage = car.leaseMileage ?? _leasMileage;
|
|
943
945
|
const leasMonths = car.leaseMonths ?? _leasPeriod;
|
|
944
946
|
const hasLeasTerms = Boolean(leasMileage && leasMonths);
|
|
@@ -979,14 +981,17 @@ export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t, c
|
|
|
979
981
|
<PpRow label={t('autobahn:card.price.leasing')} value={car.lease as number} unit="mtl." />
|
|
980
982
|
{hasLeasTerms && (
|
|
981
983
|
<div className="pp-sub-terms">
|
|
982
|
-
{/*
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
984
|
+
{/* dedicated keys (not a rework of leaseTerms) so mobile/VDP's own reviewed
|
|
985
|
+
wording there stays untouched, but includes the same Sonderzahlung figure.
|
|
986
|
+
Split across two lines with an explicit <br/> (column is too narrow for all
|
|
987
|
+
three figures + Details on one line) — forced right after km/Jahr so "36" and
|
|
988
|
+
"Mon." always land on the same line instead of an awkward mid-number wrap. */}
|
|
989
|
+
{t('autobahn:card.price.leaseTermsCompactLine1', {
|
|
990
|
+
firstInstallment: leasFirstInstallment,
|
|
988
991
|
mileage: leasMileageStr,
|
|
989
|
-
})}{' '}
|
|
992
|
+
})}{' · '}
|
|
993
|
+
<br />
|
|
994
|
+
{t('autobahn:card.price.leaseTermsCompactLine2', { months: leasMonths })}{' '}
|
|
990
995
|
· {detailsLink('leasing')}
|
|
991
996
|
</div>
|
|
992
997
|
)}
|
package/locales/de/autobahn.json
CHANGED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"financeTerms": "{{firstInstallment}} € Anzahlung · {{months}} Monate",
|
|
13
13
|
"financeTerms_plural": "{{firstInstallment}} € Anzahlung · {{months}} Monate",
|
|
14
14
|
"leaseTerms": "{{firstInstallment}} € Sonderzahlung · {{months}} Mon. · {{mileage}} km/Jahr",
|
|
15
|
-
"
|
|
15
|
+
"leaseTermsCompactLine1": "{{firstInstallment}} € Sonderzahlung · {{mileage}} km/Jahr",
|
|
16
|
+
"leaseTermsCompactLine2": "{{months}} Mon.",
|
|
16
17
|
"detailsLink": "Details",
|
|
17
18
|
"uvpRateLabel": "UVP-Rate",
|
|
18
19
|
"uvpRateTooltipBody": "Rechnerische Vergleichsrate auf Basis der unverbindlichen Preisempfehlung des Herstellers und mit denselben Finanzierungsparametern wie das Angebot. Keine früher verlangte Rate. Das Rundum-Sorglos-Paket wird einmalig separat berechnet.",
|
package/locales/en/autobahn.json
CHANGED
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
"financeTerms": "€{{firstInstallment}} down payment · {{months}} months",
|
|
13
13
|
"financeTerms_plural": "€{{firstInstallment}} down payment · {{months}} months term",
|
|
14
14
|
"leaseTerms": "€{{firstInstallment}} down payment · {{months}} mo. · {{mileage}} km/year",
|
|
15
|
-
"
|
|
15
|
+
"leaseTermsCompactLine1": "€{{firstInstallment}} down payment · {{mileage}} km/year",
|
|
16
|
+
"leaseTermsCompactLine2": "{{months}} mo.",
|
|
16
17
|
"detailsLink": "Details",
|
|
17
18
|
"uvpRateLabel": "UVP rate",
|
|
18
19
|
"uvpRateTooltipBody": "Calculated comparison rate based on the manufacturer's non-binding price recommendation, using the same financing parameters as the offer. Not a previously requested rate. The all-inclusive package is billed separately, as a one-off.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bytebrand/fe-ui-core-autobahn",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.99",
|
|
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/theme/md3.css
CHANGED
|
@@ -5844,9 +5844,10 @@ line-height: 31px;
|
|
|
5844
5844
|
.md3 .vdp-bottom-bar {
|
|
5845
5845
|
position: fixed;
|
|
5846
5846
|
left: 0;
|
|
5847
|
+
right: 0;
|
|
5847
5848
|
bottom: 0;
|
|
5848
5849
|
z-index: 60;
|
|
5849
|
-
width:
|
|
5850
|
+
width: auto;
|
|
5850
5851
|
height: 196px;
|
|
5851
5852
|
background: rgba(244, 243, 243, 0.95);
|
|
5852
5853
|
border: 1px solid #D4DDE7;
|
|
@@ -8637,7 +8638,9 @@ color: #005CFF;
|
|
|
8637
8638
|
font-size: 13px;
|
|
8638
8639
|
line-height: 15px;
|
|
8639
8640
|
color: #111820;
|
|
8641
|
+
margin: 0px 0px;
|
|
8640
8642
|
margin-bottom: 12px;
|
|
8643
|
+
vertical-align: -3px;
|
|
8641
8644
|
}
|
|
8642
8645
|
/* "Finanzierungsdetails"/"Leasing-Details" reads as a link here (unlike CarCard's quiet
|
|
8643
8646
|
.cc-terms-link, which stays text-colored on purpose) — underlined. */
|
|
@@ -8657,11 +8660,11 @@ color: #005CFF;
|
|
|
8657
8660
|
font-weight: 700 !important;
|
|
8658
8661
|
color: var(--md-on-surface-variant) !important;
|
|
8659
8662
|
}
|
|
8660
|
-
/* figma pricing-card padding is
|
|
8663
|
+
/* figma pricing-card padding is 15px 12px (inline says 20 — hence !important); the side-by-side
|
|
8661
8664
|
CTAs must be allowed to SHRINK (mbtn is nowrap min-width:auto, 0-30px padding — the pair
|
|
8662
8665
|
alone mins out wider than the phone card) */
|
|
8663
8666
|
.md3 .vdp-aside > .mcard {
|
|
8664
|
-
padding:
|
|
8667
|
+
padding: 15px 12px !important;
|
|
8665
8668
|
}
|
|
8666
8669
|
.md3 .fin-cta-row .mbtn {
|
|
8667
8670
|
min-width: 0;
|
package/utils/financeFormat.ts
CHANGED
|
@@ -19,6 +19,13 @@ export function formatPct(n: number): string {
|
|
|
19
19
|
return `${n.toFixed(2).replace('.', ',')} %`;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
/** Monetary figure → de-DE grouped string with fixed cents (e.g. 44333 → "44.333,00",
|
|
23
|
+
* 42243.9 → "42.243,90"). Unlike formatEur, always shows exactly 2 decimals — for the "Repräsentatives
|
|
24
|
+
* Beispiel" breakdown table (FinanceDetailsModal), where every € line is expected to carry cents. */
|
|
25
|
+
export function formatEurCents(n: number): string {
|
|
26
|
+
return n.toLocaleString('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
|
|
27
|
+
}
|
|
28
|
+
|
|
22
29
|
export interface FinanceExampleFields {
|
|
23
30
|
price: number;
|
|
24
31
|
apr: number;
|
package/vdp/VdpModules.tsx
CHANGED
|
@@ -28,7 +28,7 @@ import { Button, Dropdown, DropdownOption, Icon, Spec, StatChip, Stars } from '.
|
|
|
28
28
|
import { CO2_CLASSES, CO2_COLORS, TIER_LABELS, TIER_KEYS, TIER_COLORS, TIER_BACKGROUNDS } from '../constants';
|
|
29
29
|
import { defaultVdpSpecs, EquipmentGroups, PriceRatingBands, VehicleDetail, VdpSpec, VdpReview } from './types';
|
|
30
30
|
import { AddServicesTooltipBody, CalcRow, DocCheckIcon, EvalBar, expanderBtnStyle, FinanceMode, Slider, TermChips, ToggleRow } from './FinanceCalculator';
|
|
31
|
-
import { formatEur as eur, formatPct as pct } from '../utils/financeFormat';
|
|
31
|
+
import { formatEur as eur, formatEurCents as eurCents, formatPct as pct } from '../utils/financeFormat';
|
|
32
32
|
|
|
33
33
|
/** Figma "check with open arc" glyph (modern lucide circle-check-big; the bundled lucide
|
|
34
34
|
* 0.288 only ships the closed-circle variant, so the two paths are inlined). */
|
|
@@ -2082,51 +2082,51 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
|
|
|
2082
2082
|
const subtotalWithPackage = ratesSum != null ? ratesSum + down + (hasAddServicesRow ? addServicesRowValue : 0) : undefined;
|
|
2083
2083
|
const grandTotal = subtotalWithPackage != null ? subtotalWithPackage + residual : undefined;
|
|
2084
2084
|
rows = [
|
|
2085
|
-
[t('autobahn:modal.leaseVehiclePrice'), `${
|
|
2085
|
+
[t('autobahn:modal.leaseVehiclePrice'), `${eurCents(price)} €`],
|
|
2086
2086
|
[t('autobahn:modal.term'), t('autobahn:modal.months', { months: term, count: term })],
|
|
2087
2087
|
...(annualMileage != null ? ([[t('autobahn:modal.annualMileage'), `${eur(annualMileage)} km`]] as Array<[string, string]>) : []),
|
|
2088
|
-
[t('autobahn:modal.leaseDownPayment'), `${
|
|
2089
|
-
[t('autobahn:modal.leasingRateCount', { count: term }), `${
|
|
2090
|
-
[t('autobahn:modal.finalPaymentDue'), `${
|
|
2091
|
-
...(residual > 0 ? ([[t('autobahn:modal.residualValue'), `${
|
|
2088
|
+
[t('autobahn:modal.leaseDownPayment'), `${eurCents(down)} €`],
|
|
2089
|
+
[t('autobahn:modal.leasingRateCount', { count: term }), `${eurCents(monthly)} €`],
|
|
2090
|
+
[t('autobahn:modal.finalPaymentDue'), `${eurCents(0)} €`],
|
|
2091
|
+
...(residual > 0 ? ([[t('autobahn:modal.residualValue'), `${eurCents(residual)} €`]] as Array<[string, string]>) : []),
|
|
2092
2092
|
...(ratesSum != null
|
|
2093
|
-
? ([[t('autobahn:modal.rateSumLabel', { term, amount:
|
|
2093
|
+
? ([[t('autobahn:modal.rateSumLabel', { term, amount: eurCents(monthly) }), `${eurCents(ratesSum)} €`, true]] as Array<[string, string, boolean]>)
|
|
2094
2094
|
: []),
|
|
2095
|
-
...(ratesSum != null ? ([[t('autobahn:modal.leaseDownPayment'), `${
|
|
2095
|
+
...(ratesSum != null ? ([[t('autobahn:modal.leaseDownPayment'), `${eurCents(down)} €`]] as Array<[string, string]>) : []),
|
|
2096
2096
|
...(ratesSum != null && hasAddServicesRow
|
|
2097
|
-
? ([[t('autobahn:modal.addServicesRowLease'), `${
|
|
2097
|
+
? ([[t('autobahn:modal.addServicesRowLease'), `${eurCents(addServicesRowValue)} €`]] as Array<[string, string]>)
|
|
2098
2098
|
: []),
|
|
2099
2099
|
...(subtotalWithPackage != null
|
|
2100
|
-
? ([[hasAddServicesRow ? t('autobahn:modal.subtotalWithPackage') : t('autobahn:modal.subtotalNoPackage'), `${
|
|
2100
|
+
? ([[hasAddServicesRow ? t('autobahn:modal.subtotalWithPackage') : t('autobahn:modal.subtotalNoPackage'), `${eurCents(subtotalWithPackage)} €`, true]] as Array<
|
|
2101
2101
|
[string, string, boolean]
|
|
2102
2102
|
>)
|
|
2103
2103
|
: []),
|
|
2104
|
-
...(residual > 0 && grandTotal != null ? ([[t('autobahn:modal.residualValue'), `${
|
|
2104
|
+
...(residual > 0 && grandTotal != null ? ([[t('autobahn:modal.residualValue'), `${eurCents(residual)} €`]] as Array<[string, string]>) : []),
|
|
2105
2105
|
...(grandTotal != null
|
|
2106
|
-
? ([[t('autobahn:modal.grandTotalWithResidual'), `${
|
|
2106
|
+
? ([[t('autobahn:modal.grandTotalWithResidual'), `${eurCents(grandTotal)} €`, true]] as Array<[string, string, boolean]>)
|
|
2107
2107
|
: []),
|
|
2108
|
-
...(listPrice != null && listPrice > 0 ? ([[t('autobahn:modal.listPriceLease'), `${
|
|
2108
|
+
...(listPrice != null && listPrice > 0 ? ([[t('autobahn:modal.listPriceLease'), `${eurCents(listPrice)} €`]] as Array<[string, string]>) : []),
|
|
2109
2109
|
];
|
|
2110
2110
|
} else {
|
|
2111
2111
|
rows = [
|
|
2112
|
-
[t('autobahn:modal.vehiclePrice'), `${
|
|
2112
|
+
[t('autobahn:modal.vehiclePrice'), `${eurCents(price)} €`],
|
|
2113
2113
|
[t('autobahn:modal.term'), t('autobahn:modal.months', { months: term, count: term })],
|
|
2114
|
-
[t('autobahn:modal.downPayment'), `${
|
|
2115
|
-
[t('autobahn:modal.monthlyRateCount', { count: term }), `${
|
|
2116
|
-
...(finalInstallment != null && finalInstallment > 0 ? ([[t('autobahn:modal.finalInstallment'), `${
|
|
2114
|
+
[t('autobahn:modal.downPayment'), `${eurCents(down)} €`],
|
|
2115
|
+
[t('autobahn:modal.monthlyRateCount', { count: term }), `${eurCents(monthly)} €`],
|
|
2116
|
+
...(finalInstallment != null && finalInstallment > 0 ? ([[t('autobahn:modal.finalInstallment'), `${eurCents(finalInstallment)} €`]] as Array<[string, string]>) : []),
|
|
2117
2117
|
...(hasAddServicesRow
|
|
2118
|
-
? ([[t('autobahn:modal.addServicesRow'), `${
|
|
2118
|
+
? ([[t('autobahn:modal.addServicesRow'), `${eurCents(addServicesRowValue)} €`]] as Array<[string, string]>)
|
|
2119
2119
|
: []),
|
|
2120
2120
|
...(nominalRate != null && nominalRate > 0 ? ([[t('autobahn:modal.nominalRate'), pct(nominalRate)]] as Array<[string, string]>) : []),
|
|
2121
2121
|
[t('autobahn:modal.effectiveRate'), pct(apr)],
|
|
2122
|
-
[t('autobahn:modal.netLoanAmount'), `${
|
|
2123
|
-
...(grossAmount != null && grossAmount > 0 ? ([[t('autobahn:modal.totalRepayment'), `${
|
|
2122
|
+
[t('autobahn:modal.netLoanAmount'), `${eurCents(netto)} €`],
|
|
2123
|
+
...(grossAmount != null && grossAmount > 0 ? ([[t('autobahn:modal.totalRepayment'), `${eurCents(grossAmount)} €`]] as Array<[string, string]>) : []),
|
|
2124
2124
|
...(totalCost != null
|
|
2125
|
-
? ([[hasAddServices ? t('autobahn:modal.totalCostWithPackage') : t('autobahn:modal.totalCost'), `${
|
|
2125
|
+
? ([[hasAddServices ? t('autobahn:modal.totalCostWithPackage') : t('autobahn:modal.totalCost'), `${eurCents(totalCost)} €`, true]] as Array<
|
|
2126
2126
|
[string, string, boolean]
|
|
2127
2127
|
>)
|
|
2128
2128
|
: []),
|
|
2129
|
-
...(listPrice != null && listPrice > 0 ? ([[t('autobahn:modal.listPrice'), `${
|
|
2129
|
+
...(listPrice != null && listPrice > 0 ? ([[t('autobahn:modal.listPrice'), `${eurCents(listPrice)} €`]] as Array<[string, string]>) : []),
|
|
2130
2130
|
];
|
|
2131
2131
|
}
|
|
2132
2132
|
const breakdownRows = rows.map(([l, v, bold], i) => (
|