@bytebrand/fe-ui-core-autobahn 1.0.81 → 1.0.83
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/CarCard.tsx +9 -1
- package/cards/CarRow.tsx +31 -3
- package/cards/cardParts.tsx +23 -3
- package/compat/CookieModal/modals/ManageCookieModal/ManageCookieModal.tsx +2 -2
- package/compat/MdAccordionGroup/MdAccordionGroup.tsx +1 -1
- package/locales/de/autobahn.json +5 -2
- package/locales/en/autobahn.json +5 -2
- package/package.json +1 -1
- package/theme/md3.css +21 -2
- package/vdp/FinanceCalculator.tsx +19 -6
- package/vdp/VdpModules.tsx +9 -7
package/cards/CarCard.tsx
CHANGED
|
@@ -102,6 +102,14 @@ const CarCard: React.FunctionComponent<CarCardProps> = ({
|
|
|
102
102
|
const [viewerOpen, setViewerOpen] = useState(false);
|
|
103
103
|
const showSave = car.savings != null && car.savings > 600;
|
|
104
104
|
const showOfferBadge = !!(car.isNew || car.drop != null || showSave || car.dropPct != null || car.zeroDown);
|
|
105
|
+
// PM call: the badge row only fits 3 pills — when Drop/Save + Percent + ZeroDown are all
|
|
106
|
+
// active that's already 3, so NEU is dropped rather than causing a 4th to overflow.
|
|
107
|
+
const activeDealChips = [
|
|
108
|
+
car.drop != null || showSave,
|
|
109
|
+
car.dropPct != null && car.dropPct > 0,
|
|
110
|
+
!!car.zeroDown,
|
|
111
|
+
].filter(Boolean).length;
|
|
112
|
+
const showNeu = car.isNew && activeDealChips < 3;
|
|
105
113
|
return (
|
|
106
114
|
<article
|
|
107
115
|
className="mcard mcard--interactive cc-card"
|
|
@@ -162,7 +170,7 @@ const CarCard: React.FunctionComponent<CarCardProps> = ({
|
|
|
162
170
|
color: '#005CFF',
|
|
163
171
|
}}
|
|
164
172
|
/>
|
|
165
|
-
{
|
|
173
|
+
{showNeu && <span className="neu-badge">NEU</span>}
|
|
166
174
|
</div>
|
|
167
175
|
<OfferBadge show={showOfferBadge} t={t} />
|
|
168
176
|
</div>
|
package/cards/CarRow.tsx
CHANGED
|
@@ -60,13 +60,36 @@ export interface CarRowProps {
|
|
|
60
60
|
* Rendered as a quiet button under the CTA; the page decides visibility (JWT claim).
|
|
61
61
|
*/
|
|
62
62
|
adminAction?: { label: string; onClick: () => void };
|
|
63
|
+
/**
|
|
64
|
+
* takes over the desktop price column's "Details" links (financing/leasing terms rows) — e.g.
|
|
65
|
+
* navigate to this car's own VDP and open its finance modal already expanded, on the tab the
|
|
66
|
+
* link was under. Optional/page-owned like CarCard's identically-named prop; when omitted the
|
|
67
|
+
* links render as plain text (see PricePaths' own fallback).
|
|
68
|
+
*/
|
|
69
|
+
onShowFinancingDetails?: (car: AutobahnCar, mode: PaymentMode) => void;
|
|
63
70
|
}
|
|
64
71
|
|
|
65
|
-
const CarRow: React.FunctionComponent<CarRowProps> = ({
|
|
72
|
+
const CarRow: React.FunctionComponent<CarRowProps> = ({
|
|
73
|
+
car,
|
|
74
|
+
isFavorite,
|
|
75
|
+
onToggleFavorite,
|
|
76
|
+
onOpen,
|
|
77
|
+
onMediaEnter,
|
|
78
|
+
t,
|
|
79
|
+
adminAction,
|
|
80
|
+
onShowFinancingDetails,
|
|
81
|
+
}) => {
|
|
66
82
|
const [mode, setMode] = useState<PaymentMode>('financing');
|
|
67
83
|
const [photoIndex, setPhotoIndex] = useState(0);
|
|
68
84
|
const showSave = car.savings != null && car.savings > 600;
|
|
69
85
|
const showOfferBadge = !!(car.isNew || car.drop != null || showSave || car.dropPct != null || car.zeroDown);
|
|
86
|
+
// same overflow rule as CarCard: the row only fits 3 pills, so NEU drops when the other 3 are all active.
|
|
87
|
+
const activeDealChips = [
|
|
88
|
+
car.drop != null || showSave,
|
|
89
|
+
car.dropPct != null && car.dropPct > 0,
|
|
90
|
+
!!car.zeroDown,
|
|
91
|
+
].filter(Boolean).length;
|
|
92
|
+
const showNeu = car.isNew && activeDealChips < 3;
|
|
70
93
|
const facts: Array<[icon: string, value: string]> = [
|
|
71
94
|
['gauge', fmtKm(car.km)],
|
|
72
95
|
['calendar', t('autobahn:card.specs.firstRegistration', { reg: car.reg })],
|
|
@@ -106,7 +129,7 @@ const CarRow: React.FunctionComponent<CarRowProps> = ({ car, isFavorite, onToggl
|
|
|
106
129
|
}}
|
|
107
130
|
>
|
|
108
131
|
<div style={{ display: 'flex', flexWrap: 'nowrap', alignItems: 'center', gap: 5 }}>
|
|
109
|
-
{
|
|
132
|
+
{showNeu && <span className="neu-badge">NEU</span>}
|
|
110
133
|
{car.drop != null ? <DropChip t={t} amount={car.drop} /> : showSave && <SaveChip t={t} amount={car.savings!} />}
|
|
111
134
|
<ZeroDownChip t={t} show={car.zeroDown} compact className="show-mobile" />
|
|
112
135
|
<ZeroDownChip
|
|
@@ -259,7 +282,12 @@ const CarRow: React.FunctionComponent<CarRowProps> = ({ car, isFavorite, onToggl
|
|
|
259
282
|
<PpActivity t={t} car={car} />
|
|
260
283
|
</div>
|
|
261
284
|
|
|
262
|
-
<PricePaths
|
|
285
|
+
<PricePaths
|
|
286
|
+
car={car}
|
|
287
|
+
t={t}
|
|
288
|
+
className="hide-mobile"
|
|
289
|
+
onShowDetails={onShowFinancingDetails ? (mode) => onShowFinancingDetails(car, mode) : undefined}
|
|
290
|
+
/>
|
|
263
291
|
<div className="pp-purchase hide-mobile">
|
|
264
292
|
<PriceKauf car={car} t={t} />
|
|
265
293
|
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
|
package/cards/cardParts.tsx
CHANGED
|
@@ -386,6 +386,11 @@ export interface PricePathsProps {
|
|
|
386
386
|
t: TranslationFunction;
|
|
387
387
|
/** extra class appended to the root (e.g. the SRP card's desktop-only `hide-mobile` marker). */
|
|
388
388
|
className?: string;
|
|
389
|
+
/** takes over the financing/leasing terms rows' own "Details" links — e.g. navigate to this
|
|
390
|
+
* car's VDP and open its finance modal already expanded, on the tab the link was under
|
|
391
|
+
* (financing/leasing). Optional/page-owned like CarCard's onShowFinancingDetails; when
|
|
392
|
+
* omitted the links render as plain (non-interactive) text, same as before this prop existed. */
|
|
393
|
+
onShowDetails?: (mode: PaymentMode) => void;
|
|
389
394
|
}
|
|
390
395
|
|
|
391
396
|
/** Map the AutobahnCar rating tone → meter segment index (0 best … 4 worst). */
|
|
@@ -926,7 +931,7 @@ const PpRow: React.FunctionComponent<PpRowProps> = ({ label, value, unit, old, f
|
|
|
926
931
|
* is omitted entirely when leasing isn't active. The Kaufen row is rendered separately
|
|
927
932
|
* (PriceKauf) below a divider so only the financing rate stands out — no wall of blue prices.
|
|
928
933
|
*/
|
|
929
|
-
export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t, className }) => {
|
|
934
|
+
export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t, className, onShowDetails }) => {
|
|
930
935
|
const hasLease = car.lease != null;
|
|
931
936
|
// Terms of the config the displayed rate was actually computed with (per-car:
|
|
932
937
|
// dealer rate + the user's saved localStorage adjustments) — default config
|
|
@@ -938,6 +943,21 @@ export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t, c
|
|
|
938
943
|
const leasMonths = car.leaseMonths ?? _leasPeriod;
|
|
939
944
|
const hasLeasTerms = Boolean(leasMileage && leasMonths);
|
|
940
945
|
const leasMileageStr = leasMileage ? Number(leasMileage).toLocaleString('de-DE') : '';
|
|
946
|
+
const detailsLink = (mode: PaymentMode): React.ReactNode =>
|
|
947
|
+
onShowDetails ? (
|
|
948
|
+
<button
|
|
949
|
+
type="button"
|
|
950
|
+
className="pp-details-link"
|
|
951
|
+
onClick={(e) => {
|
|
952
|
+
e.stopPropagation();
|
|
953
|
+
onShowDetails(mode);
|
|
954
|
+
}}
|
|
955
|
+
>
|
|
956
|
+
{t('autobahn:card.price.details')}
|
|
957
|
+
</button>
|
|
958
|
+
) : (
|
|
959
|
+
<span className="pp-details-link">{t('autobahn:card.price.details')}</span>
|
|
960
|
+
);
|
|
941
961
|
return (
|
|
942
962
|
<div className={'pricepaths' + (className ? ' ' + className : '')}>
|
|
943
963
|
<div className="pp-eyebrow">{t('autobahn:card.price.financingFrom')}</div>
|
|
@@ -952,7 +972,7 @@ export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t, c
|
|
|
952
972
|
months: finMonths,
|
|
953
973
|
count: finMonths,
|
|
954
974
|
})}{' '}
|
|
955
|
-
·
|
|
975
|
+
· {detailsLink('financing')}
|
|
956
976
|
</div>
|
|
957
977
|
{hasLease && (
|
|
958
978
|
<div className="pp-lease-row">
|
|
@@ -967,7 +987,7 @@ export const PricePaths: React.FunctionComponent<PricePathsProps> = ({ car, t, c
|
|
|
967
987
|
months: leasMonths,
|
|
968
988
|
mileage: leasMileageStr,
|
|
969
989
|
})}{' '}
|
|
970
|
-
·
|
|
990
|
+
· {detailsLink('leasing')}
|
|
971
991
|
</div>
|
|
972
992
|
)}
|
|
973
993
|
</div>
|
|
@@ -30,11 +30,11 @@ const ManageCookieModal = ({ toggleModal, handleSentryInit } : IManageCookieModa
|
|
|
30
30
|
() => {
|
|
31
31
|
const newAnalyticsSwitches = Object.values(COOKIE_SCHEMA.analytics)
|
|
32
32
|
.reduce((acc, val) => acc.concat(val), [])
|
|
33
|
-
.reduce((acc, item) => ({ ...acc, [item]:
|
|
33
|
+
.reduce((acc, item) => ({ ...acc, [item]: true }), {});
|
|
34
34
|
|
|
35
35
|
const newMarketingSwitches = Object.values(COOKIE_SCHEMA.marketing)
|
|
36
36
|
.reduce((acc, val) => acc.concat(val), [])
|
|
37
|
-
.reduce((acc, item) => ({ ...acc, [item]:
|
|
37
|
+
.reduce((acc, item) => ({ ...acc, [item]: true }), {});
|
|
38
38
|
setAnalyticsSwitches(newAnalyticsSwitches);
|
|
39
39
|
setMarketingSwitches(newMarketingSwitches);
|
|
40
40
|
},
|
|
@@ -45,7 +45,7 @@ const MdAccordionGroup: React.FC<IMdAccordionGroupProps> = ({ title, tooltipText
|
|
|
45
45
|
) : null}
|
|
46
46
|
<Icon name='chevron-down' cls='macc-chev' />
|
|
47
47
|
</div>
|
|
48
|
-
{open ? <div style={{ padding: '4px
|
|
48
|
+
{open ? <div style={{ padding: '4px 15px 12px' }}>{children}</div> : null}
|
|
49
49
|
</section>
|
|
50
50
|
);
|
|
51
51
|
};
|
package/locales/de/autobahn.json
CHANGED
|
@@ -107,9 +107,12 @@
|
|
|
107
107
|
"addServicesPerMonth": "+{{value}} € / Monat",
|
|
108
108
|
"addServicesOnce": "+{{value}} €",
|
|
109
109
|
"addServicesIncluded": "inklusive",
|
|
110
|
-
"
|
|
110
|
+
"addServicesTooltipIntroCash": "Das Rundum-Sorglos-Paket ist Bestandteil des Angebots und im Kaufpreis enthalten.",
|
|
111
|
+
"addServicesTooltipIntroFinanced": "Das Rundum-Sorglos-Paket ist verpflichtender Bestandteil des Angebots. Die Kosten fallen unabhängig von der gewählten Zahlungsweise an.",
|
|
111
112
|
"addServicesTooltipHeading": "Im Rundum-Sorglos-Paket enthalten:",
|
|
112
|
-
"addServicesTooltipItems": "kompletter Zulassungsservice inklusive Wunschkennzeichen, soweit verfügbar\nsorgfältige Prüfung und Vorbereitung aller Zulassungsunterlagen\nbundesweite Fahrzeugauslieferung bis vor Ihre Haustür\npersönliche Fahrzeugübergabe\nhochwertige Fahrzeugaufbereitung innen und außen\nausführlicher technischer Übergabecheck\nHU und Inspektion, falls erforderlich\nTank- beziehungsweise Ladegrundfüllung bei Übergabe\npersönlicher Ansprechpartner von Beginn an"
|
|
113
|
+
"addServicesTooltipItems": "kompletter Zulassungsservice inklusive Wunschkennzeichen, soweit verfügbar\nsorgfältige Prüfung und Vorbereitung aller Zulassungsunterlagen\nbundesweite Fahrzeugauslieferung bis vor Ihre Haustür\npersönliche Fahrzeugübergabe\nhochwertige Fahrzeugaufbereitung innen und außen\nausführlicher technischer Übergabecheck\nHU und Inspektion, falls erforderlich\nTank- beziehungsweise Ladegrundfüllung bei Übergabe\npersönlicher Ansprechpartner von Beginn an",
|
|
114
|
+
"addServicesTooltipOutroFinancing": "Sie können die Paketkosten entweder einmalig in Höhe von 1.499,00 € bezahlen oder in die Fahrzeugfinanzierung einbeziehen lassen. Bei der Mitfinanzierung wird keine zusätzliche Einmalzahlung für das Paket erhoben. Die gewählte Zahlungsweise sowie die daraus resultierende monatliche Finanzierungsrate und der Gesamtbetrag werden in den Finanzierungsdetails ausgewiesen. Die Paketkosten sind in jedem Fall im ausgewiesenen Gesamtbetrag berücksichtigt.",
|
|
115
|
+
"addServicesTooltipOutroLeasing": "Sie können die Paketkosten entweder einmalig in Höhe von 1.499,00 € bezahlen oder in die monatliche Leasingrate einrechnen lassen. Bei der Rateneinrechnung wird keine zusätzliche Einmalzahlung für das Paket erhoben. Die gewählte Zahlungsweise sowie die daraus resultierende Monatsrate und der Gesamtbetrag werden in den Leasingdetails ausgewiesen. Die Paketkosten sind in jedem Fall im ausgewiesenen Gesamtbetrag berücksichtigt."
|
|
113
116
|
},
|
|
114
117
|
"specTable": {
|
|
115
118
|
"title": "Fahrzeugdaten",
|
package/locales/en/autobahn.json
CHANGED
|
@@ -107,9 +107,12 @@
|
|
|
107
107
|
"addServicesPerMonth": "+€{{value}} / month",
|
|
108
108
|
"addServicesOnce": "+€{{value}}",
|
|
109
109
|
"addServicesIncluded": "included",
|
|
110
|
-
"
|
|
110
|
+
"addServicesTooltipIntroCash": "The all-round care package is part of the offer and included in the purchase price.",
|
|
111
|
+
"addServicesTooltipIntroFinanced": "The all-round care package is a mandatory part of the offer. Its cost applies regardless of the payment method chosen.",
|
|
111
112
|
"addServicesTooltipHeading": "Included in the all-round care package:",
|
|
112
|
-
"addServicesTooltipItems": "complete registration service including a custom license plate, where available\ncareful review and preparation of all registration documents\nnationwide vehicle delivery to your doorstep\npersonal vehicle handover\nhigh-quality interior and exterior vehicle detailing\ndetailed technical handover check\nroadworthiness test (HU) and inspection, if required\nfuel or charge top-up at handover\npersonal point of contact from day one"
|
|
113
|
+
"addServicesTooltipItems": "complete registration service including a custom license plate, where available\ncareful review and preparation of all registration documents\nnationwide vehicle delivery to your doorstep\npersonal vehicle handover\nhigh-quality interior and exterior vehicle detailing\ndetailed technical handover check\nroadworthiness test (HU) and inspection, if required\nfuel or charge top-up at handover\npersonal point of contact from day one",
|
|
114
|
+
"addServicesTooltipOutroFinancing": "You can either pay the package cost as a one-off amount of €1,499.00, or have it included in the vehicle financing. If included in financing, no separate one-off payment for the package is charged. The payment method you choose, along with the resulting monthly financing rate and total amount, is shown in the financing details. The package cost is included in the total amount shown in either case.",
|
|
115
|
+
"addServicesTooltipOutroLeasing": "You can either pay the package cost as a one-off amount of €1,499.00, or have it included in the monthly leasing rate. If included in the rate, no separate one-off payment for the package is charged. The payment method you choose, along with the resulting monthly rate and total amount, is shown in the leasing details. The package cost is included in the total amount shown in either case."
|
|
113
116
|
},
|
|
114
117
|
"specTable": {
|
|
115
118
|
"title": "Vehicle data",
|
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.83",
|
|
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
|
@@ -4447,7 +4447,18 @@ line-height: 31px;
|
|
|
4447
4447
|
.md3 .listcard-price .pricepaths .pp-hero-terms { font-size: 10.5px; }
|
|
4448
4448
|
/* "Details" link at the end of the financing/leasing terms lines (Figma "mcard") — quiet, same
|
|
4449
4449
|
color as the rest of the terms line but underlined so it still reads as tappable. */
|
|
4450
|
-
.md3 .pp-details-link {
|
|
4450
|
+
.md3 .pp-details-link {
|
|
4451
|
+
border: 0;
|
|
4452
|
+
background: none;
|
|
4453
|
+
padding: 0;
|
|
4454
|
+
margin: 0;
|
|
4455
|
+
font: inherit;
|
|
4456
|
+
color: var(--md-primary);
|
|
4457
|
+
text-decoration: underline;
|
|
4458
|
+
font-weight: 600;
|
|
4459
|
+
white-space: nowrap;
|
|
4460
|
+
cursor: pointer;
|
|
4461
|
+
}
|
|
4451
4462
|
/* z.B./old-rate/unit column beside the CarCard hero figure — mirrors .fin-rate-unit
|
|
4452
4463
|
(FinanceCalculator.tsx/md3.css) exactly; only used inside .cc-price's PriceHero. */
|
|
4453
4464
|
.md3 .pp-hero-unit-group {
|
|
@@ -7184,13 +7195,21 @@ color: #005CFF;
|
|
|
7184
7195
|
width: auto;
|
|
7185
7196
|
z-index: 20;
|
|
7186
7197
|
margin-bottom: 10px;
|
|
7187
|
-
max-height: 260px;
|
|
7188
7198
|
cursor: default;
|
|
7189
7199
|
}
|
|
7190
7200
|
.md3 .fin-modal .fin-toggle-addservices--cash .fin-toggle-tooltip {
|
|
7191
7201
|
top: auto;
|
|
7192
7202
|
bottom: auto;
|
|
7193
7203
|
}
|
|
7204
|
+
.md3 .fin-modal .show-mobile .fin-toggle-tooltip {
|
|
7205
|
+
border-radius: 11px;
|
|
7206
|
+
}
|
|
7207
|
+
/* desktop (.hide-mobile) row sits close to the top of a short, non-scrolling card — opening
|
|
7208
|
+
upward has nowhere near enough room for the now-long financing/leasing copy (intro + 9
|
|
7209
|
+
bullets + outro). */
|
|
7210
|
+
.md3 .fin-modal .hide-mobile .fin-toggle-tooltip {
|
|
7211
|
+
bottom: auto;
|
|
7212
|
+
}
|
|
7194
7213
|
.md3 .fin-calc-card .fin-toggle-tooltip-close,
|
|
7195
7214
|
.md3 .fin-modal .fin-toggle-tooltip-close {
|
|
7196
7215
|
position: absolute;
|
|
@@ -261,11 +261,19 @@ export const ToggleRow: React.FunctionComponent<{
|
|
|
261
261
|
};
|
|
262
262
|
|
|
263
263
|
/** body content for the "Rundum-Sorglos-Paket" ToggleRow tooltip — intro sentence, bold heading,
|
|
264
|
-
*
|
|
265
|
-
*
|
|
266
|
-
|
|
264
|
+
* the package's contents as a bullet list, then (financing/leasing only) a closing paragraph
|
|
265
|
+
* explaining the one-off-vs-financed payment choice. Shared by every addServicesToggle
|
|
266
|
+
* ToggleRow (FinanceCalculator's own card + VdpModules' modal/mobile-sheet instances); intro/
|
|
267
|
+
* outro vary by mode since cash mode has no "financed into the rate" option. */
|
|
268
|
+
export const AddServicesTooltipBody: React.FunctionComponent<{ t: TranslationFunction; isCash?: boolean; isLease?: boolean }> = ({
|
|
269
|
+
t,
|
|
270
|
+
isCash,
|
|
271
|
+
isLease,
|
|
272
|
+
}) => (
|
|
267
273
|
<>
|
|
268
|
-
<p style={{ margin: '0 0 8px' }}>
|
|
274
|
+
<p style={{ margin: '0 0 8px' }}>
|
|
275
|
+
{t(isCash ? 'autobahn:finance.addServicesTooltipIntroCash' : 'autobahn:finance.addServicesTooltipIntroFinanced')}
|
|
276
|
+
</p>
|
|
269
277
|
<p style={{ fontFamily: 'Arial', fontWeight: 700, fontSize: 10, lineHeight: '13px', color: '#0E2238', margin: '0 0 4px' }}>
|
|
270
278
|
{t('autobahn:finance.addServicesTooltipHeading')}
|
|
271
279
|
</p>
|
|
@@ -276,6 +284,11 @@ export const AddServicesTooltipBody: React.FunctionComponent<{ t: TranslationFun
|
|
|
276
284
|
<li key={item}>{item}</li>
|
|
277
285
|
))}
|
|
278
286
|
</ul>
|
|
287
|
+
{!isCash && (
|
|
288
|
+
<p style={{ margin: '8px 0 0' }}>
|
|
289
|
+
{t(isLease ? 'autobahn:finance.addServicesTooltipOutroLeasing' : 'autobahn:finance.addServicesTooltipOutroFinancing')}
|
|
290
|
+
</p>
|
|
291
|
+
)}
|
|
279
292
|
</>
|
|
280
293
|
);
|
|
281
294
|
|
|
@@ -826,7 +839,7 @@ const FinanceCalculator: React.FunctionComponent<FinanceCalculatorProps> = ({
|
|
|
826
839
|
disabled={addServicesDisabled}
|
|
827
840
|
onChange={onToggleAddServices}
|
|
828
841
|
staticNote={t('autobahn:finance.addServicesIncluded')}
|
|
829
|
-
tooltip={<AddServicesTooltipBody t={t} />}
|
|
842
|
+
tooltip={<AddServicesTooltipBody t={t} isCash />}
|
|
830
843
|
tooltipCloseLabel={t('autobahn:modal.close')}
|
|
831
844
|
/>
|
|
832
845
|
)}
|
|
@@ -891,7 +904,7 @@ const FinanceCalculator: React.FunctionComponent<FinanceCalculatorProps> = ({
|
|
|
891
904
|
checked={!!withAddServices}
|
|
892
905
|
disabled={addServicesDisabled}
|
|
893
906
|
onChange={onToggleAddServices}
|
|
894
|
-
tooltip={<AddServicesTooltipBody t={t} />}
|
|
907
|
+
tooltip={<AddServicesTooltipBody t={t} isLease={isLease} />}
|
|
895
908
|
tooltipCloseLabel={t('autobahn:modal.close')}
|
|
896
909
|
/>
|
|
897
910
|
)}
|
package/vdp/VdpModules.tsx
CHANGED
|
@@ -1967,8 +1967,10 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
|
|
|
1967
1967
|
const [uvpTooltipOpen, setUvpTooltipOpen] = React.useState(false);
|
|
1968
1968
|
// opened directly via the "Finanzierungsdetails" link (initialShowBreakdown) — on mobile the
|
|
1969
1969
|
// breakdown is still gated behind its own toggle, so scroll the sheet down to reveal it instead
|
|
1970
|
-
// of leaving the user at the top. Desktop always shows the breakdown inline
|
|
1971
|
-
//
|
|
1970
|
+
// of leaving the user at the top. Desktop always shows the breakdown inline (no toggle), but it
|
|
1971
|
+
// can still sit below the fold inside .fin-modal-body's own scroll area, so it gets the same
|
|
1972
|
+
// treatment — whichever of the two refs is actually visible (show-mobile/hide-mobile via CSS)
|
|
1973
|
+
// is the one scrolled.
|
|
1972
1974
|
const desktopBreakdownRef = React.useRef<HTMLDivElement | null>(null);
|
|
1973
1975
|
const mobileBreakdownRef = React.useRef<HTMLDivElement | null>(null);
|
|
1974
1976
|
React.useEffect(() => {
|
|
@@ -1976,8 +1978,8 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
|
|
|
1976
1978
|
setShowBreakdown(!!initialShowBreakdown);
|
|
1977
1979
|
if (!initialShowBreakdown) return;
|
|
1978
1980
|
const timer = window.setTimeout(() => {
|
|
1979
|
-
const target = mobileBreakdownRef.current;
|
|
1980
|
-
if (target
|
|
1981
|
+
const target = [mobileBreakdownRef.current, desktopBreakdownRef.current].find((el) => el && el.offsetParent !== null);
|
|
1982
|
+
if (target) target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
|
1981
1983
|
}, 50);
|
|
1982
1984
|
return () => window.clearTimeout(timer);
|
|
1983
1985
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -2429,7 +2431,7 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
|
|
|
2429
2431
|
checked={!!withAddServices}
|
|
2430
2432
|
disabled={addServicesDisabled}
|
|
2431
2433
|
onChange={onToggleAddServices}
|
|
2432
|
-
tooltip={<AddServicesTooltipBody t={t} />}
|
|
2434
|
+
tooltip={<AddServicesTooltipBody t={t} isLease={isLease} />}
|
|
2433
2435
|
tooltipCloseLabel={t('autobahn:modal.close')}
|
|
2434
2436
|
/>
|
|
2435
2437
|
)}
|
|
@@ -2917,7 +2919,7 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
|
|
|
2917
2919
|
disabled={addServicesDisabled}
|
|
2918
2920
|
onChange={(checked) => onToggleAddServices && onToggleAddServices(checked)}
|
|
2919
2921
|
staticNote={t('autobahn:finance.addServicesIncluded')}
|
|
2920
|
-
tooltip={<AddServicesTooltipBody t={t} />}
|
|
2922
|
+
tooltip={<AddServicesTooltipBody t={t} isCash />}
|
|
2921
2923
|
tooltipCloseLabel={t('autobahn:modal.close')}
|
|
2922
2924
|
/>
|
|
2923
2925
|
)}
|
|
@@ -3053,7 +3055,7 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
|
|
|
3053
3055
|
checked={!!withAddServices}
|
|
3054
3056
|
disabled={addServicesDisabled}
|
|
3055
3057
|
onChange={onToggleAddServices}
|
|
3056
|
-
tooltip={<AddServicesTooltipBody t={t} />}
|
|
3058
|
+
tooltip={<AddServicesTooltipBody t={t} isLease={isLease} />}
|
|
3057
3059
|
tooltipCloseLabel={t('autobahn:modal.close')}
|
|
3058
3060
|
/>
|
|
3059
3061
|
)}
|