@bytebrand/fe-ui-core-autobahn 1.0.151 → 1.0.153

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/chrome/Footer.tsx CHANGED
@@ -86,6 +86,14 @@ export interface FooterProps {
86
86
  * (VehicleDetailedNextPage), never site-wide, since every other page shows only footnotes 1-4.
87
87
  */
88
88
  showCostFootnotes?: boolean;
89
+ /**
90
+ * Hides the brand blurb + "stay in contact"/social + 3 link columns block (the
91
+ * `.footer-grid`), leaving just the legal disclaimer and copyright/"Nach Oben" bar. Opt-in,
92
+ * off by default — every other caller keeps the full footer. Only CheckoutThankYouPage.tsx
93
+ * (checkout step 6 "Danke") uses this today: that page's own Figma reference (64637:37033)
94
+ * has just the compact legal/copyright strip, not the full site footer.
95
+ */
96
+ hideBrandColumns?: boolean;
89
97
  }
90
98
 
91
99
  /**
@@ -93,7 +101,7 @@ export interface FooterProps {
93
101
  * disclaimer block, and a copyright + "Nach Oben" bar. Pure/presentational MD3 chrome — renders
94
102
  * correctly only inside a `<div className="md3">` subtree (scoped theme at source/theme/autobahn).
95
103
  */
96
- const Footer: React.FunctionComponent<FooterProps> = ({ t, showCostFootnotes }) => {
104
+ const Footer: React.FunctionComponent<FooterProps> = ({ t, showCostFootnotes, hideBrandColumns }) => {
97
105
  const scrollTop = (): void => window.scroll({ top: 0, left: 0, behavior: 'smooth' });
98
106
  const now = new Date();
99
107
  const year = now.getFullYear();
@@ -104,6 +112,7 @@ const Footer: React.FunctionComponent<FooterProps> = ({ t, showCostFootnotes })
104
112
 
105
113
  return (
106
114
  <footer style={{ background: 'var(--md-sc-low)', borderTop: '1px solid var(--md-outline-variant)' }}>
115
+ {!hideBrandColumns ? (
107
116
  <div className="container footer-grid" style={{ padding: '40px 24px 24px' }}>
108
117
  <div>
109
118
  <img src={logoUrl} height="30" alt="auto.de" />
@@ -169,10 +178,14 @@ const Footer: React.FunctionComponent<FooterProps> = ({ t, showCostFootnotes })
169
178
  </div>
170
179
  ))}
171
180
  </div>
181
+ ) : null}
172
182
 
