@bytebrand/fe-ui-core-autobahn 1.0.25 → 1.0.27
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/locales/de/autobahn.json +1 -0
- package/locales/en/autobahn.json +707 -706
- package/package.json +1 -1
- package/theme/md3.css +27 -8
- package/vdp/FinanceCalculator.tsx +3 -1
- package/vdp/VdpModules.tsx +39 -17
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.27",
|
|
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
|
@@ -157,10 +157,11 @@
|
|
|
157
157
|
.md3 .listcard-chips .chip:hover { background: var(--md-surface); border-color: var(--md-outline-variant); }
|
|
158
158
|
/* VDP trust row (Sofort verfügbar/views/favorites/Geprüft) — mobile-only, so the figma
|
|
159
159
|
push-chip palette is used literally (light blue-gray fill, dark bold label). */
|
|
160
|
-
.md3 .vdp-trust-chip { display: inline-flex; align-items: center;
|
|
161
|
-
border-radius: 11px; font-size: 11px; font-weight: 700; line-height: 1; cursor: default;
|
|
162
|
-
background: #F5F7FA; color: #1D2A38; border: 1px solid #E5EAF0;
|
|
163
|
-
|
|
160
|
+
.md3 .vdp-trust-chip { display: inline-flex; align-items: center; justify-content: center; gap: 5px; height: 30px;
|
|
161
|
+
padding: 0 9px; border-radius: 11px; font-size: 11px; font-weight: 700; line-height: 1; cursor: default;
|
|
162
|
+
white-space: nowrap; background: #F5F7FA; color: #1D2A38; border: 1px solid #E5EAF0;
|
|
163
|
+
flex: 1 1 auto; /* the four chips stretch to fill the block width (mockup), min = natural width */ }
|
|
164
|
+
.md3 .vdp-trust-chip .lucide { width: 14px; height: 14px; flex: none; }
|
|
164
165
|
|
|
165
166
|
/* status / rating chip (no CTA) */
|
|
166
167
|
.md3 .statchip { display: inline-flex; align-items: center; gap: 5px; height: 24px; padding: 0 10px;
|
|
@@ -1316,7 +1317,7 @@
|
|
|
1316
1317
|
/* mobile-only "first screen": identity + trust row BEFORE the finance card, highlights/
|
|
1317
1318
|
condition tiles moved AFTER it (both split out of the desktop-only VdpHeaderCard,
|
|
1318
1319
|
which stays bundled inside .vdp-gallery, hidden on mobile via hide-mobile). */
|
|
1319
|
-
.md3 .vdp-header-summary { order: 2; padding: 0
|
|
1320
|
+
.md3 .vdp-header-summary { order: 2; padding: 0; margin-bottom: 4px; /* flush with the card edges so the trust chips span the same width */ }
|
|
1320
1321
|
.md3 .vdp-aside { order: 3; }
|
|
1321
1322
|
.md3 .vdp-header-extras { order: 4; margin-top: 16px; }
|
|
1322
1323
|
.md3 .vdp-details { order: 5; }
|
|
@@ -1389,7 +1390,7 @@
|
|
|
1389
1390
|
.md3 .vdp-header-summary .vdp-trim { display: none; }
|
|
1390
1391
|
.md3 .vdp-header-summary .vdp-meta { display: flex; flex-wrap: wrap; grid-template-columns: none; margin-top: 6px;
|
|
1391
1392
|
font-size: 13.5px; font-weight: 400; color: var(--md-on-surface-variant); }
|
|
1392
|
-
.md3 .vdp-header-summary .vdp-meta > span + span::before { content: ''; }
|
|
1393
|
+
.md3 .vdp-header-summary .vdp-meta > span + span::before { content: ''; margin: 0 8px; }
|
|
1393
1394
|
.md3 .vdp-header-summary .vdp-meta > span { overflow: visible; text-overflow: clip; }
|
|
1394
1395
|
.md3 .vdp-header-summary .vdp-meta .lucide { display: none; }
|
|
1395
1396
|
.md3 .vdp-header-summary .vdp-meta > span:nth-child(5) { display: none; }
|
|
@@ -1492,12 +1493,30 @@
|
|
|
1492
1493
|
.md3 .push-badge--discount { background: #E60000; color: #fff; }
|
|
1493
1494
|
.md3 .push-badge--down { background: #EAF2FF; color: #005CFF; border: 1px solid rgba(0,92,255,.05); }
|
|
1494
1495
|
|
|
1496
|
+
/* "Rate anpassen" sheet (mobile modal) — mockup slider rows: bordered current-value box
|
|
1497
|
+
above the slider; term chips as one flat row of plain numbers (no "Mon." suffix). */
|
|
1498
|
+
.md3 .fin-val-box { display: inline-block; border: 1px solid var(--md-outline-variant); border-radius: 7px;
|
|
1499
|
+
padding: 4px 9px; font-size: 12.5px; font-weight: 600; margin-bottom: 6px; background: var(--md-sc-lowest); }
|
|
1500
|
+
.md3 .fin-sheet-terms .term-chips { display: flex; flex-wrap: wrap; gap: 8px; }
|
|
1501
|
+
.md3 .fin-sheet-terms .term-chip { flex: 1 1 0; min-width: 46px; height: 40px; border-radius: 8px; padding: 0 2px; }
|
|
1502
|
+
.md3 .fin-sheet-terms .tc-unit { display: none; }
|
|
1503
|
+
/* mockup sliders show no min/max end labels — the boxed current value carries the figure */
|
|
1504
|
+
.md3 .fin-sheet-adjust .mslider + div { display: none; }
|
|
1505
|
+
|
|
1495
1506
|
@media (max-width: 600px) {
|
|
1496
|
-
/* full-bleed gallery: edge-to-edge, app-like
|
|
1497
|
-
|
|
1507
|
+
/* full-bleed gallery: edge-to-edge, app-like; mockup image band is short+wide (~390×222,
|
|
1508
|
+
not 4:3) so the whole finance card — incl. Rate anpassen — fits the first screen */
|
|
1509
|
+
.md3 .vdp-gallerybox { margin: 0 -24px; border-radius: 0; border: 0; box-shadow: none;
|
|
1510
|
+
height: 222px; aspect-ratio: auto; }
|
|
1511
|
+
/* controls row straddles the image's bottom edge (mockup), half-on half-off */
|
|
1512
|
+
.md3 .gallery-controls-row { margin-top: -17px; position: relative; z-index: 3; padding: 0 2px; }
|
|
1498
1513
|
/* the carousel's own overlay dots move into the below-image controls row (page-rendered;
|
|
1499
1514
|
the dots div carries an inline display:flex — hence !important) */
|
|
1500
1515
|
.md3 .vdp-gallerybox .cardcar-dots { display: none !important; }
|
|
1516
|
+
/* tighter stacked rhythm so title→chips→finance card land above the fold */
|
|
1517
|
+
.md3 .vdp-grid { gap: 14px; }
|
|
1518
|
+
.md3 .fin-tabs { margin-bottom: 12px; }
|
|
1519
|
+
.md3 .fin-info { margin-top: 10px; padding-top: 10px; }
|
|
1501
1520
|
/* mockup hero rate is a notch bigger on phone (inline style says 48 — hence !important) */
|
|
1502
1521
|
.md3 .fin-rate-main .num { font-size: 52px !important; letter-spacing: -1.5px !important; }
|
|
1503
1522
|
/* narrower rating column (figma bar is 115px) frees room for the bigger rate; let the
|
|
@@ -530,7 +530,9 @@ const FinanceCalculator: React.FunctionComponent<FinanceCalculatorProps> = ({
|
|
|
530
530
|
}}
|
|
531
531
|
>
|
|
532
532
|
<Icon name="info" size={18} color="var(--md-on-surface-variant)" style={{ flex: 'none' }} />
|
|
533
|
-
|
|
533
|
+
{/* no max-width: "Finanzierungsdetails" is one unbreakable word — capping the
|
|
534
|
+
span clipped it mid-word instead of wrapping */}
|
|
535
|
+
<span className="md-label-sm" style={{ lineHeight: 1.5 }}>
|
|
534
536
|
{mode === 'leasing' ? t('autobahn:finance.leasingDetails') : t('autobahn:finance.financingDetails')}
|
|
535
537
|
</span>
|
|
536
538
|
</button>
|
package/vdp/VdpModules.tsx
CHANGED
|
@@ -176,7 +176,7 @@ export interface VdpTrustRowProps {
|
|
|
176
176
|
* 130-point inspected, so this one is always shown, not conditional real data). */
|
|
177
177
|
export const VdpTrustRow: React.FunctionComponent<VdpTrustRowProps> = ({ available, viewCount, favCount, t }) => (
|
|
178
178
|
// one swipeable line (mockup), never a ragged second row
|
|
179
|
-
<div style={{ display: 'flex', flexWrap: 'nowrap', overflowX: 'auto', scrollbarWidth: 'none', alignItems: 'center', gap:
|
|
179
|
+
<div style={{ display: 'flex', flexWrap: 'nowrap', overflowX: 'auto', scrollbarWidth: 'none', alignItems: 'center', gap: 5, marginTop: 10 }}>
|
|
180
180
|
{available && (
|
|
181
181
|
<span className="vdp-trust-chip">
|
|
182
182
|
<Icon name="check" size={13} stroke={2.4} color="var(--md-good)" />
|
|
@@ -1011,7 +1011,10 @@ const ToggleRow: React.FunctionComponent<{
|
|
|
1011
1011
|
onChange: (checked: boolean) => void;
|
|
1012
1012
|
}> = ({ label, price, checked, disabled, onChange }) => (
|
|
1013
1013
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 10 }}>
|
|
1014
|
-
<span className="md-title-sm"
|
|
1014
|
+
<span className="md-title-sm" style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
|
|
1015
|
+
{label}
|
|
1016
|
+
<Icon name="info" size={13} color="var(--md-on-surface-variant)" />
|
|
1017
|
+
</span>
|
|
1015
1018
|
<div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
|
|
1016
1019
|
{price && (
|
|
1017
1020
|
<span className="num" style={{ fontWeight: 700, fontSize: 13.5 }}>
|
|
@@ -1028,6 +1031,8 @@ export interface FinanceDetailsModalProps {
|
|
|
1028
1031
|
open: boolean;
|
|
1029
1032
|
/** active payment mode — drives labels + which legal example shows. */
|
|
1030
1033
|
mode: 'fin' | 'leasing' | 'cash';
|
|
1034
|
+
/** car make+model — mobile sheet subtitle under the title (mockup). */
|
|
1035
|
+
vehicleName?: string;
|
|
1031
1036
|
price: number;
|
|
1032
1037
|
monthly: number;
|
|
1033
1038
|
apr: number;
|
|
@@ -1092,6 +1097,7 @@ export interface FinanceDetailsModalProps {
|
|
|
1092
1097
|
export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalProps> = ({
|
|
1093
1098
|
open,
|
|
1094
1099
|
mode,
|
|
1100
|
+
vehicleName,
|
|
1095
1101
|
price,
|
|
1096
1102
|
monthly,
|
|
1097
1103
|
apr,
|
|
@@ -1204,8 +1210,13 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
|
|
|
1204
1210
|
<h2 className="md-headline-sm hide-mobile" style={{ margin: 0 }}>
|
|
1205
1211
|
{title}
|
|
1206
1212
|
</h2>
|
|
1207
|
-
<h2 className="md-headline-sm show-mobile" style={{ margin: 0 }}>
|
|
1213
|
+
<h2 className="md-headline-sm show-mobile" style={{ margin: 0, flexDirection: 'column', alignItems: 'flex-start', gap: 2 }}>
|
|
1208
1214
|
{mobileTitle}
|
|
1215
|
+
{vehicleName && (
|
|
1216
|
+
<span className="md-label-sm" style={{ fontWeight: 400 }}>
|
|
1217
|
+
{vehicleName}
|
|
1218
|
+
</span>
|
|
1219
|
+
)}
|
|
1209
1220
|
</h2>
|
|
1210
1221
|
<button className="icon-btn" onClick={onClose} aria-label={t('autobahn:modal.close')}>
|
|
1211
1222
|
<Icon name="x" size={20} />
|
|
@@ -1356,20 +1367,25 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
|
|
|
1356
1367
|
<Button variant="filled" size="lg" icon="shield-check" style={{ flex: 1 }} onClick={onSecure}>
|
|
1357
1368
|
{t('autobahn:finance.secureOffer')}
|
|
1358
1369
|
</Button>
|
|
1359
|
-
|
|
1370
|
+
{/* padding:0 — mbtn--lg's 30px side padding left no room for the icon at width 52 */}
|
|
1371
|
+
<Button variant="outlined" size="lg" icon="phone" style={{ width: 52, flex: 'none', padding: 0, borderRadius: 12 }} onClick={onCall} />
|
|
1360
1372
|
</div>
|
|
1361
1373
|
</>
|
|
1362
1374
|
) : (
|
|
1363
1375
|
<>
|
|
1364
1376
|
{adjustable && (
|
|
1365
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
|
1377
|
+
<div className="fin-sheet-adjust" style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
|
|
1366
1378
|
<div>
|
|
1367
|
-
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 6 }}>
|
|
1368
|
-
<span className="md-title-sm"
|
|
1369
|
-
|
|
1379
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>
|
|
1380
|
+
<span className="md-title-sm" style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
|
|
1381
|
+
{t('autobahn:finance.downPaymentSliderLabel')}
|
|
1382
|
+
<Icon name="info" size={13} color="var(--md-on-surface-variant)" />
|
|
1383
|
+
</span>
|
|
1384
|
+
<span className="num" style={{ fontWeight: 700, color: 'var(--md-primary)' }}>
|
|
1370
1385
|
{eur(down)} €
|
|
1371
1386
|
</span>
|
|
1372
1387
|
</div>
|
|
1388
|
+
<span className="fin-val-box num">{eur(down)} €</span>
|
|
1373
1389
|
<Slider
|
|
1374
1390
|
min={downMin as number}
|
|
1375
1391
|
max={downMax as number}
|
|
@@ -1381,12 +1397,16 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
|
|
|
1381
1397
|
</div>
|
|
1382
1398
|
{isLease && annualMileage != null && onAnnualMileageChange && (
|
|
1383
1399
|
<div>
|
|
1384
|
-
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 6 }}>
|
|
1385
|
-
<span className="md-title-sm"
|
|
1386
|
-
|
|
1400
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 6 }}>
|
|
1401
|
+
<span className="md-title-sm" style={{ display: 'inline-flex', alignItems: 'center', gap: 5 }}>
|
|
1402
|
+
{t('autobahn:finance.annualMileageLabel')}
|
|
1403
|
+
<Icon name="info" size={13} color="var(--md-on-surface-variant)" />
|
|
1404
|
+
</span>
|
|
1405
|
+
<span className="num" style={{ fontWeight: 700, color: 'var(--md-primary)' }}>
|
|
1387
1406
|
{eur(annualMileage)} km
|
|
1388
1407
|
</span>
|
|
1389
1408
|
</div>
|
|
1409
|
+
<span className="fin-val-box num">{eur(annualMileage)} km</span>
|
|
1390
1410
|
<Slider
|
|
1391
1411
|
min={annualMileageMin}
|
|
1392
1412
|
max={annualMileageMax}
|
|
@@ -1397,9 +1417,10 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
|
|
|
1397
1417
|
/>
|
|
1398
1418
|
</div>
|
|
1399
1419
|
)}
|
|
1400
|
-
<div>
|
|
1401
|
-
<div className="md-title-sm" style={{ marginBottom: 8 }}>
|
|
1402
|
-
{t('autobahn:finance.
|
|
1420
|
+
<div className="fin-sheet-terms">
|
|
1421
|
+
<div className="md-title-sm" style={{ display: 'flex', alignItems: 'center', gap: 5, marginBottom: 8 }}>
|
|
1422
|
+
{t('autobahn:finance.termSelectionMonths')}
|
|
1423
|
+
<Icon name="info" size={13} color="var(--md-on-surface-variant)" />
|
|
1403
1424
|
</div>
|
|
1404
1425
|
<TermChips options={termVals} value={term} onChange={onTermChange as (n: number) => void} t={t} />
|
|
1405
1426
|
</div>
|
|
@@ -1427,15 +1448,16 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
|
|
|
1427
1448
|
<Button variant="filled" size="lg" icon="shield-check" style={{ flex: 1 }} onClick={onSecure}>
|
|
1428
1449
|
{t('autobahn:finance.requestRate')}
|
|
1429
1450
|
</Button>
|
|
1430
|
-
|
|
1451
|
+
{/* padding:0 — mbtn--lg's 30px side padding left no room for the icon at width 52 */}
|
|
1452
|
+
<Button variant="outlined" size="lg" icon="phone" style={{ width: 52, flex: 'none', padding: 0, borderRadius: 12 }} onClick={onCall} />
|
|
1431
1453
|
</div>
|
|
1432
1454
|
|
|
1433
|
-
|
|
1455
|
+
{/* centered ⓘ details toggle (mockup shows no chevron) */}
|
|
1456
|
+
<button type="button" onClick={() => setShowBreakdown((v) => !v)} style={{ ...expanderBtnStyle, justifyContent: 'center', padding: '2px 0' }}>
|
|
1434
1457
|
<span style={{ display: 'inline-flex', alignItems: 'center', gap: 7 }}>
|
|
1435
1458
|
<Icon name="info" size={16} color="var(--md-primary)" />
|
|
1436
1459
|
{isLease ? t('autobahn:modal.leasingDetails') : t('autobahn:modal.financingDetails')}
|
|
1437
1460
|
</span>
|
|
1438
|
-
<Icon name={showBreakdown ? 'chevron-up' : 'chevron-down'} size={18} color="var(--md-primary)" />
|
|
1439
1461
|
</button>
|
|
1440
1462
|
{showBreakdown && (
|
|
1441
1463
|
<div>
|