@bytebrand/fe-ui-core-autobahn 1.0.137 → 1.0.139

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/constants/app.ts CHANGED
@@ -40,7 +40,17 @@ export const LOCAL_STORAGE_KEY = {
40
40
  i18n_KEY: 'i18nLanguage'
41
41
  };
42
42
 
43
- export const DEFAULT_LANG: string = typeof window !== 'undefined' ? localStorage.getItem(LOCAL_STORAGE_KEY.i18n_KEY) : 'de';
43
+ // ADV-284: evaluated at import time — with site storage blocked, reading localStorage throws a
44
+ // SecurityError that took down the whole bundle. Blocked storage behaves like "nothing saved".
45
+ const readStoredLang = (): string | null => {
46
+ try {
47
+ return localStorage.getItem(LOCAL_STORAGE_KEY.i18n_KEY);
48
+ } catch (e) {
49
+ return null;
50
+ }
51
+ };
52
+
53
+ export const DEFAULT_LANG: string = typeof window !== 'undefined' ? readStoredLang() : 'de';
44
54
 
45
55
  // Default support contact phone
46
56
  export const CONTACT_PHONE: string = '+498004030182';
package/constants/core.ts CHANGED
@@ -35,7 +35,18 @@ export const LOCAL_STORAGE_KEY = {
35
35
  i18n_KEY: 'i18nLanguage'
36
36
  };
37
37
 
38
- export const DEFAULT_LANG: string = (typeof window !== 'undefined' ? window.localStorage.getItem(LOCAL_STORAGE_KEY.i18n_KEY) : null) ?? 'de';
38
+ // ADV-284: evaluated at import time — with site storage blocked, merely reading
39
+ // window.localStorage throws a SecurityError, which took down the whole bundle (landing
40
+ // page never rendered). Treat blocked storage like "no language saved".
41
+ const readStoredLang = (): string | null => {
42
+ try {
43
+ return typeof window !== 'undefined' ? window.localStorage.getItem(LOCAL_STORAGE_KEY.i18n_KEY) : null;
44
+ } catch (e) {
45
+ return null;
46
+ }
47
+ };
48
+
49
+ export const DEFAULT_LANG: string = readStoredLang() ?? 'de';
39
50
 
40
51
  export const ROW_STYLES = {
41
52
  marginBottom: 10
package/package.json CHANGED
@@ -1,30 +1,30 @@
1
- {
2
- "name": "@bytebrand/fe-ui-core-autobahn",
3
- "version": "1.0.137",
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
- "main": "index.ts",
6
- "license": "UNLICENSED",
7
- "peerDependencies": {
8
- "react": "^18.0.0",
9
- "react-dom": "^18.0.0"
10
- },
11
- "dependencies": {
12
- "@bytebrand/car-schema-selectors": "^2.0.7",
13
- "@bytebrand/fe-financing": "^5.14.20",
14
- "classnames": "2.2.6",
15
- "clsx": "^2.1.1",
16
- "d3-format": "1.4.5",
17
- "js-cookie": "^2.2.0",
18
- "lodash": "^4.17.21",
19
- "lucide-react": "^0.288.0",
20
- "mobx-react": "^7.6.0",
21
- "moment": "^2.29.1",
22
- "qs": "^6.6.0",
23
- "react-device-detect": "^2.1.2",
24
- "react-grid-system": "^5.0.2",
25
- "react-lazyload": "^3.2.0",
26
- "react-scroll": "^1.9.3",
27
- "react-slick": "^0.29.0",
28
- "slick-carousel": "1.8.1"
29
- }
30
- }
1
+ {
2
+ "name": "@bytebrand/fe-ui-core-autobahn",
3
+ "version": "1.0.139",
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
+ "main": "index.ts",
6
+ "license": "UNLICENSED",
7
+ "peerDependencies": {
8
+ "react": "^18.0.0",
9
+ "react-dom": "^18.0.0"
10
+ },
11
+ "dependencies": {
12
+ "@bytebrand/car-schema-selectors": "^2.0.7",
13
+ "@bytebrand/fe-financing": "^5.14.20",
14
+ "classnames": "2.2.6",
15
+ "clsx": "^2.1.1",
16
+ "d3-format": "1.4.5",
17
+ "js-cookie": "^2.2.0",
18
+ "lodash": "^4.17.21",
19
+ "lucide-react": "^0.288.0",
20
+ "mobx-react": "^7.6.0",
21
+ "moment": "^2.29.1",
22
+ "qs": "^6.6.0",
23
+ "react-device-detect": "^2.1.2",
24
+ "react-grid-system": "^5.0.2",
25
+ "react-lazyload": "^3.2.0",
26
+ "react-scroll": "^1.9.3",
27
+ "react-slick": "^0.29.0",
28
+ "slick-carousel": "1.8.1"
29
+ }
30
+ }
@@ -2241,18 +2241,31 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
2241
2241
  }, [open, initialShowBreakdown]);
