@bytebrand/fe-ui-core-autobahn 1.0.138 → 1.0.140

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,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytebrand/fe-ui-core-autobahn",
3
- "version": "1.0.138",
3
+ "version": "1.0.140",
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",
@@ -2240,28 +2240,29 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
2240
2240
  // eslint-disable-next-line react-hooks/exhaustive-deps
2241
2241
  }, [open, initialShowBreakdown]);
2242
2242
  // in-sheet "Finanzierungs-/Leasingdetails" toggle (mobile): expanding the breakdown alone left
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) 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.
2243
+ // it below the fold — scroll the sheet body so the "Repräsentatives Beispiel" headline lands at
2244
+ // the top of the body (not all the way down: that hid the headline and overshot). Runs
2245
+ // alongside .fin-modal--expanded's own 0.35s min-height transition instead of waiting it out
2246
+ // or disabling it: the target is re-read every frame and clamped to the current max scroll,
2247
+ // so the growing sheet and the scroll finish together in one motion. Hand-rolled rAF instead
2248
+ // of scrollTo({behavior:'smooth'}) so the duration is ours. Collapsing doesn't scroll.
2249
2249
  const revealBreakdownRef = React.useRef(false);
2250
2250
  React.useEffect(() => {
2251
2251
  if (!showBreakdown || !revealBreakdownRef.current) return;
2252
2252
  revealBreakdownRef.current = false;
2253
- const body = mobileBreakdownRef.current?.closest('.fin-modal-body') as HTMLElement | null | undefined;
2254
- if (!body) return;
2253
+ const el = mobileBreakdownRef.current;
2254
+ const body = el?.closest('.fin-modal-body') as HTMLElement | null | undefined;
2255
+ if (!el || !body) return;
2255
2256
  const from = body.scrollTop;
2256
- const dist = body.scrollHeight - body.clientHeight - from;
2257
- if (dist <= 0) return;
2258
- const duration = 300;
2257
+ const duration = 400;
2259
2258
  let start: number | null = null;
2260
2259
  let raf = 0;
2261
2260
  const step = (now: number): void => {
2262
2261
  if (start === null) start = now;
2263
2262
  const p = Math.min(1, (now - start) / duration);
2264
- body.scrollTop = from + dist * (1 - Math.pow(1 - p, 3));
2263
+ const headlineTop = el.getBoundingClientRect().top - body.getBoundingClientRect().top + body.scrollTop;
2264
+ const to = Math.max(from, Math.min(headlineTop - 8, body.scrollHeight - body.clientHeight));
2265
+ body.scrollTop = from + (to - from) * (1 - Math.pow(1 - p, 3));
2265
2266
  if (p < 1) raf = window.requestAnimationFrame(step);
2266
2267
  };
2267
2268
  raf = window.requestAnimationFrame(step);
@@ -3443,9 +3444,6 @@ export const FinanceDetailsModal: React.FunctionComponent<FinanceDetailsModalPro
3443
3444
  type="button"
3444
3445
  onClick={() => {
3445
3446
  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';
3449
3447
  setShowBreakdown((v) => !v);
3450
3448
  }}
3451
3449
  style={{ ...expanderBtnStyle, justifyContent: 'center', padding: '2px 0 20px' }}>