173
183
  {/* Legally required disclaimers (PAngV §17a financing example w/ live APR/nominal rate +
174
- term, DAT CO₂-Leitfaden, MwSt, Streichpreis, image notice). Same text as the legacy footer. */}
175
- <div style={{ borderTop: '1px solid var(--md-outline-variant)' }}>
184
+ term, DAT CO₂-Leitfaden, MwSt, Streichpreis, image notice). Same text as the legacy footer.
185
+ The top border separates this from .footer-grid above — with hideBrandColumns that
186
+ block is gone, so the border would just double up against whatever's already directly
187
+ above the footer on the page (CheckoutThankYouPage.tsx's own header border). */}
188
+ <div style={hideBrandColumns ? undefined : { borderTop: '1px solid var(--md-outline-variant)' }}>
176
189
  <div className="container" style={{ padding: '18px 24px' }}>
177
190
  <p
178
191
  className="md-label-sm"
@@ -8,6 +8,7 @@ import * as React from 'react';
8
8
  import classnames from 'classnames';
9
9
 
10
10
  import Icon from '../../ui/Icon';
11
+ import MfieldCheckIcon from '../../ui/MfieldCheckIcon';
11
12
 
12
13
  export interface MdFieldProps {
13
14
  className?: string;
@@ -32,12 +33,21 @@ export interface MdFieldProps {
32
33
  * when empty and unfocused, then floats up to the normal small-label spot on focus
33
34
  * or once a value is typed. Defaults to false — the static above-field label. */
34
35
  floatingLabel?: boolean;
36
+ /** opt-in: show a green check + green border when the field is filled and valid (checkout).
37
+ * Same contract/markup as FormField's own showValid (.mfield--valid/.mfield-ok, md3.css). */
38
+ showValid?: boolean;
35
39
  onChange: (value: string, name?: string, event?: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => void;
40
+ /** fires after the field's own internal blur handling (floating-label state). Callers use
41
+ * this to trigger `field.validate()` (mobx-react-form) on blur — this component only owns
42
+ * the `error` prop's display, not when validation actually runs, so without a caller wiring
43
+ * this in, `field.error` never populates from blur and a required-but-empty field never
44
+ * shows its error text/red border until some other validate() call happens to run. */
45
+ onBlur?: () => void;
36
46
  }
37
47
 
38
48
  const MdField: React.FunctionComponent<MdFieldProps> = ({
39
49
  className, error, sx, required, disabled, multiline, autoComplete,
40
- value, type, name, rows, label, placeholder, floatingLabel, maxLength, onChange
50
+ value, type, name, rows, label, placeholder, floatingLabel, maxLength, showValid, onChange, onBlur
41
51
  }) => {
42
52
  const [reveal, setReveal] = React.useState(false);
43
53
  const [focused, setFocused] = React.useState(false);
@@ -54,6 +64,7 @@ const MdField: React.FunctionComponent<MdFieldProps> = ({
54
64
  // a value is typed, the real <label> appears in its normal static spot above the
55
65
  // field and the native placeholder goes quiet — the two never show at the same time.
56
66
  const hasValue = value != null && value !== '';
67
+ const isValid = !!showValid && !disabled && !isPassword && !hasError && hasValue;
57
68
  const resting = !!floatingLabel && !focused && !hasValue;
58
69
  const effectivePlaceholder = floatingLabel ? (resting ? (label || placeholder || '') : '') : (placeholder || '');
59
70
  // The real <label> is skipped entirely while resting (see above), leaving the input with
@@ -71,7 +82,9 @@ const MdField: React.FunctionComponent<MdFieldProps> = ({
71
82
 
72
83
  return (
73
84
  <div className={classnames('mfield-group', className)} style={sx as React.CSSProperties}>
74
- {label && !resting ? (
85
+ {/* Non-floating fields (FormField's own call sites don't set floatingLabel) keep the
86
+ plain label-above-the-box row — unchanged, still a .mfield-group flex child. */}
87
+ {label && !resting && !floatingLabel ? (
75
88
  <label className='md-label-sm mfield-label' htmlFor={generatedId}>
76
89
  {label}{required ? ' *' : ''}
77
90
  </label>
@@ -87,8 +100,18 @@ const MdField: React.FunctionComponent<MdFieldProps> = ({
87
100
  + (hasError ? ' mfield--error' : '')
88
101
  + (disabled ? ' mfield--disabled' : '')
89
102
  + (floatingLabel ? ' mfield--floating' : '')
103
+ + (isValid ? ' mfield--valid' : '')
90
104
  }
91
105
  >
106
+ {/* floatingLabel + floated (focused or has a value): the Material "notched outline"
107
+ treatment — label sits ON the border line, not stacked above it in its own row.
108
+ Lives INSIDE .mfield (not .mfield-group) so it can position against .mfield's own
109
+ edge (.mfield is position:relative already, md3.css) via .mfield-label--notch. */}
110
+ {label && !resting && floatingLabel ? (
111
+ <label className='md-label-sm mfield-label mfield-label--notch' htmlFor={generatedId}>
112
+ {label}{required ? ' *' : ''}
113
+ </label>
114
+ ) : null}
92
115
  {multiline ? (
93
116
  <textarea
94
117
  id={generatedId}
@@ -96,7 +119,7 @@ const MdField: React.FunctionComponent<MdFieldProps> = ({
96
119
  value={value == null ? '' : value}
97
120
  onChange={handleChange}
98
121
  onFocus={() => setFocused(true)}
99
- onBlur={() => setFocused(false)}
122
+ onBlur={() => { setFocused(false); onBlur?.(); }}
100
123
  disabled={disabled}
101
124
  rows={rows || 3}
102
125
  maxLength={maxLength}
@@ -115,7 +138,7 @@ const MdField: React.FunctionComponent<MdFieldProps> = ({
115
138
  value={value == null ? '' : value}
116
139
  onChange={handleChange}
117
140
  onFocus={() => setFocused(true)}
118
- onBlur={() => setFocused(false)}
141
+ onBlur={() => { setFocused(false); onBlur?.(); }}
119
142
  disabled={disabled}
120
143
  maxLength={maxLength}
121
144
  placeholder={effectivePlaceholder}
@@ -137,6 +160,7 @@ const MdField: React.FunctionComponent<MdFieldProps> = ({
137
160
  <Icon name={reveal ? 'eye-off' : 'eye'} size={18} />
138
161
  </button>
139
162
  ) : null}
163
+ {isValid ? <span className="mfield-ok"><MfieldCheckIcon /></span> : null}
140
164
  </div>
141
165
  {hasError ? (
142
166
  // role="alert" announces this to screen readers the moment it enters the DOM (e.g.
@@ -67,6 +67,7 @@
67
67
  "finance": {
68
68
  "termSelection": "Laufzeit",
69
69
  "termSelectionMonths": "Laufzeit (Monate)",
70
+ "change": "Ändern",
70
71
  "headerTitle": "Dein Angebot",
71
72
  "adjustRate": "Rate anpassen",
72
73
  "secureOffer": "Angebot anfragen",
@@ -700,7 +701,7 @@
700
701
  },
701
702
  "modal": {
702
703
  "leasingDetails": "Leasingdetails",
703
- "financingDetails": "Finanzierungs-Details",
704
+ "financingDetails": "Details",
704
705
  "close": "Schließen",
705
706
  "vehiclePrice": "Fahrzeugpreis ggf. inkl. MwSt.",
706
707
  "leasingAmount": "Leasingbetrag",
@@ -67,6 +67,7 @@
67
67
  "finance": {
68
68
  "termSelection": "Term",
69
69
  "termSelectionMonths": "Term (months)",
70
+ "change": "Change",
70
71
  "headerTitle": "Your offer",
71
72
  "adjustRate": "Adjust rate",
72
73
  "secureOffer": "Request offer",
package/package.json CHANGED
@@ -1,30 +1,30 @@
1
- {
2
- "name": "@bytebrand/fe-ui-core-autobahn",
3
- "version": "1.0.151",
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.153",
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
+ }