@bytebrand/fe-ui-core-autobahn 1.0.1 → 1.0.2
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/assets/autode-logo.svg +6 -6
- package/cards/CarCard.tsx +174 -174
- package/cards/CarRow.tsx +186 -182
- package/cards/cardParts.tsx +529 -489
- package/cards/index.ts +37 -35
- package/cards/types.ts +122 -114
- package/chrome/Footer.tsx +189 -189
- package/chrome/TopBar.tsx +405 -405
- package/chrome/index.ts +20 -20
- package/chrome/svg.d.ts +11 -11
- package/compat/AccardionSection/AccardionSection.styl +45 -45
- package/compat/AccardionSection/AccardionSection.tsx +56 -56
- package/compat/AccordionWidget/AccordionWidget.styl +220 -220
- package/compat/AccordionWidget/AccordionWidget.tsx +257 -257
- package/compat/AccordionWrapper/AccordionItem/AccordionItem.styl +34 -34
- package/compat/AccordionWrapper/AccordionItem/AccordionItem.tsx +64 -64
- package/compat/AccordionWrapper/AccordionWrapper.tsx +34 -34
- package/compat/AdvantageItem/AdvantageItem.styl +47 -47
- package/compat/AdvantageItem/AdvantageItem.tsx +26 -26
- package/compat/Alternative/DealerInfo.styl +116 -116
- package/compat/Alternative/DealerInfo.tsx +171 -171
- package/compat/Badge/Badge.styl +44 -44
- package/compat/Badge/Badge.tsx +25 -25
- package/compat/BodyTypeIcons/Audi.tsx +9 -9
- package/compat/BodyTypeIcons/Bmw.tsx +860 -860
- package/compat/BodyTypeIcons/Ford.tsx +31 -31
- package/compat/BodyTypeIcons/IconsConfig.tsx +44 -44
- package/compat/BodyTypeIcons/IconsConfigCompact.tsx +30 -30
- package/compat/BodyTypeIcons/Mazda.tsx +44 -44
- package/compat/BodyTypeIcons/MercedesBenz.tsx +38 -38
- package/compat/BodyTypeIcons/Opel.tsx +19 -19
- package/compat/BodyTypeIcons/Search.tsx +19 -19
- package/compat/BodyTypeIcons/SelectorCategoryCombi.tsx +68 -68
- package/compat/BodyTypeIcons/SelectorCategoryCompact.tsx +20 -20
- package/compat/BodyTypeIcons/SelectorCategoryConvertible.tsx +68 -68
- package/compat/BodyTypeIcons/SelectorCategoryCoupe.tsx +60 -60
- package/compat/BodyTypeIcons/SelectorCategoryMinibus.tsx +64 -64
- package/compat/BodyTypeIcons/SelectorCategorySedan.tsx +69 -69
- package/compat/BodyTypeIcons/SelectorCategorySuv.tsx +77 -77
- package/compat/BodyTypeIcons/SelectorCategoryTransporter.tsx +68 -68
- package/compat/BodyTypeIcons/SelectorCategoryVan.tsx +72 -72
- package/compat/BodyTypeIcons/Volkswagen.tsx +330 -330
- package/compat/BodyTypeIcons/index.ts +17 -17
- package/compat/Button/Button.tsx +65 -65
- package/compat/ButtonOld/Button.styl +65 -65
- package/compat/ButtonOld/Button.tsx +84 -84
- package/compat/Checkbox/Checkbox.styl +119 -119
- package/compat/Checkbox/Checkbox.tsx +151 -151
- package/compat/Checkbox/FormCheckbox.styl +22 -22
- package/compat/Checkbox/FormCheckbox.tsx +86 -86
- package/compat/Co2Widget/CO2Efficiency.styl +219 -219
- package/compat/Co2Widget/CO2Efficiency.tsx +93 -93
- package/compat/ContactInfo/ContactInfo.styl +22 -22
- package/compat/ContactInfo/ContactInfo.tsx +161 -161
- package/compat/ContactInfo/TemporaryTranslation.ts +11 -11
- package/compat/CookieModal/CookieModal.tsx +49 -49
- package/compat/CookieModal/Modal.tsx +43 -43
- package/compat/CookieModal/ModalsConfig.tsx +23 -23
- package/compat/CookieModal/modals/ManageCookieModal/ManageCookieModal.styl +86 -86
- package/compat/CookieModal/modals/ManageCookieModal/ManageCookieModal.tsx +184 -184
- package/compat/CookieModal/modals/PreviewCookieModal/PreviewCookieModal.styl +66 -66
- package/compat/CookieModal/modals/PreviewCookieModal/PreviewCookieModal.tsx +51 -51
- package/compat/CookieModal/modals/TestModal.tsx +7 -7
- package/compat/CookieModal/useModal.ts +13 -13
- package/compat/CustomerQuote/CustomerQuote.styl +79 -79
- package/compat/CustomerQuote/CustomerQuote.tsx +68 -68
- package/compat/CustomerQuotesSlider/CustomerQuotesSlider.styl +46 -46
- package/compat/CustomerQuotesSlider/CustomerQuotesSlider.tsx +79 -79
- package/compat/CustomerQuotesSlider/SliderArrow.tsx +20 -20
- package/compat/CustomerQuotesSlider/slider.global.styl +2 -2
- package/compat/ExpansionPanel/ExpansionPanel.tsx +68 -68
- package/compat/FirstInfoBlock/FirstInfoBlock.styl +33 -33
- package/compat/FirstInfoBlock/FirstInfoBlock.tsx +49 -49
- package/compat/FirstInfoBlock/FirstInfoBlockItem/FirstInfoBlockItem.styl +66 -66
- package/compat/FirstInfoBlock/FirstInfoBlockItem/FirstInfoBlockItem.tsx +21 -21
- package/compat/FormattedNumber/FormattedNumber.styl +1 -1
- package/compat/FormattedNumber/FormattedNumber.tsx +90 -90
- package/compat/IconContainer/IconContainer.styl +23 -23
- package/compat/IconContainer/IconContainer.tsx +34 -34
- package/compat/Image/Image.styl +109 -109
- package/compat/Image/Image.tsx +302 -302
- package/compat/ImageSettings/EditableOptionsTable/CustomCheckbox/CustomCheckbox.styl +7 -7
- package/compat/ImageSettings/EditableOptionsTable/CustomCheckbox/CustomCheckbox.tsx +30 -30
- package/compat/ImageSettings/EditableOptionsTable/EditableOptionsTable.styl +122 -122
- package/compat/ImageSettings/EditableOptionsTable/EditableOptionsTable.tsx +199 -199
- package/compat/ImageSettings/EditableOptionsTable/ImageIcon/ImageIcon.styl +3 -3
- package/compat/ImageSettings/EditableOptionsTable/ImageIcon/ImageIcon.tsx +15 -15
- package/compat/ImageSettings/OptionsTable/OptionsTable.styl +47 -47
- package/compat/ImageSettings/OptionsTable/OptionsTable.tsx +122 -122
- package/compat/ImageSettings/PricePlan/PricePlan.styl +63 -63
- package/compat/ImageSettings/PricePlan/PricePlan.tsx +32 -32
- package/compat/ImageSettings/index.ts +42 -42
- package/compat/ImagesSet/ImagesSet.styl +27 -27
- package/compat/ImagesSet/ImagesSet.tsx +76 -76
- package/compat/InfoBlockWrapper/InfoBlockWrapper.styl +41 -41
- package/compat/InfoBlockWrapper/InfoBlockWrapper.tsx +46 -46
- package/compat/Loader/Loader.styl +39 -39
- package/compat/Loader/Loader.tsx +32 -32
- package/compat/MagnifyGlass/MagnifyGlass.styl +33 -33
- package/compat/MagnifyGlass/MagnifyGlass.tsx +213 -213
- package/compat/MdAccordionGroup/MdAccordionGroup.tsx +53 -53
- package/compat/MdCheckbox/MdCheckbox.tsx +69 -69
- package/compat/MdField/MdField.tsx +100 -100
- package/compat/MdSelect/MdSelect.tsx +103 -103
- package/compat/MdSwitch/MdSwitch.tsx +29 -29
- package/compat/MdTabs/MdTabs.tsx +47 -47
- package/compat/MdTooltip/MdTooltip.tsx +31 -31
- package/compat/OfferDetailedSection/OfferDetailedSection.styl +31 -31
- package/compat/OfferDetailedSection/OfferDetailedSection.tsx +100 -100
- package/compat/OfferDetailedSection/partials/PanelConfig.styl +131 -131
- package/compat/OfferDetailedSection/partials/PanelConfig.tsx +121 -121
- package/compat/OfferPanel/AboAccordion/AboAccordion.styl +24 -24
- package/compat/OfferPanel/AboAccordion/AboAccordion.tsx +128 -128
- package/compat/OfferPanel/AboAccordion/AboColorOptions/AboColorOptions.styl +11 -11
- package/compat/OfferPanel/AboAccordion/AboColorOptions/AboColorOptions.tsx +35 -35
- package/compat/OfferPanel/AboAccordion/AboFaq/AboFaq.styl +20 -20
- package/compat/OfferPanel/AboAccordion/AboFaq/AboFaq.tsx +25 -25
- package/compat/OfferPanel/AboAccordion/AboIncludedServices/AboIncludedServices.styl +13 -13
- package/compat/OfferPanel/AboAccordion/AboIncludedServices/AboIncludedServices.tsx +39 -39
- package/compat/OfferPanel/MuiOfferPeriod/MuiOfferPeriod.tsx +42 -42
- package/compat/OfferPanel/OfferCheckboxGroup/CheckboxContainer.tsx +140 -140
- package/compat/OfferPanel/OfferCheckboxGroup/OfferCheckboxGroup.styl +144 -144
- package/compat/OfferPanel/OfferCheckboxGroup/OfferCheckboxGroup.tsx +23 -23
- package/compat/OfferPanel/OfferPanel.styl +193 -193
- package/compat/OfferPanel/OfferPanel.tsx +81 -81
- package/compat/OfferPanel/OfferPeriod/OfferPeriod.styl +24 -24
- package/compat/OfferPanel/OfferPeriod/OfferPeriod.tsx +45 -45
- package/compat/OfferPanel/RangeGroup/RangeGroup.tsx +39 -39
- package/compat/OfferRequestButtonWrapper/OfferRequestButtonWrapper.styl +119 -119
- package/compat/OfferRequestButtonWrapper/OfferRequestButtonWrapper.styled.tsx +33 -33
- package/compat/OfferRequestButtonWrapper/OfferRequestButtonWrapper.tsx +122 -122
- package/compat/PriceRating/PriceRating.styl +47 -47
- package/compat/PriceRating/PriceRating.tsx +64 -64
- package/compat/PriceRatingDetailed/PriceRatingDetailed.styl +120 -120
- package/compat/PriceRatingDetailed/PriceRatingDetailed.tsx +191 -191
- package/compat/PricingToolBlock/PricingTool.styl +6 -6
- package/compat/PricingToolBlock/PricingTool.tsx +29 -29
- package/compat/Radio/Radio.styl +115 -115
- package/compat/Radio/Radio.tsx +141 -141
- package/compat/Radio/RadioGroup.styl +5 -5
- package/compat/Radio/RadioGroup.tsx +65 -65
- package/compat/Range/Range.tsx +79 -79
- package/compat/RateSearchValue/RateSearchValue.styl +22 -22
- package/compat/RateSearchValue/RateSearchValue.tsx +55 -55
- package/compat/RateSearchWidget/RateSearchWidget.styl +106 -106
- package/compat/RateSearchWidget/RateSearchWidget.tsx +163 -163
- package/compat/ServiceBlockItem/ServiceBlockItem.styl +47 -47
- package/compat/ServiceBlockItem/ServiceBlockItem.tsx +25 -25
- package/compat/SkeletonItem/SkeletonItem.styl +80 -80
- package/compat/SkeletonItem/SkeletonItem.tsx +80 -80
- package/compat/StarButton/StarButton.styl +39 -39
- package/compat/StarButton/StarButton.tsx +31 -31
- package/compat/TabPanel/TabPanel.tsx +28 -28
- package/compat/TimePicker/TimePicker.styl +22 -22
- package/compat/TimePicker/TimePicker.tsx +156 -156
- package/compat/Tooltip/Tooltip.styl +117 -117
- package/compat/Tooltip/Tooltip.tsx +63 -63
- package/compat/Usp/Usp.styl +78 -78
- package/compat/Usp/Usp.tsx +30 -30
- package/compat/Usp/uspTranslate.ts +12 -12
- package/compat/VehicleDetailedSidebar/VehicleDetailedSidebar.styl +36 -36
- package/compat/VehicleDetailedSidebar/VehicleDetailedSidebar.tsx +178 -178
- package/compat/VehicleDetailedSidebar/partials/Price.styl +27 -27
- package/compat/VehicleDetailedSidebar/partials/Price.tsx +41 -41
- package/compat/VehicleDetailedSidebar/partials/PriceContent.styl +123 -123
- package/compat/VehicleDetailedSidebar/partials/PriceContent.tsx +128 -128
- package/compat/VehicleDetailedSidebar/partials/Properties.styl +58 -58
- package/compat/VehicleDetailedSidebar/partials/Properties.tsx +155 -155
- package/compat/VehicleDetailedSidebar/partials/Title.styl +35 -35
- package/compat/VehicleDetailedSidebar/partials/Title.tsx +33 -33
- package/compat/VehicleDetailedSlider/VehicleDetailedSlider.styl +146 -146
- package/compat/VehicleDetailedSlider/VehicleDetailedSlider.tsx +382 -382
- package/compat/VehicleDetailedSlider/partials/MobileStast.tsx +61 -61
- package/compat/VehicleDetailedSlider/partials/MobileStats.styl +71 -71
- package/compat/VehicleDetailedSlider/partials/PriceData.styl +50 -50
- package/compat/VehicleDetailedSlider/partials/PriceData.tsx +67 -67
- package/compat/VehicleDetailedSlider/partials/Stats.styl +80 -80
- package/compat/VehicleDetailedSlider/partials/Stats.tsx +62 -62
- package/compat/VehicleDetailedSlider/partials/Title.styl +44 -44
- package/compat/VehicleDetailedSlider/partials/Title.tsx +36 -36
- package/compat/VehicleFormattedPrice/VehicleFormattedPrice.styl +148 -148
- package/compat/VehicleFormattedPrice/VehicleFormattedPrice.tsx +163 -163
- package/compat/VehicleSlider/VehicleSlider.styl +62 -62
- package/compat/VehicleSlider/VehicleSlider.tsx +125 -125
- package/compat/VehicleSlider/VehicleSliderForSRL.tsx +175 -175
- package/compat/VehicleSmallCard/SeoText/SeoText.styl +8 -8
- package/compat/VehicleSmallCard/SeoText/SeoText.tsx +16 -16
- package/compat/VehicleSmallCard/VehicleData/VechiclePriceItem/VechiclePriceItem.styl +204 -204
- package/compat/VehicleSmallCard/VehicleData/VechiclePriceItem/VechiclePriceItem.tsx +199 -199
- package/compat/VehicleSmallCard/VehicleData/VehicleInfo/VehicleInfo.styl +273 -273
- package/compat/VehicleSmallCard/VehicleData/VehicleInfo/VehicleInfo.tsx +179 -179
- package/compat/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.styl +165 -165
- package/compat/VehicleSmallCard/VehicleData/VehiclePrice/VehiclePrice.tsx +299 -299
- package/compat/VehicleSmallCard/VehicleData/VehicleProperty/VehicleProperty.styl +32 -32
- package/compat/VehicleSmallCard/VehicleData/VehicleProperty/VehicleProperty.tsx +35 -35
- package/compat/VehicleSmallCard/VehicleData/VehicleTitle/VehicleTitle.styl +135 -135
- package/compat/VehicleSmallCard/VehicleData/VehicleTitle/VehicleTitle.tsx +91 -91
- package/compat/VehicleSmallCard/VehicleSmallCard.styl +309 -309
- package/compat/VehicleSmallCard/VehicleSmallCard.tsx +448 -448
- package/compat/index.ts +77 -77
- package/compat/legacy-theme/mixins.styl +93 -93
- package/compat/legacy-theme/priceReviewColors.styl +12 -12
- package/compat/legacy-theme/slider.global.styl +5 -5
- package/compat/legacy-theme/theme.styl +136 -136
- package/compat/withLabel/withLabel.styl +33 -33
- package/compat/withLabel/withLabel.tsx +44 -44
- package/compat/withStats/withStats.styl +174 -174
- package/compat/withStats/withStats.tsx +238 -238
- package/constants/RateSearchWidget.ts +15 -15
- package/constants/Search.ts +290 -290
- package/constants/SearchWidget.ts +108 -108
- package/constants/app.ts +223 -223
- package/constants/common.ts +127 -127
- package/constants/core.ts +131 -131
- package/constants/highlights.ts +165 -165
- package/constants/price.ts +9 -9
- package/constants/selectors.ts +38 -38
- package/constants.ts +91 -91
- package/data/DataTransformers.ts +88 -88
- package/data/fieldMapping.ts +364 -342
- package/data/toAutobahnCar.ts +455 -442
- package/iconsvg/IconSVG.tsx +30 -30
- package/iconsvg/IconSVGConfig.tsx +768 -768
- package/iconsvg/SVG/AboPartner.tsx +16 -16
- package/iconsvg/SVG/ArrowQuotes.tsx +22 -22
- package/iconsvg/SVG/CloseIcon.tsx +17 -17
- package/iconsvg/SVG/CloseIconSelect.tsx +18 -18
- package/iconsvg/SVG/ClosedLockIcon.tsx +18 -18
- package/iconsvg/SVG/DealerCheckIcon.tsx +18 -18
- package/iconsvg/SVG/DealerPopoverMail.tsx +21 -21
- package/iconsvg/SVG/DealerPopoverPhone.tsx +21 -21
- package/iconsvg/SVG/GrayPhoneIcon.tsx +22 -22
- package/iconsvg/SVG/InternetIcon.tsx +18 -18
- package/iconsvg/SVG/WhiteEnvelopeIcon.tsx +21 -21
- package/iconsvg/SVG/bodyType/Cabrio.tsx +23 -23
- package/iconsvg/SVG/bodyType/Coupe.tsx +22 -22
- package/iconsvg/SVG/bodyType/Minibus.tsx +22 -22
- package/iconsvg/SVG/bodyType/Other.tsx +25 -25
- package/iconsvg/SVG/bodyType/Sedan.tsx +22 -22
- package/iconsvg/SVG/bodyType/SelectorCategoryCombi.tsx +68 -68
- package/iconsvg/SVG/bodyType/SelectorCategoryCompact.tsx +20 -20
- package/iconsvg/SVG/bodyType/SelectorCategoryConvertible.tsx +68 -68
- package/iconsvg/SVG/bodyType/SelectorCategoryCoupe.tsx +60 -60
- package/iconsvg/SVG/bodyType/SelectorCategoryMinibus.tsx +64 -64
- package/iconsvg/SVG/bodyType/SelectorCategoryOther.tsx +60 -60
- package/iconsvg/SVG/bodyType/SelectorCategorySedan.tsx +69 -69
- package/iconsvg/SVG/bodyType/SelectorCategorySuv.tsx +77 -77
- package/iconsvg/SVG/bodyType/SelectorCategoryTransporter.tsx +68 -68
- package/iconsvg/SVG/bodyType/SelectorCategoryVan.tsx +72 -72
- package/iconsvg/SVG/bodyType/Small.tsx +23 -23
- package/iconsvg/SVG/bodyType/Suv.tsx +23 -23
- package/iconsvg/SVG/bodyType/Van.tsx +23 -23
- package/iconsvg/SVG/bodyType/Wagon.tsx +23 -23
- package/iconsvg/SVG/common/AddIcon.tsx +16 -16
- package/iconsvg/SVG/common/AddPlus.tsx +16 -16
- package/iconsvg/SVG/common/AddressDashboard.tsx +29 -29
- package/iconsvg/SVG/common/AddressIcon.tsx +20 -20
- package/iconsvg/SVG/common/ArrowDetailedAccordionBlue.tsx +26 -26
- package/iconsvg/SVG/common/ArrowDownBlue.tsx +21 -21
- package/iconsvg/SVG/common/ArrowSelect.tsx +23 -23
- package/iconsvg/SVG/common/ArrowStepDown.tsx +18 -18
- package/iconsvg/SVG/common/Autocheck.tsx +19 -19
- package/iconsvg/SVG/common/AutodeLogo.tsx +36 -36
- package/iconsvg/SVG/common/Avatar.tsx +17 -17
- package/iconsvg/SVG/common/BellGray.tsx +19 -19
- package/iconsvg/SVG/common/BigInfoTransparent.tsx +13 -13
- package/iconsvg/SVG/common/Browse.tsx +20 -20
- package/iconsvg/SVG/common/Calendar.tsx +24 -24
- package/iconsvg/SVG/common/CallbackDashboard.tsx +30 -30
- package/iconsvg/SVG/common/Camera.tsx +17 -17
- package/iconsvg/SVG/common/Car.tsx +16 -16
- package/iconsvg/SVG/common/CarBody.tsx +19 -19
- package/iconsvg/SVG/common/CarFront.tsx +43 -43
- package/iconsvg/SVG/common/CarInspectionCheck.tsx +21 -21
- package/iconsvg/SVG/common/CarInspectionScheme0.tsx +32 -32
- package/iconsvg/SVG/common/CarInspectionScheme1.tsx +53 -53
- package/iconsvg/SVG/common/CarInspectionScheme2.tsx +52 -52
- package/iconsvg/SVG/common/CarInspectionScheme3.tsx +32 -32
- package/iconsvg/SVG/common/CarInspectionScheme4.tsx +32 -32
- package/iconsvg/SVG/common/CarInspectionScheme5.tsx +32 -32
- package/iconsvg/SVG/common/CarInspectionScheme6.tsx +32 -32
- package/iconsvg/SVG/common/CarInspectionSchemeGeneral copy.tsx +24 -24
- package/iconsvg/SVG/common/CarInspectionSchemeGeneral.tsx +24 -24
- package/iconsvg/SVG/common/CheckBlue.tsx +18 -18
- package/iconsvg/SVG/common/CheckGreen.tsx +22 -22
- package/iconsvg/SVG/common/CheckMark.tsx +16 -16
- package/iconsvg/SVG/common/CheckWhite.tsx +19 -19
- package/iconsvg/SVG/common/Chevron.tsx +17 -17
- package/iconsvg/SVG/common/CircledCheckmark.tsx +25 -25
- package/iconsvg/SVG/common/Clock.tsx +18 -18
- package/iconsvg/SVG/common/Close.tsx +19 -19
- package/iconsvg/SVG/common/CloseGrey.tsx +22 -22
- package/iconsvg/SVG/common/ContactEmail.tsx +21 -21
- package/iconsvg/SVG/common/ContactPhone.tsx +28 -28
- package/iconsvg/SVG/common/CopyIcon copy.tsx +22 -22
- package/iconsvg/SVG/common/CopyIcon.tsx +22 -22
- package/iconsvg/SVG/common/CopyIconForDealer.tsx +21 -21
- package/iconsvg/SVG/common/DashboardIcon.tsx +20 -20
- package/iconsvg/SVG/common/DashboardQuestionMark.tsx +20 -20
- package/iconsvg/SVG/common/DealersIcon.tsx +20 -20
- package/iconsvg/SVG/common/DeleteCircle.tsx +31 -31
- package/iconsvg/SVG/common/DeleteV1Icon.tsx +18 -18
- package/iconsvg/SVG/common/DeliveryDashboard.tsx +25 -25
- package/iconsvg/SVG/common/DeliveryMail.tsx +24 -24
- package/iconsvg/SVG/common/Discount100De.tsx +18 -18
- package/iconsvg/SVG/common/Discount100En.tsx +19 -19
- package/iconsvg/SVG/common/Discount66De.tsx +28 -28
- package/iconsvg/SVG/common/Discount66En.tsx +20 -20
- package/iconsvg/SVG/common/DoneIcon.tsx +18 -18
- package/iconsvg/SVG/common/EditCircle.tsx +32 -32
- package/iconsvg/SVG/common/EditPriceIcon.tsx +20 -20
- package/iconsvg/SVG/common/EuroCurrency.tsx +18 -18
- package/iconsvg/SVG/common/Export.tsx +20 -20
- package/iconsvg/SVG/common/Eye.tsx +17 -17
- package/iconsvg/SVG/common/EyeCatch.tsx +19 -19
- package/iconsvg/SVG/common/FavoritesIcon.tsx +20 -20
- package/iconsvg/SVG/common/FilterRange.tsx +16 -16
- package/iconsvg/SVG/common/FilterToolBlack.tsx +23 -23
- package/iconsvg/SVG/common/FlagDe.tsx +21 -21
- package/iconsvg/SVG/common/FlagEn.tsx +43 -43
- package/iconsvg/SVG/common/GrayEnvelopeIcon.tsx +19 -19
- package/iconsvg/SVG/common/HamburgerMenuIcon.tsx +18 -18
- package/iconsvg/SVG/common/HandingOverDashboard.tsx +32 -32
- package/iconsvg/SVG/common/ImageSettingsIcon.tsx +20 -20
- package/iconsvg/SVG/common/Info.tsx +16 -16
- package/iconsvg/SVG/common/InfoIcon.tsx +17 -17
- package/iconsvg/SVG/common/InfoTransparent.tsx +18 -18
- package/iconsvg/SVG/common/LogoutIcon.tsx +20 -20
- package/iconsvg/SVG/common/MagnifyingGlass.tsx +31 -31
- package/iconsvg/SVG/common/MenuArrow.tsx +16 -16
- package/iconsvg/SVG/common/MenuGrey.tsx +22 -22
- package/iconsvg/SVG/common/MobileDeLogo.tsx +108 -108
- package/iconsvg/SVG/common/MyOrderIcon.tsx +20 -20
- package/iconsvg/SVG/common/MyVehiclesIcon.tsx +20 -20
- package/iconsvg/SVG/common/NewFlagDe.tsx +25 -25
- package/iconsvg/SVG/common/NewFlagEn.tsx +34 -34
- package/iconsvg/SVG/common/OrderReceivedDashboard.tsx +27 -27
- package/iconsvg/SVG/common/Package.tsx +30 -30
- package/iconsvg/SVG/common/Phone.tsx +18 -18
- package/iconsvg/SVG/common/PhoneGrey.tsx +22 -22
- package/iconsvg/SVG/common/PickupDashboard.tsx +30 -30
- package/iconsvg/SVG/common/Picture.tsx +24 -24
- package/iconsvg/SVG/common/Pictures.tsx +32 -32
- package/iconsvg/SVG/common/Plus.tsx +16 -16
- package/iconsvg/SVG/common/PlusNew.tsx +16 -16
- package/iconsvg/SVG/common/PreparationDashboard.tsx +29 -29
- package/iconsvg/SVG/common/ProfileDashboard.tsx +24 -24
- package/iconsvg/SVG/common/ProfileIcon.tsx +17 -17
- package/iconsvg/SVG/common/Question.tsx +19 -19
- package/iconsvg/SVG/common/QuestionBold.tsx +25 -25
- package/iconsvg/SVG/common/RegistrationDashboard.tsx +31 -31
- package/iconsvg/SVG/common/SavedSearchsIcon.tsx +20 -20
- package/iconsvg/SVG/common/Search.tsx +19 -19
- package/iconsvg/SVG/common/SearchGrey.tsx +22 -22
- package/iconsvg/SVG/common/SettingPenIcon.tsx +20 -20
- package/iconsvg/SVG/common/Share.tsx +16 -16
- package/iconsvg/SVG/common/ShoppingCart.tsx +18 -18
- package/iconsvg/SVG/common/SliderArrow.tsx +21 -21
- package/iconsvg/SVG/common/SliderEye.tsx +17 -17
- package/iconsvg/SVG/common/SortUpDownArrows.tsx +18 -18
- package/iconsvg/SVG/common/Speedometer.tsx +23 -23
- package/iconsvg/SVG/common/Star.tsx +20 -20
- package/iconsvg/SVG/common/StarNew.tsx +16 -16
- package/iconsvg/SVG/common/StarOutline.tsx +20 -20
- package/iconsvg/SVG/common/StarRoundedCorners.tsx +18 -18
- package/iconsvg/SVG/common/Stats.tsx +17 -17
- package/iconsvg/SVG/common/Step1.tsx +21 -21
- package/iconsvg/SVG/common/Step2.tsx +20 -20
- package/iconsvg/SVG/common/Step3.tsx +21 -21
- package/iconsvg/SVG/common/SupportCallbackIcon.tsx +20 -20
- package/iconsvg/SVG/common/Telephone.tsx +22 -22
- package/iconsvg/SVG/common/Time.tsx +17 -17
- package/iconsvg/SVG/common/Timetable.tsx +18 -18
- package/iconsvg/SVG/common/Trash.tsx +22 -22
- package/iconsvg/SVG/common/TrashRed.tsx +23 -23
- package/iconsvg/SVG/common/Upload.tsx +17 -17
- package/iconsvg/SVG/common/UserGrey.tsx +22 -22
- package/iconsvg/SVG/common/UserProfileIcon.tsx +20 -20
- package/iconsvg/SVG/common/ValidateFailure.tsx +21 -21
- package/iconsvg/SVG/common/ValidateSuccess.tsx +21 -21
- package/iconsvg/SVG/common/WarningTriangle.tsx +20 -20
- package/iconsvg/SVG/common/WhiteArrowUp.tsx +21 -21
- package/iconsvg/SVG/common/WhiteKey.tsx +21 -21
- package/iconsvg/SVG/common/WhitePeople.tsx +23 -23
- package/iconsvg/SVG/common/WhiteTick.tsx +19 -19
- package/iconsvg/SVG/flags/AT.tsx +19 -19
- package/iconsvg/SVG/flags/BE.tsx +20 -20
- package/iconsvg/SVG/flags/BG.tsx +20 -20
- package/iconsvg/SVG/flags/CH.tsx +22 -22
- package/iconsvg/SVG/flags/CZ.tsx +18 -18
- package/iconsvg/SVG/flags/DE.tsx +18 -18
- package/iconsvg/SVG/flags/DK.tsx +18 -18
- package/iconsvg/SVG/flags/ES.tsx +2585 -2585
- package/iconsvg/SVG/flags/FI.tsx +18 -18
- package/iconsvg/SVG/flags/FR.tsx +20 -20
- package/iconsvg/SVG/flags/GB.tsx +26 -26
- package/iconsvg/SVG/flags/HR.tsx +135 -135
- package/iconsvg/SVG/flags/HU.tsx +20 -20
- package/iconsvg/SVG/flags/IT.tsx +20 -20
- package/iconsvg/SVG/flags/LI.tsx +106 -106
- package/iconsvg/SVG/flags/LU.tsx +18 -18
- package/iconsvg/SVG/flags/NL.tsx +18 -18
- package/iconsvg/SVG/flags/NO.tsx +20 -20
- package/iconsvg/SVG/flags/PL.tsx +19 -19
- package/iconsvg/SVG/flags/RO.tsx +20 -20
- package/iconsvg/SVG/flags/RU.tsx +20 -20
- package/iconsvg/SVG/flags/SE.tsx +20 -20
- package/iconsvg/SVG/flags/SI.tsx +54 -54
- package/iconsvg/SVG/flags/SK.tsx +34 -34
- package/iconsvg/SVG/flags/UA.tsx +19 -19
- package/iconsvg/SVG/infoBlocks/14DaysReturnPolicy.tsx +18 -18
- package/iconsvg/SVG/infoBlocks/AlertInfo.tsx +19 -19
- package/iconsvg/SVG/infoBlocks/Autocheck.tsx +19 -19
- package/iconsvg/SVG/infoBlocks/CheckTheStory.tsx +22 -22
- package/iconsvg/SVG/infoBlocks/CustomerServiceWhite.tsx +16 -16
- package/iconsvg/SVG/infoBlocks/Guarantee.tsx +16 -16
- package/iconsvg/SVG/infoBlocks/OrderWhite.tsx +13 -13
- package/iconsvg/SVG/infoBlocks/PriceGuarantee.tsx +19 -19
- package/iconsvg/SVG/infoBlocks/PriceGuaranteeWhite.tsx +17 -17
- package/iconsvg/SVG/infoBlocks/TransportAndDelivery.tsx +21 -21
- package/iconsvg/SVG/infoBlocks/Warranty.tsx +23 -23
- package/iconsvg/SVG/popower/Mail.tsx +18 -18
- package/iconsvg/SVG/popower/Phone.tsx +19 -19
- package/iconsvg/SVG/popower/Schedule.tsx +18 -18
- package/iconsvg/SVG/searchWidgets/drive/AAllWheelDrive.tsx +26 -26
- package/iconsvg/SVG/searchWidgets/drive/AllWheelDrive.tsx +26 -26
- package/iconsvg/SVG/searchWidgets/drive/FrontWheelDrive.tsx +25 -25
- package/iconsvg/SVG/searchWidgets/drive/OtherWheelDrive.tsx +26 -26
- package/iconsvg/SVG/searchWidgets/drive/RearWheelDrive.tsx +25 -25
- package/iconsvg/SVG/searchWidgets/fuel/FuelDiesel.tsx +18 -18
- package/iconsvg/SVG/searchWidgets/fuel/FuelElectrical.tsx +19 -19
- package/iconsvg/SVG/searchWidgets/fuel/FuelElectricalDiesel.tsx +34 -34
- package/iconsvg/SVG/searchWidgets/fuel/FuelElectricalPetrol.tsx +20 -20
- package/iconsvg/SVG/searchWidgets/fuel/FuelEthanol.tsx +53 -53
- package/iconsvg/SVG/searchWidgets/fuel/FuelHydrogen.tsx +24 -24
- package/iconsvg/SVG/searchWidgets/fuel/FuelLpg.tsx +24 -24
- package/iconsvg/SVG/searchWidgets/fuel/FuelNaturalGas.tsx +23 -23
- package/iconsvg/SVG/searchWidgets/fuel/FuelOther.tsx +28 -28
- package/iconsvg/SVG/searchWidgets/fuel/FuelPetrol.tsx +18 -18
- package/iconsvg/SVG/settings/Account.tsx +17 -17
- package/iconsvg/SVG/settings/DataUsage.tsx +17 -17
- package/iconsvg/SVG/settings/MarketResearch.tsx +17 -17
- package/iconsvg/SVG/settings/Newsletter.tsx +17 -17
- package/iconsvg/SVG/settings/RemoveEye.tsx +17 -17
- package/iconsvg/SVG/settings/RemoveEyeOff.tsx +17 -17
- package/iconsvg/SVG/settings/Security.tsx +17 -17
- package/iconsvg/SVG/settings/Warning.tsx +17 -17
- package/iconsvg/SVG/slider/360.tsx +23 -23
- package/iconsvg/SVG/slider/360New.tsx +20 -20
- package/iconsvg/SVG/slider/Checked.tsx +19 -19
- package/iconsvg/SVG/slider/DiscountRibbon.tsx +51 -51
- package/iconsvg/SVG/slider/DiscountRibbonMobile.tsx +47 -47
- package/iconsvg/SVG/slider/DiscountRibbonNew.tsx +29 -29
- package/iconsvg/SVG/slider/Easy.tsx +19 -19
- package/iconsvg/SVG/slider/Fullscreen.tsx +16 -16
- package/iconsvg/SVG/slider/FullscreenWindow.tsx +23 -23
- package/iconsvg/SVG/slider/Safe.tsx +19 -19
- package/iconsvg/SVG/slider/ToBuy.tsx +19 -19
- package/iconsvg/SVG/slider/YoutubeButton.tsx +26 -26
- package/iconsvg/SVG/slider/ZoomIn.tsx +21 -21
- package/iconsvg/SVG/slider/ZoomOut.tsx +21 -21
- package/iconsvg/SVG/social/AndroidLogo.tsx +18 -18
- package/iconsvg/SVG/social/Apple.tsx +19 -19
- package/iconsvg/SVG/social/FacebookF.tsx +19 -19
- package/iconsvg/SVG/social/GooglePlusG.tsx +19 -19
- package/iconsvg/SVG/social/Instagram.tsx +17 -17
- package/iconsvg/SVG/social/Pinterest.tsx +19 -19
- package/iconsvg/SVG/social/SharingInterface.tsx +21 -21
- package/iconsvg/SVG/social/Twitter.tsx +19 -19
- package/iconsvg/SVG/social/Youtube.tsx +19 -19
- package/iconsvg/SVG/vehicle/AboIcon.tsx +11 -11
- package/iconsvg/SVG/vehicle/Abs.tsx +24 -24
- package/iconsvg/SVG/vehicle/AirCond.tsx +34 -34
- package/iconsvg/SVG/vehicle/Airbag.tsx +21 -21
- package/iconsvg/SVG/vehicle/AuxiliaryHeating.tsx +23 -23
- package/iconsvg/SVG/vehicle/Bluetooth.tsx +22 -22
- package/iconsvg/SVG/vehicle/BuyIcon.tsx +15 -15
- package/iconsvg/SVG/vehicle/CarAvailability.tsx +22 -22
- package/iconsvg/SVG/vehicle/CarInspectionCheck.tsx +21 -21
- package/iconsvg/SVG/vehicle/CarInspectionCross.tsx +21 -21
- package/iconsvg/SVG/vehicle/CheckoutChecked.tsx +15 -15
- package/iconsvg/SVG/vehicle/Co2.tsx +24 -24
- package/iconsvg/SVG/vehicle/CruiseControl.tsx +25 -25
- package/iconsvg/SVG/vehicle/Date.tsx +21 -21
- package/iconsvg/SVG/vehicle/Delivery.tsx +12 -12
- package/iconsvg/SVG/vehicle/Diesel.tsx +28 -28
- package/iconsvg/SVG/vehicle/Display.tsx +25 -25
- package/iconsvg/SVG/vehicle/Done.tsx +11 -11
- package/iconsvg/SVG/vehicle/Door.tsx +19 -19
- package/iconsvg/SVG/vehicle/DoubleDone.tsx +18 -18
- package/iconsvg/SVG/vehicle/EditIcon.tsx +11 -11
- package/iconsvg/SVG/vehicle/EmergencyBrakeAssistant.tsx +27 -27
- package/iconsvg/SVG/vehicle/Eps.tsx +24 -24
- package/iconsvg/SVG/vehicle/Esp.tsx +24 -24
- package/iconsvg/SVG/vehicle/FinancingIcon.tsx +20 -20
- package/iconsvg/SVG/vehicle/FuelConsumption.tsx +20 -20
- package/iconsvg/SVG/vehicle/Fueling.tsx +22 -22
- package/iconsvg/SVG/vehicle/FullDrive.tsx +24 -24
- package/iconsvg/SVG/vehicle/GasElectric.tsx +28 -28
- package/iconsvg/SVG/vehicle/HandsFreePhoneSystem.tsx +24 -24
- package/iconsvg/SVG/vehicle/Kw.tsx +23 -23
- package/iconsvg/SVG/vehicle/LastCrawledAt.tsx +22 -22
- package/iconsvg/SVG/vehicle/LeasingIcon.tsx +14 -14
- package/iconsvg/SVG/vehicle/Led.tsx +24 -24
- package/iconsvg/SVG/vehicle/LightSensor.tsx +22 -22
- package/iconsvg/SVG/vehicle/LinkAlternative.tsx +15 -15
- package/iconsvg/SVG/vehicle/Location.tsx +17 -17
- package/iconsvg/SVG/vehicle/MinusIcon.tsx +11 -11
- package/iconsvg/SVG/vehicle/Mirror.tsx +19 -19
- package/iconsvg/SVG/vehicle/Navigation.tsx +27 -27
- package/iconsvg/SVG/vehicle/NewCar.tsx +21 -21
- package/iconsvg/SVG/vehicle/NoImage.tsx +17 -17
- package/iconsvg/SVG/vehicle/Owner.tsx +18 -18
- package/iconsvg/SVG/vehicle/PanoramicRoof.tsx +23 -23
- package/iconsvg/SVG/vehicle/ParkingAssistants.tsx +24 -24
- package/iconsvg/SVG/vehicle/PickYourself.tsx +18 -18
- package/iconsvg/SVG/vehicle/PlusIcon.tsx +11 -11
- package/iconsvg/SVG/vehicle/Power.tsx +21 -21
- package/iconsvg/SVG/vehicle/Ps.tsx +19 -19
- package/iconsvg/SVG/vehicle/Question.tsx +24 -24
- package/iconsvg/SVG/vehicle/Seats.tsx +21 -21
- package/iconsvg/SVG/vehicle/SeatsHeating.tsx +26 -26
- package/iconsvg/SVG/vehicle/SelectorGearboxAutomatic.tsx +24 -24
- package/iconsvg/SVG/vehicle/SelectorGearboxManualShift.tsx +19 -19
- package/iconsvg/SVG/vehicle/SelectorGearboxOther.tsx +24 -24
- package/iconsvg/SVG/vehicle/SelectorGearboxSemiAutomatic.tsx +30 -30
- package/iconsvg/SVG/vehicle/SelectorInteriorTypeAlcantara.tsx +225 -225
- package/iconsvg/SVG/vehicle/SelectorInteriorTypeFabric.tsx +29 -29
- package/iconsvg/SVG/vehicle/SelectorInteriorTypeFullLeather.tsx +29 -29
- package/iconsvg/SVG/vehicle/SelectorInteriorTypeOther.tsx +26 -26
- package/iconsvg/SVG/vehicle/SelectorInteriorTypePartLeather.tsx +142 -142
- package/iconsvg/SVG/vehicle/SelectorInteriorTypeSyntheticLeather.tsx +27 -27
- package/iconsvg/SVG/vehicle/SelectorInteriorTypeVelours.tsx +39 -39
- package/iconsvg/SVG/vehicle/Shield.tsx +39 -39
- package/iconsvg/SVG/vehicle/Speedometer.tsx +17 -17
- package/iconsvg/SVG/vehicle/StartStopSystem.tsx +30 -30
- package/iconsvg/SVG/vehicle/Stop.tsx +25 -25
- package/iconsvg/SVG/vehicle/TickMark.tsx +21 -21
- package/iconsvg/SVG/vehicle/TrafficSignRecognition.tsx +29 -29
- package/iconsvg/SVG/vehicle/TrailerCoupling.tsx +24 -24
- package/iconsvg/SVG/vehicle/Transmission.tsx +27 -27
- package/iconsvg/SVG/vehicle/Wheel.tsx +43 -43
- package/iconsvg/SVG/vehicle/Wipers.tsx +22 -22
- package/iconsvg/SVG/vehicle/Wrench.tsx +17 -17
- package/iconsvg/index.ts +7 -7
- package/index.ts +18 -18
- package/locales/de/autobahn.json +676 -671
- package/locales/en/autobahn.json +676 -671
- package/locales/legacy/SearchDetailedPage.ts +205 -205
- package/locales/legacy/cbd.ts +719 -719
- package/locales/legacy/common.ts +109 -109
- package/locales/legacy/data.ts +1118 -1118
- package/locales/legacy/priceRating.ts +10 -10
- package/locales/legacy/sortingOptions.ts +21 -21
- package/media/images/raiting-stars-min.svg +7 -7
- package/media/images/refresh-button.svg +49 -49
- package/media/images/user-icon.svg +16 -16
- package/media/svg/infoBlocks/whyAutodeIconSet-F.svg +9 -9
- package/media/svg/infoBlocks/whyAutodeIconSet-G.svg +8 -8
- package/media/svg/infoBlocks/whyAutodeIconSet-Q.svg +6 -6
- package/media/svg/infoBlocks/whyAutodeIconSet-R.svg +9 -9
- package/media/svg/usp/icon1.svg +16 -16
- package/media/svg/usp/icon2.svg +13 -13
- package/media/svg/usp/icon3.svg +10 -10
- package/media/svg/usp/icon4.svg +14 -14
- package/package.json +30 -30
- package/schemes/AggregationScheme.ts +73 -73
- package/searchFilters/filterOptions.ts +119 -119
- package/searchFilters/filterProps.ts +35 -35
- package/searchFilters/index.ts +15 -15
- package/theme/autobahn.css +25 -25
- package/theme/colors_and_type.css +113 -113
- package/theme/md3.css +2045 -2034
- package/types/types.ts +373 -373
- package/types.ts +8 -8
- package/ui/Accordion.tsx +134 -134
- package/ui/Button.tsx +62 -62
- package/ui/CardCarousel.tsx +133 -133
- package/ui/Chip.tsx +29 -29
- package/ui/DatePicker.tsx +145 -145
- package/ui/Dropdown.tsx +205 -205
- package/ui/FileUpload.tsx +154 -154
- package/ui/FormCheckbox.tsx +79 -79
- package/ui/FormDropdown.tsx +327 -327
- package/ui/FormField.tsx +88 -88
- package/ui/FormRadio.tsx +93 -93
- package/ui/FormRadioGroup.tsx +106 -106
- package/ui/Icon.tsx +391 -391
- package/ui/IconButton.tsx +44 -44
- package/ui/Modal.tsx +187 -187
- package/ui/Pagination.tsx +140 -140
- package/ui/Price.tsx +25 -25
- package/ui/PriceEvalBar.tsx +48 -48
- package/ui/SaveChip.tsx +34 -34
- package/ui/Segmented.tsx +48 -48
- package/ui/Skeleton.tsx +75 -75
- package/ui/Spec.tsx +24 -24
- package/ui/Stars.tsx +29 -29
- package/ui/StatChip.tsx +21 -21
- package/ui/Stepper.tsx +106 -106
- package/ui/Switch.tsx +65 -65
- package/ui/Table.tsx +156 -156
- package/ui/Textarea.tsx +58 -58
- package/ui/index.ts +88 -88
- package/utils/CommonUtils.ts +648 -648
- package/utils/DateUtils.ts +101 -101
- package/utils/index.ts +74 -74
- package/utils/power.ts +11 -11
- package/utils/query.ts +21 -21
- package/vdp/FinanceCalculator.tsx +465 -465
- package/vdp/VdpModules.tsx +1490 -1490
- package/vdp/VdpViewer.tsx +209 -209
- package/vdp/index.ts +75 -75
- package/vdp/types.ts +197 -197
- package/vehiclesProps/cbdSelectors.ts +117 -117
- package/vehiclesProps/decoratedLightProps.tsx +572 -572
- package/vehiclesProps/decoratedProps.tsx +1746 -1746
- package/vehiclesProps/equipment.ts +129 -129
- package/vehiclesProps/vehicleDetails.ts +428 -428
- package/widgets/SearchBox.tsx +256 -256
- package/widgets/index.ts +5 -5
package/ui/CardCarousel.tsx
CHANGED
|
@@ -1,133 +1,133 @@
|
|
|
1
|
-
import React, { useState, useRef, useEffect } from 'react';
|
|
2
|
-
|
|
3
|
-
import Icon from './Icon';
|
|
4
|
-
|
|
5
|
-
export interface CardCarouselProps {
|
|
6
|
-
/** ready-to-use image URLs (already resolved by the caller — no asset/window lookup here). */
|
|
7
|
-
images: string[];
|
|
8
|
-
/** px number or any CSS length (e.g. "100%") so cards can fill their media box. */
|
|
9
|
-
height?: number | string;
|
|
10
|
-
radius?: number | string;
|
|
11
|
-
/** fired with the new active index whenever the slide changes. */
|
|
12
|
-
onChange?: (index: number) => void;
|
|
13
|
-
/** object-fit for each image; 'contain' adds inset padding. */
|
|
14
|
-
fit?: 'cover' | 'contain';
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Image carousel for cards — touch-swipeable, dots + hover arrows (desktop).
|
|
19
|
-
* Stops click bubbling so it can live inside a clickable card.
|
|
20
|
-
*/
|
|
21
|
-
const CardCarousel: React.FunctionComponent<CardCarouselProps> = ({
|
|
22
|
-
images,
|
|
23
|
-
height = 188,
|
|
24
|
-
radius,
|
|
25
|
-
onChange,
|
|
26
|
-
fit = 'cover',
|
|
27
|
-
}) => {
|
|
28
|
-
const [i, setI] = useState(0);
|
|
29
|
-
const n = images.length;
|
|
30
|
-
// MOBX-CQ-2: reset to the first slide whenever the caller hands us a
|
|
31
|
-
// DIFFERENT gallery (this instance reused for another car) — otherwise a
|
|
32
|
-
// stale index can point past the end of a shorter gallery or show the
|
|
33
|
-
// wrong photo. Keyed on CONTENT, not array identity: parents (e.g. the
|
|
34
|
-
// VDP) rebuild the array every render, and an identity-keyed reset undid
|
|
35
|
-
// every arrow click whose onChange triggered a parent re-render (the
|
|
36
|
-
// counter advanced while the track snapped back to slide 0).
|
|
37
|
-
const gallerySignature = images.join('|');
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
setI(0);
|
|
40
|
-
}, [gallerySignature]);
|
|
41
|
-
const jump = (nx: number, e?: React.SyntheticEvent) => {
|
|
42
|
-
e && e.stopPropagation();
|
|
43
|
-
setI(nx);
|
|
44
|
-
onChange && onChange(nx);
|
|
45
|
-
};
|
|
46
|
-
const go = (d: number, e?: React.SyntheticEvent) => jump((i + d + n) % n, e);
|
|
47
|
-
const trackRef = useRef<HTMLDivElement>(null);
|
|
48
|
-
const tx = useRef<number | null>(null);
|
|
49
|
-
return (
|
|
50
|
-
<div
|
|
51
|
-
className="cardcar"
|
|
52
|
-
style={{ position: 'relative', height, overflow: 'hidden', borderRadius: radius }}
|
|
53
|
-
onTouchStart={(e) => {
|
|
54
|
-
tx.current = e.touches[0].clientX;
|
|
55
|
-
}}
|
|
56
|
-
onTouchEnd={(e) => {
|
|
57
|
-
if (tx.current == null) return;
|
|
58
|
-
const dx = e.changedTouches[0].clientX - tx.current;
|
|
59
|
-
tx.current = null;
|
|
60
|
-
if (Math.abs(dx) > 40) go(dx > 0 ? -1 : 1);
|
|
61
|
-
}}
|
|
62
|
-
>
|
|
63
|
-
<div
|
|
64
|
-
ref={trackRef}
|
|
65
|
-
style={{
|
|
66
|
-
display: 'flex',
|
|
67
|
-
height: '100%',
|
|
68
|
-
transform: `translateX(-${i * 100}%)`,
|
|
69
|
-
transition: 'transform var(--dur-3) var(--ease-emphasized)',
|
|
70
|
-
}}
|
|
71
|
-
>
|
|
72
|
-
{images.map((src, k) => (
|
|
73
|
-
<img
|
|
74
|
-
key={k}
|
|
75
|
-
src={src}
|
|
76
|
-
alt=""
|
|
77
|
-
loading="lazy"
|
|
78
|
-
decoding="async"
|
|
79
|
-
style={{
|
|
80
|
-
flex: '0 0 100%',
|
|
81
|
-
width: '100%',
|
|
82
|
-
height: '100%',
|
|
83
|
-
objectFit: fit,
|
|
84
|
-
padding: fit === 'contain' ? '5% 6%' : 0,
|
|
85
|
-
boxSizing: 'border-box',
|
|
86
|
-
background: '#fff',
|
|
87
|
-
}}
|
|
88
|
-
/>
|
|
89
|
-
))}
|
|
90
|
-
</div>
|
|
91
|
-
{/* arrows + dots only when there is actually something to switch to — with a single
|
|
92
|
-
image (e.g. SRP cards before their gallery is lazy-loaded) they are dead controls. */}
|
|
93
|
-
{n > 1 && (
|
|
94
|
-
<>
|
|
95
|
-
<button className="car-arrow car-arrow--l" aria-label="zurück" onClick={(e) => go(-1, e)}>
|
|
96
|
-
<Icon name="chevron-left" size={20} />
|
|
97
|
-
</button>
|
|
98
|
-
<button className="car-arrow car-arrow--r" aria-label="weiter" onClick={(e) => go(1, e)}>
|
|
99
|
-
<Icon name="chevron-right" size={20} />
|
|
100
|
-
</button>
|
|
101
|
-
<div
|
|
102
|
-
style={{
|
|
103
|
-
position: 'absolute',
|
|
104
|
-
bottom: 9,
|
|
105
|
-
left: 0,
|
|
106
|
-
right: 0,
|
|
107
|
-
display: 'flex',
|
|
108
|
-
justifyContent: 'center',
|
|
109
|
-
gap: 6,
|
|
110
|
-
pointerEvents: 'none',
|
|
111
|
-
}}
|
|
112
|
-
>
|
|
113
|
-
{images.slice(0, 6).map((_, k) => (
|
|
114
|
-
<span
|
|
115
|
-
key={k}
|
|
116
|
-
style={{
|
|
117
|
-
width: k === i ? 16 : 6,
|
|
118
|
-
height: 6,
|
|
119
|
-
borderRadius: 3,
|
|
120
|
-
background: k === i ? 'var(--md-on-surface)' : 'rgba(26,27,34,.3)',
|
|
121
|
-
boxShadow: '0 0 0 1px rgba(255,255,255,.5)',
|
|
122
|
-
transition: 'width var(--dur-2)',
|
|
123
|
-
}}
|
|
124
|
-
/>
|
|
125
|
-
))}
|
|
126
|
-
</div>
|
|
127
|
-
</>
|
|
128
|
-
)}
|
|
129
|
-
</div>
|
|
130
|
-
);
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
export default CardCarousel;
|
|
1
|
+
import React, { useState, useRef, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
import Icon from './Icon';
|
|
4
|
+
|
|
5
|
+
export interface CardCarouselProps {
|
|
6
|
+
/** ready-to-use image URLs (already resolved by the caller — no asset/window lookup here). */
|
|
7
|
+
images: string[];
|
|
8
|
+
/** px number or any CSS length (e.g. "100%") so cards can fill their media box. */
|
|
9
|
+
height?: number | string;
|
|
10
|
+
radius?: number | string;
|
|
11
|
+
/** fired with the new active index whenever the slide changes. */
|
|
12
|
+
onChange?: (index: number) => void;
|
|
13
|
+
/** object-fit for each image; 'contain' adds inset padding. */
|
|
14
|
+
fit?: 'cover' | 'contain';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Image carousel for cards — touch-swipeable, dots + hover arrows (desktop).
|
|
19
|
+
* Stops click bubbling so it can live inside a clickable card.
|
|
20
|
+
*/
|
|
21
|
+
const CardCarousel: React.FunctionComponent<CardCarouselProps> = ({
|
|
22
|
+
images,
|
|
23
|
+
height = 188,
|
|
24
|
+
radius,
|
|
25
|
+
onChange,
|
|
26
|
+
fit = 'cover',
|
|
27
|
+
}) => {
|
|
28
|
+
const [i, setI] = useState(0);
|
|
29
|
+
const n = images.length;
|
|
30
|
+
// MOBX-CQ-2: reset to the first slide whenever the caller hands us a
|
|
31
|
+
// DIFFERENT gallery (this instance reused for another car) — otherwise a
|
|
32
|
+
// stale index can point past the end of a shorter gallery or show the
|
|
33
|
+
// wrong photo. Keyed on CONTENT, not array identity: parents (e.g. the
|
|
34
|
+
// VDP) rebuild the array every render, and an identity-keyed reset undid
|
|
35
|
+
// every arrow click whose onChange triggered a parent re-render (the
|
|
36
|
+
// counter advanced while the track snapped back to slide 0).
|
|
37
|
+
const gallerySignature = images.join('|');
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
setI(0);
|
|
40
|
+
}, [gallerySignature]);
|
|
41
|
+
const jump = (nx: number, e?: React.SyntheticEvent) => {
|
|
42
|
+
e && e.stopPropagation();
|
|
43
|
+
setI(nx);
|
|
44
|
+
onChange && onChange(nx);
|
|
45
|
+
};
|
|
46
|
+
const go = (d: number, e?: React.SyntheticEvent) => jump((i + d + n) % n, e);
|
|
47
|
+
const trackRef = useRef<HTMLDivElement>(null);
|
|
48
|
+
const tx = useRef<number | null>(null);
|
|
49
|
+
return (
|
|
50
|
+
<div
|
|
51
|
+
className="cardcar"
|
|
52
|
+
style={{ position: 'relative', height, overflow: 'hidden', borderRadius: radius }}
|
|
53
|
+
onTouchStart={(e) => {
|
|
54
|
+
tx.current = e.touches[0].clientX;
|
|
55
|
+
}}
|
|
56
|
+
onTouchEnd={(e) => {
|
|
57
|
+
if (tx.current == null) return;
|
|
58
|
+
const dx = e.changedTouches[0].clientX - tx.current;
|
|
59
|
+
tx.current = null;
|
|
60
|
+
if (Math.abs(dx) > 40) go(dx > 0 ? -1 : 1);
|
|
61
|
+
}}
|
|
62
|
+
>
|
|
63
|
+
<div
|
|
64
|
+
ref={trackRef}
|
|
65
|
+
style={{
|
|
66
|
+
display: 'flex',
|
|
67
|
+
height: '100%',
|
|
68
|
+
transform: `translateX(-${i * 100}%)`,
|
|
69
|
+
transition: 'transform var(--dur-3) var(--ease-emphasized)',
|
|
70
|
+
}}
|
|
71
|
+
>
|
|
72
|
+
{images.map((src, k) => (
|
|
73
|
+
<img
|
|
74
|
+
key={k}
|
|
75
|
+
src={src}
|
|
76
|
+
alt=""
|
|
77
|
+
loading="lazy"
|
|
78
|
+
decoding="async"
|
|
79
|
+
style={{
|
|
80
|
+
flex: '0 0 100%',
|
|
81
|
+
width: '100%',
|
|
82
|
+
height: '100%',
|
|
83
|
+
objectFit: fit,
|
|
84
|
+
padding: fit === 'contain' ? '5% 6%' : 0,
|
|
85
|
+
boxSizing: 'border-box',
|
|
86
|
+
background: '#fff',
|
|
87
|
+
}}
|
|
88
|
+
/>
|
|
89
|
+
))}
|
|
90
|
+
</div>
|
|
91
|
+
{/* arrows + dots only when there is actually something to switch to — with a single
|
|
92
|
+
image (e.g. SRP cards before their gallery is lazy-loaded) they are dead controls. */}
|
|
93
|
+
{n > 1 && (
|
|
94
|
+
<>
|
|
95
|
+
<button className="car-arrow car-arrow--l" aria-label="zurück" onClick={(e) => go(-1, e)}>
|
|
96
|
+
<Icon name="chevron-left" size={20} />
|
|
97
|
+
</button>
|
|
98
|
+
<button className="car-arrow car-arrow--r" aria-label="weiter" onClick={(e) => go(1, e)}>
|
|
99
|
+
<Icon name="chevron-right" size={20} />
|
|
100
|
+
</button>
|
|
101
|
+
<div
|
|
102
|
+
style={{
|
|
103
|
+
position: 'absolute',
|
|
104
|
+
bottom: 9,
|
|
105
|
+
left: 0,
|
|
106
|
+
right: 0,
|
|
107
|
+
display: 'flex',
|
|
108
|
+
justifyContent: 'center',
|
|
109
|
+
gap: 6,
|
|
110
|
+
pointerEvents: 'none',
|
|
111
|
+
}}
|
|
112
|
+
>
|
|
113
|
+
{images.slice(0, 6).map((_, k) => (
|
|
114
|
+
<span
|
|
115
|
+
key={k}
|
|
116
|
+
style={{
|
|
117
|
+
width: k === i ? 16 : 6,
|
|
118
|
+
height: 6,
|
|
119
|
+
borderRadius: 3,
|
|
120
|
+
background: k === i ? 'var(--md-on-surface)' : 'rgba(26,27,34,.3)',
|
|
121
|
+
boxShadow: '0 0 0 1px rgba(255,255,255,.5)',
|
|
122
|
+
transition: 'width var(--dur-2)',
|
|
123
|
+
}}
|
|
124
|
+
/>
|
|
125
|
+
))}
|
|
126
|
+
</div>
|
|
127
|
+
</>
|
|
128
|
+
)}
|
|
129
|
+
</div>
|
|
130
|
+
);
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
export default CardCarousel;
|
package/ui/Chip.tsx
CHANGED
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
|
|
3
|
-
import Icon from './Icon';
|
|
4
|
-
|
|
5
|
-
export interface ChipProps {
|
|
6
|
-
/** kebab-case lucide icon name rendered before the label. */
|
|
7
|
-
icon?: string;
|
|
8
|
-
/** toggled/applied state — also drives `aria-pressed` so assistive tech announces the chip
|
|
9
|
-
* as a pressed toggle button (undefined = not a toggle, so no `aria-pressed` is rendered). */
|
|
10
|
-
selected?: boolean;
|
|
11
|
-
/** renders the filter-chip variant (different selected color). */
|
|
12
|
-
filter?: boolean;
|
|
13
|
-
children?: React.ReactNode;
|
|
14
|
-
onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
15
|
-
/** native `<button>` type; defaults to "button" (see Button.tsx for the same footgun). */
|
|
16
|
-
type?: 'button' | 'submit' | 'reset';
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const Chip: React.FunctionComponent<ChipProps> = ({ icon, selected, filter, children, onClick, type = 'button' }) => {
|
|
20
|
-
const cn = ['chip', filter && 'chip--filter', selected && 'chip--selected'].filter(Boolean).join(' ');
|
|
21
|
-
return (
|
|
22
|
-
<button type={type} className={cn} aria-pressed={selected} onClick={onClick}>
|
|
23
|
-
{icon && <Icon name={icon} size={16} />}
|
|
24
|
-
{children}
|
|
25
|
-
</button>
|
|
26
|
-
);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
export default Chip;
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import Icon from './Icon';
|
|
4
|
+
|
|
5
|
+
export interface ChipProps {
|
|
6
|
+
/** kebab-case lucide icon name rendered before the label. */
|
|
7
|
+
icon?: string;
|
|
8
|
+
/** toggled/applied state — also drives `aria-pressed` so assistive tech announces the chip
|
|
9
|
+
* as a pressed toggle button (undefined = not a toggle, so no `aria-pressed` is rendered). */
|
|
10
|
+
selected?: boolean;
|
|
11
|
+
/** renders the filter-chip variant (different selected color). */
|
|
12
|
+
filter?: boolean;
|
|
13
|
+
children?: React.ReactNode;
|
|
14
|
+
onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
15
|
+
/** native `<button>` type; defaults to "button" (see Button.tsx for the same footgun). */
|
|
16
|
+
type?: 'button' | 'submit' | 'reset';
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const Chip: React.FunctionComponent<ChipProps> = ({ icon, selected, filter, children, onClick, type = 'button' }) => {
|
|
20
|
+
const cn = ['chip', filter && 'chip--filter', selected && 'chip--selected'].filter(Boolean).join(' ');
|
|
21
|
+
return (
|
|
22
|
+
<button type={type} className={cn} aria-pressed={selected} onClick={onClick}>
|
|
23
|
+
{icon && <Icon name={icon} size={16} />}
|
|
24
|
+
{children}
|
|
25
|
+
</button>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default Chip;
|
package/ui/DatePicker.tsx
CHANGED
|
@@ -1,145 +1,145 @@
|
|
|
1
|
-
// Autobahn (auto.de redesign) — md3 date field bound to a mobx-react-form field.
|
|
2
|
-
//
|
|
3
|
-
// Native, themeable replacement for the legacy fe-ui-core <MaterialDatePicker> (which mounts a MUI
|
|
4
|
-
// <MobileDatePicker> under its own <ThemeProvider> — that second theme bleeds into the scoped `.md3`
|
|
5
|
-
// subtree and reads as "not-md3"). Instead we render a single <input type="date"> styled exactly like
|
|
6
|
-
// `.mfield`, so the browser supplies a locale-correct calendar popup while WE own the visual chrome.
|
|
7
|
-
//
|
|
8
|
-
// DATA CONTRACT — must match the legacy MaterialDatePicker usage EXACTLY (5 pages: Einstellungen
|
|
9
|
-
// birthday, Checkout birthday + co-borrower birthday, VehicleEdit constructionDate), because the same
|
|
10
|
-
// mobx-react-form field + validation rules + submit hooks are reused unchanged:
|
|
11
|
-
// - value: Date | string | null (legacy passes `field.value || null`; we read field.value here).
|
|
12
|
-
// - onChange emits a **Date object** via `field.onChange(value, field.name)` — the exact call the
|
|
13
|
-
// legacy callers wired into MaterialDatePicker's `onChange(value: Date)`. Clearing emits `null`.
|
|
14
|
-
// - minDate / maxDate: Date objects (legacy: `_minDate` = 1900-01-01, `handleMaxDateForPicker()` =
|
|
15
|
-
// today−18y). We forward them to the native input as min/max=yyyy-mm-dd so out-of-range dates
|
|
16
|
-
// can't be picked, mirroring the legacy onAccept clamp.
|
|
17
|
-
// - error shown inline from field.error (legacy passed `field.hasError && field.error`).
|
|
18
|
-
//
|
|
19
|
-
// The native <input type="date"> is locale-free at the value level (always yyyy-mm-dd), so the
|
|
20
|
-
// `format`/`language` props are accepted for signature parity but don't change the wire value; the
|
|
21
|
-
// browser renders the visible date in the user's locale. observer-wrapped so it re-renders on
|
|
22
|
-
// field value/error changes. Renders correctly only inside a `<div className="md3">` subtree.
|
|
23
|
-
|
|
24
|
-
import * as React from 'react';
|
|
25
|
-
import { observer } from 'mobx-react';
|
|
26
|
-
|
|
27
|
-
export interface DatePickerProps {
|
|
28
|
-
/** mobx-react-form field (ContactDetailsForm.$('privateAddress.birthday') etc.). Typed any — the lib ships no TS types. */
|
|
29
|
-
field: any;
|
|
30
|
-
/** i18n translate — resolves the field's label/placeholder key. Optional (matches legacy, which passed t). */
|
|
31
|
-
t?: (key: string, options?: object) => string;
|
|
32
|
-
/** kept for legacy signature parity; the native input value is always locale-free yyyy-mm-dd. */
|
|
33
|
-
language?: 'de' | 'en';
|
|
34
|
-
/** earliest selectable date (legacy `_minDate`). */
|
|
35
|
-
minDate?: Date;
|
|
36
|
-
/** latest selectable date (legacy `handleMaxDateForPicker()`). */
|
|
37
|
-
maxDate?: Date;
|
|
38
|
-
/** kept for legacy signature parity (display format); does not change the emitted Date value. */
|
|
39
|
-
format?: string;
|
|
40
|
-
/** explicit visible label override (legacy ProfileTabAccount/Checkout pass a namespaced label). */
|
|
41
|
-
label?: string;
|
|
42
|
-
id?: string;
|
|
43
|
-
disabled?: boolean;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** Date | string | null -> 'yyyy-mm-dd' (the native <input type="date"> value), or '' when empty/invalid. */
|
|
47
|
-
function toInputValue(value: Date | string | null | undefined): string {
|
|
48
|
-
if (!value) return '';
|
|
49
|
-
const d = value instanceof Date ? value : new Date(value);
|
|
50
|
-
const time = d.getTime();
|
|
51
|
-
if (Number.isNaN(time)) return '';
|
|
52
|
-
// Use local Y/M/D (not toISOString, which shifts by timezone and can land on the previous day).
|
|
53
|
-
const y = d.getFullYear();
|
|
54
|
-
const m = `${d.getMonth() + 1}`.padStart(2, '0');
|
|
55
|
-
const day = `${d.getDate()}`.padStart(2, '0');
|
|
56
|
-
return `${y}-${m}-${day}`;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/** 'yyyy-mm-dd' -> a local-midnight Date (matching `new Date('01/01/1970')` semantics the legacy used), or null. */
|
|
60
|
-
function fromInputValue(value: string): Date | null {
|
|
61
|
-
if (!value) return null;
|
|
62
|
-
const parts = value.split('-');
|
|
63
|
-
if (parts.length !== 3) return null;
|
|
64
|
-
const y = Number(parts[0]);
|
|
65
|
-
const m = Number(parts[1]);
|
|
66
|
-
const day = Number(parts[2]);
|
|
67
|
-
if (!y || !m || !day) return null;
|
|
68
|
-
return new Date(y, m - 1, day);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const DatePicker: React.FunctionComponent<DatePickerProps> = observer(
|
|
72
|
-
({ field, t, minDate, maxDate, label, id, disabled }) => {
|
|
73
|
-
const translate = t || ((k: string) => k);
|
|
74
|
-
const hasError = !!field.hasError && !!field.error;
|
|
75
|
-
|
|
76
|
-
// Visible label: explicit `label` prop wins (namespaced callers), else FormField's pattern —
|
|
77
|
-
// prefer the field's placeholder key, else its label key. translate() returns the input
|
|
78
|
-
// unchanged when there's no translation, so this is safe for plain-string labels too.
|
|
79
|
-
const resolvedLabel =
|
|
80
|
-
label != null
|
|
81
|
-
? label
|
|
82
|
-
: field.placeholder
|
|
83
|
-
? translate(field.placeholder)
|
|
84
|
-
: field.label
|
|
85
|
-
? translate(field.label)
|
|
86
|
-
: '';
|
|
87
|
-
|
|
88
|
-
const value = toInputValue(field.value);
|
|
89
|
-
const min = minDate ? toInputValue(minDate) : undefined;
|
|
90
|
-
const max = maxDate ? toInputValue(maxDate) : undefined;
|
|
91
|
-
|
|
92
|
-
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
93
|
-
const next = fromInputValue(e.target.value);
|
|
94
|
-
// Emit a Date (or null) via the EXACT legacy call: field.onChange(value, field.name).
|
|
95
|
-
field.onChange(next as any, field.name);
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
const handleBlur = () => {
|
|
99
|
-
// Mirror the legacy onBlurBirthday: validate, surfacing errors if the field is invalid.
|
|
100
|
-
if (typeof field.validate === 'function') {
|
|
101
|
-
const result = field.validate();
|
|
102
|
-
if (result && typeof result.then === 'function') {
|
|
103
|
-
result.then((subField: any) => {
|
|
104
|
-
if (field.isValid === false && subField && typeof subField.showErrors === 'function') {
|
|
105
|
-
subField.showErrors(true);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
return (
|
|
113
|
-
<div className="mfield-group mdate">
|
|
114
|
-
{resolvedLabel ? (
|
|
115
|
-
<label className="md-label-sm mfield-label" htmlFor={id}>
|
|
116
|
-
{resolvedLabel}
|
|
117
|
-
</label>
|
|
118
|
-
) : null}
|
|
119
|
-
<div
|
|
120
|
-
className={
|
|
121
|
-
'mfield mdate-field' +
|
|
122
|
-
(hasError ? ' mfield--error' : '') +
|
|
123
|
-
(disabled ? ' mfield--disabled' : '')
|
|
124
|
-
}
|
|
125
|
-
>
|
|
126
|
-
<input
|
|
127
|
-
id={id}
|
|
128
|
-
type="date"
|
|
129
|
-
className="mdate-input"
|
|
130
|
-
value={value}
|
|
131
|
-
min={min}
|
|
132
|
-
max={max}
|
|
133
|
-
disabled={disabled}
|
|
134
|
-
onChange={handleChange}
|
|
135
|
-
onBlur={handleBlur}
|
|
136
|
-
style={{ width: '100%' }}
|
|
137
|
-
/>
|
|
138
|
-
</div>
|
|
139
|
-
{hasError ? <span className="mfield-error-text">{field.error}</span> : null}
|
|
140
|
-
</div>
|
|
141
|
-
);
|
|
142
|
-
},
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
export default DatePicker;
|
|
1
|
+
// Autobahn (auto.de redesign) — md3 date field bound to a mobx-react-form field.
|
|
2
|
+
//
|
|
3
|
+
// Native, themeable replacement for the legacy fe-ui-core <MaterialDatePicker> (which mounts a MUI
|
|
4
|
+
// <MobileDatePicker> under its own <ThemeProvider> — that second theme bleeds into the scoped `.md3`
|
|
5
|
+
// subtree and reads as "not-md3"). Instead we render a single <input type="date"> styled exactly like
|
|
6
|
+
// `.mfield`, so the browser supplies a locale-correct calendar popup while WE own the visual chrome.
|
|
7
|
+
//
|
|
8
|
+
// DATA CONTRACT — must match the legacy MaterialDatePicker usage EXACTLY (5 pages: Einstellungen
|
|
9
|
+
// birthday, Checkout birthday + co-borrower birthday, VehicleEdit constructionDate), because the same
|
|
10
|
+
// mobx-react-form field + validation rules + submit hooks are reused unchanged:
|
|
11
|
+
// - value: Date | string | null (legacy passes `field.value || null`; we read field.value here).
|
|
12
|
+
// - onChange emits a **Date object** via `field.onChange(value, field.name)` — the exact call the
|
|
13
|
+
// legacy callers wired into MaterialDatePicker's `onChange(value: Date)`. Clearing emits `null`.
|
|
14
|
+
// - minDate / maxDate: Date objects (legacy: `_minDate` = 1900-01-01, `handleMaxDateForPicker()` =
|
|
15
|
+
// today−18y). We forward them to the native input as min/max=yyyy-mm-dd so out-of-range dates
|
|
16
|
+
// can't be picked, mirroring the legacy onAccept clamp.
|
|
17
|
+
// - error shown inline from field.error (legacy passed `field.hasError && field.error`).
|
|
18
|
+
//
|
|
19
|
+
// The native <input type="date"> is locale-free at the value level (always yyyy-mm-dd), so the
|
|
20
|
+
// `format`/`language` props are accepted for signature parity but don't change the wire value; the
|
|
21
|
+
// browser renders the visible date in the user's locale. observer-wrapped so it re-renders on
|
|
22
|
+
// field value/error changes. Renders correctly only inside a `<div className="md3">` subtree.
|
|
23
|
+
|
|
24
|
+
import * as React from 'react';
|
|
25
|
+
import { observer } from 'mobx-react';
|
|
26
|
+
|
|
27
|
+
export interface DatePickerProps {
|
|
28
|
+
/** mobx-react-form field (ContactDetailsForm.$('privateAddress.birthday') etc.). Typed any — the lib ships no TS types. */
|
|
29
|
+
field: any;
|
|
30
|
+
/** i18n translate — resolves the field's label/placeholder key. Optional (matches legacy, which passed t). */
|
|
31
|
+
t?: (key: string, options?: object) => string;
|
|
32
|
+
/** kept for legacy signature parity; the native input value is always locale-free yyyy-mm-dd. */
|
|
33
|
+
language?: 'de' | 'en';
|
|
34
|
+
/** earliest selectable date (legacy `_minDate`). */
|
|
35
|
+
minDate?: Date;
|
|
36
|
+
/** latest selectable date (legacy `handleMaxDateForPicker()`). */
|
|
37
|
+
maxDate?: Date;
|
|
38
|
+
/** kept for legacy signature parity (display format); does not change the emitted Date value. */
|
|
39
|
+
format?: string;
|
|
40
|
+
/** explicit visible label override (legacy ProfileTabAccount/Checkout pass a namespaced label). */
|
|
41
|
+
label?: string;
|
|
42
|
+
id?: string;
|
|
43
|
+
disabled?: boolean;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Date | string | null -> 'yyyy-mm-dd' (the native <input type="date"> value), or '' when empty/invalid. */
|
|
47
|
+
function toInputValue(value: Date | string | null | undefined): string {
|
|
48
|
+
if (!value) return '';
|
|
49
|
+
const d = value instanceof Date ? value : new Date(value);
|
|
50
|
+
const time = d.getTime();
|
|
51
|
+
if (Number.isNaN(time)) return '';
|
|
52
|
+
// Use local Y/M/D (not toISOString, which shifts by timezone and can land on the previous day).
|
|
53
|
+
const y = d.getFullYear();
|
|
54
|
+
const m = `${d.getMonth() + 1}`.padStart(2, '0');
|
|
55
|
+
const day = `${d.getDate()}`.padStart(2, '0');
|
|
56
|
+
return `${y}-${m}-${day}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** 'yyyy-mm-dd' -> a local-midnight Date (matching `new Date('01/01/1970')` semantics the legacy used), or null. */
|
|
60
|
+
function fromInputValue(value: string): Date | null {
|
|
61
|
+
if (!value) return null;
|
|
62
|
+
const parts = value.split('-');
|
|
63
|
+
if (parts.length !== 3) return null;
|
|
64
|
+
const y = Number(parts[0]);
|
|
65
|
+
const m = Number(parts[1]);
|
|
66
|
+
const day = Number(parts[2]);
|
|
67
|
+
if (!y || !m || !day) return null;
|
|
68
|
+
return new Date(y, m - 1, day);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const DatePicker: React.FunctionComponent<DatePickerProps> = observer(
|
|
72
|
+
({ field, t, minDate, maxDate, label, id, disabled }) => {
|
|
73
|
+
const translate = t || ((k: string) => k);
|
|
74
|
+
const hasError = !!field.hasError && !!field.error;
|
|
75
|
+
|
|
76
|
+
// Visible label: explicit `label` prop wins (namespaced callers), else FormField's pattern —
|
|
77
|
+
// prefer the field's placeholder key, else its label key. translate() returns the input
|
|
78
|
+
// unchanged when there's no translation, so this is safe for plain-string labels too.
|
|
79
|
+
const resolvedLabel =
|
|
80
|
+
label != null
|
|
81
|
+
? label
|
|
82
|
+
: field.placeholder
|
|
83
|
+
? translate(field.placeholder)
|
|
84
|
+
: field.label
|
|
85
|
+
? translate(field.label)
|
|
86
|
+
: '';
|
|
87
|
+
|
|
88
|
+
const value = toInputValue(field.value);
|
|
89
|
+
const min = minDate ? toInputValue(minDate) : undefined;
|
|
90
|
+
const max = maxDate ? toInputValue(maxDate) : undefined;
|
|
91
|
+
|
|
92
|
+
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
93
|
+
const next = fromInputValue(e.target.value);
|
|
94
|
+
// Emit a Date (or null) via the EXACT legacy call: field.onChange(value, field.name).
|
|
95
|
+
field.onChange(next as any, field.name);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const handleBlur = () => {
|
|
99
|
+
// Mirror the legacy onBlurBirthday: validate, surfacing errors if the field is invalid.
|
|
100
|
+
if (typeof field.validate === 'function') {
|
|
101
|
+
const result = field.validate();
|
|
102
|
+
if (result && typeof result.then === 'function') {
|
|
103
|
+
result.then((subField: any) => {
|
|
104
|
+
if (field.isValid === false && subField && typeof subField.showErrors === 'function') {
|
|
105
|
+
subField.showErrors(true);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<div className="mfield-group mdate">
|
|
114
|
+
{resolvedLabel ? (
|
|
115
|
+
<label className="md-label-sm mfield-label" htmlFor={id}>
|
|
116
|
+
{resolvedLabel}
|
|
117
|
+
</label>
|
|
118
|
+
) : null}
|
|
119
|
+
<div
|
|
120
|
+
className={
|
|
121
|
+
'mfield mdate-field' +
|
|
122
|
+
(hasError ? ' mfield--error' : '') +
|
|
123
|
+
(disabled ? ' mfield--disabled' : '')
|
|
124
|
+
}
|
|
125
|
+
>
|
|
126
|
+
<input
|
|
127
|
+
id={id}
|
|
128
|
+
type="date"
|
|
129
|
+
className="mdate-input"
|
|
130
|
+
value={value}
|
|
131
|
+
min={min}
|
|
132
|
+
max={max}
|
|
133
|
+
disabled={disabled}
|
|
134
|
+
onChange={handleChange}
|
|
135
|
+
onBlur={handleBlur}
|
|
136
|
+
style={{ width: '100%' }}
|
|
137
|
+
/>
|
|
138
|
+
</div>
|
|
139
|
+
{hasError ? <span className="mfield-error-text">{field.error}</span> : null}
|
|
140
|
+
</div>
|
|
141
|
+
);
|
|
142
|
+
},
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
export default DatePicker;
|