2242
2242
  // in-sheet "Finanzierungs-/Leasingdetails" toggle (mobile): expanding the breakdown alone left
2243
2243
  // it below the fold — scroll the sheet body all the way down (same end state as opening via
2244
- // the page's details link). Waits out .fin-modal--expanded's 0.35s min-height transition: a
2245
- // smooth scroll started while the sheet is still growing gets cut short after a few px.
2246
- // Collapsing doesn't scroll.
2244
+ // the page's details link) in one quick ~300ms ease-out. The click also skips
2245
+ // .fin-modal--expanded's 0.35s min-height transition (see the toggle's onClick): a scroll
2246
+ // running while the sheet is still growing gets clamped/retargeted every frame and stutters.
2247
+ // Hand-rolled rAF instead of scrollTo({behavior:'smooth'}) so the duration is ours, not the
2248
+ // browser's. Collapsing doesn't scroll.
2247
2249
  const revealBreakdownRef = React.useRef(false);
2248
2250
  React.useEffect(() => {
2249
2251
  if (!showBreakdown || !revealBreakdownRef.current) return;
2250
2252
  revealBreakdownRef.current = false;
2251
- const timer = window.setTimeout(() => {
2252
- const body = mobileBreakdownRef.current?.closest('.fin-modal-body') as HTMLElement | null | undefined;
2253
- if (body) body.scrollTo({ top: body.scrollHeight, behavior: 'smooth' });
2254
- }, 400);
2255
- return () => window.clearTimeout(timer);
2253
+ const body = mobileBreakdownRef.current?.closest('.fin-modal-body') as HTMLElement | null | undefined;
2254
+ if (!body) return;
2255
+ const from = body.scrollTop;
2256
+ const dist = body.scrollHeight - body.clientHeight - from;
2257
+ if (dist <= 0) return;
2258
+ const duration = 300;
2259
+ let start: number | null = null;
2260
+ let raf = 0;
2261
+ const step = (now: number): void => {
2262
+ if (start === null) start = now;
2263
+ const p = Math.min(1, (now - start) / duration);
2264
+ body.scrollTop = from + dist * (1 - Math.pow(1 - p, 3));
2265
+ if (p < 1) raf = window.requestAnimationFrame(step);
2266
+ };
2267
+ raf = window.requestAnimationFrame(step);
2268
+ return () => window.cancelAnimationFrame(raf);
2256
2269
  }, [showBreakdown]);
2257
2270
 
2258
2271
  // mobile-only: swipe-down-to-dismiss on the grabber/header (the mockup's drag handle).
@@ -3430,6 +3443,9 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
3430
3443
  type="button"
3431
3444
  onClick={() => {
3432
3445
  revealBreakdownRef.current = !showBreakdown;
3446
+ // expanding: grow the sheet to full height at once (no min-height
3447
+ // transition) so the scroll-down above runs on a settled layout
3448
+ if (!showBreakdown && sheetRef.current) sheetRef.current.style.transition = 'none';
3433
3449
  setShowBreakdown((v) => !v);
3434
3450
  }}
3435
3451
  style={{ ...expanderBtnStyle, justifyContent: 'center', padding: '2px 0 20px' }}>