@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/FormDropdown.tsx
CHANGED
|
@@ -1,327 +1,327 @@
|
|
|
1
|
-
// Autobahn (auto.de redesign) — mobx-react-form-bound dropdown adapter.
|
|
2
|
-
//
|
|
3
|
-
// A drop-in md3 replacement for the legacy fe-ui-core FormDropDown
|
|
4
|
-
// (components/ui/FormDropDown/FormDropDown.tsx). It is the #1 form dependency
|
|
5
|
-
// (11+ pages, 60+ vehicle-form selects: BasicData/EngineData/Chassis/…,
|
|
6
|
-
// Settings gender/title, …). The visual control is the md3 `Dropdown`
|
|
7
|
-
// (single-select) reused as-is; multi-select is implemented here on the same
|
|
8
|
-
// `mselect-*` classes as a checklist with selected chips on the trigger.
|
|
9
|
-
//
|
|
10
|
-
// THE DATA CONTRACT MIRRORS THE LEGACY EXACTLY so validation/output/submit are
|
|
11
|
-
// unchanged — only the markup is re-skinned:
|
|
12
|
-
//
|
|
13
|
-
// • single (default): field.value is the option OBJECT `{value,label}` (legacy
|
|
14
|
-
// `getValue`). We read `field.value.value` and commit
|
|
15
|
-
// `field.onChange({value,label}, field.name)`; clear -> `onChange('', name)`.
|
|
16
|
-
// • isObj: field.value IS the source option object (e.g. a GENDERS item
|
|
17
|
-
// `{value:number,label}`). On change we resolve the matching object out of
|
|
18
|
-
// `field.extra` and `onChange(obj, field.name)` (legacy parity — form.output
|
|
19
|
-
// keeps the object).
|
|
20
|
-
// • isMulti: field.value is a primitive array; the menu is a checklist; the
|
|
21
|
-
// trigger shows the selected labels as chips; `onChange(values, field.name)`.
|
|
22
|
-
//
|
|
23
|
-
// Option shapes in `field.extra` are normalized: primitive lists (['2','3',…]),
|
|
24
|
-
// `{value,label}` and `{key,value}`. Label resolution mirrors the legacy
|
|
25
|
-
// getOptions(): with a namespace, 'cbd' -> t('cbd:'+opt), else a labelled option
|
|
26
|
-
// -> t(namespace+':'+label), else t(opt). When `isApiTranslated`, `field.extra`
|
|
27
|
-
// already carries translated labels, so they are used verbatim.
|
|
28
|
-
//
|
|
29
|
-
// observer-wrapped (re-renders on value/error). Renders correctly only inside a
|
|
30
|
-
// `.md3` subtree.
|
|
31
|
-
|
|
32
|
-
import * as React from 'react';
|
|
33
|
-
import { observer } from 'mobx-react';
|
|
34
|
-
|
|
35
|
-
import Icon from './Icon';
|
|
36
|
-
import Dropdown, { DropdownOption } from './Dropdown';
|
|
37
|
-
|
|
38
|
-
export interface FormDropdownProps {
|
|
39
|
-
/** mobx-react-form field (form.$('basicDataForm.mainData_make') etc.). Untyped — the lib ships no TS types. */
|
|
40
|
-
field: any;
|
|
41
|
-
/** i18n translate — resolves option labels and the field's placeholder/label key. */
|
|
42
|
-
t: (key: string, options?: object) => string;
|
|
43
|
-
/** translation namespace for option labels (e.g. 'common', 'cbd', 'mainData'). */
|
|
44
|
-
namespace?: string;
|
|
45
|
-
/** field.value is the source option OBJECT, not a scalar (GENDERS/TITLES item). */
|
|
46
|
-
isObj?: boolean;
|
|
47
|
-
/** option labels in field.extra are already translated (came from a request). */
|
|
48
|
-
isApiTranslated?: boolean;
|
|
49
|
-
/** multiple selection — value is a primitive array, rendered as chips + checklist. */
|
|
50
|
-
isMulti?: boolean;
|
|
51
|
-
/** hide the clear ("×") affordance on a single select. */
|
|
52
|
-
disableClearable?: boolean;
|
|
53
|
-
/** suppress the built-in label (when an outer wrapper — e.g. FormFieldDropDown — owns the label). */
|
|
54
|
-
hideLabel?: boolean;
|
|
55
|
-
/** accepted for legacy-surface parity (the md3 control never free-types). */
|
|
56
|
-
freeSolo?: boolean;
|
|
57
|
-
disabled?: boolean;
|
|
58
|
-
/** layout passthrough (e.g. grid-area), mirrors legacy `style`. */
|
|
59
|
-
style?: React.CSSProperties;
|
|
60
|
-
/** extra class on the wrapper (legacy `className`). */
|
|
61
|
-
className?: string;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/** Raw option as it can appear in field.extra. */
|
|
65
|
-
type RawOption =
|
|
66
|
-
| string
|
|
67
|
-
| number
|
|
68
|
-
| { value: any; label?: any; key?: any; isDisabled?: boolean; isSeries?: boolean };
|
|
69
|
-
|
|
70
|
-
/** Normalize one raw option to a stable { value, label, disabled } shape (label not yet translated). */
|
|
71
|
-
function normalizeOption(opt: RawOption): { value: string; rawLabel: any; disabled: boolean } {
|
|
72
|
-
if (opt !== null && typeof opt === 'object') {
|
|
73
|
-
// {value,label} | {key,value} | {value,...}
|
|
74
|
-
const hasKey = 'key' in opt && !('label' in opt);
|
|
75
|
-
const value = hasKey ? (opt as any).key : (opt as any).value;
|
|
76
|
-
const rawLabel = hasKey
|
|
77
|
-
? (opt as any).value
|
|
78
|
-
: 'label' in opt && (opt as any).label != null
|
|
79
|
-
? (opt as any).label
|
|
80
|
-
: (opt as any).value;
|
|
81
|
-
const disabled = !!((opt as any).isDisabled || (opt as any).isSeries);
|
|
82
|
-
return { value: String(value), rawLabel, disabled };
|
|
83
|
-
}
|
|
84
|
-
// primitive
|
|
85
|
-
return { value: String(opt), rawLabel: opt, disabled: false };
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const FormDropdown: React.FunctionComponent<FormDropdownProps> = observer(
|
|
89
|
-
({ field, t, namespace, isObj, isApiTranslated, isMulti, disableClearable, freeSolo, disabled, style, className, hideLabel }) => {
|
|
90
|
-
// ---- label resolution (legacy getOptions parity) -------------------------------------------
|
|
91
|
-
const labelFor = React.useCallback(
|
|
92
|
-
(rawLabel: any): string => {
|
|
93
|
-
const s = rawLabel == null ? '' : String(rawLabel);
|
|
94
|
-
if (isApiTranslated) return s; // already translated in field.extra
|
|
95
|
-
if (namespace) {
|
|
96
|
-
if (namespace === 'cbd') return t(`cbd:${s}`);
|
|
97
|
-
// a "labelled" option translates under the namespace; a bare primitive translates as-is.
|
|
98
|
-
return t(s) === s ? t(`${namespace}:${s}`) : t(s);
|
|
99
|
-
}
|
|
100
|
-
return t(s);
|
|
101
|
-
},
|
|
102
|
-
[t, namespace, isApiTranslated],
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
// ---- options (memoized off field.extra) -----------------------------------------------------
|
|
106
|
-
const raw: RawOption[] = Array.isArray(field.extra) ? field.extra : [];
|
|
107
|
-
const options: DropdownOption[] = React.useMemo(
|
|
108
|
-
() =>
|
|
109
|
-
raw.map((o) => {
|
|
110
|
-
const n = normalizeOption(o);
|
|
111
|
-
return { value: n.value, label: labelFor(n.rawLabel), disabled: n.disabled };
|
|
112
|
-
}),
|
|
113
|
-
// field.extra identity changes when the form `.set('extra', …)` runs (make->models).
|
|
114
|
-
[raw, labelFor],
|
|
115
|
-
);
|
|
116
|
-
|
|
117
|
-
const hasError = !!field.hasError && !!field.error;
|
|
118
|
-
const label = field.placeholder ? t(field.placeholder) : field.label ? t(field.label) : '';
|
|
119
|
-
const isDisabled = !!field.disabled || !!disabled;
|
|
120
|
-
|
|
121
|
-
// =========================================================================================
|
|
122
|
-
// MULTI — primitive array value, checklist menu, chips on the trigger.
|
|
123
|
-
// =========================================================================================
|
|
124
|
-
if (isMulti) {
|
|
125
|
-
return (
|
|
126
|
-
<MultiDropdown
|
|
127
|
-
field={field}
|
|
128
|
-
options={options}
|
|
129
|
-
label={hideLabel ? '' : label}
|
|
130
|
-
hasError={hasError}
|
|
131
|
-
disabled={isDisabled}
|
|
132
|
-
ariaLabel={label}
|
|
133
|
-
style={style}
|
|
134
|
-
className={className}
|
|
135
|
-
/>
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// =========================================================================================
|
|
140
|
-
// SINGLE — value is {value,label} (default) or the source object (isObj).
|
|
141
|
-
// =========================================================================================
|
|
142
|
-
// current scalar value to highlight in the menu (legacy reads value.value ?? value).
|
|
143
|
-
const rawValue = field.value;
|
|
144
|
-
const currentValue =
|
|
145
|
-
rawValue && typeof rawValue === 'object'
|
|
146
|
-
? String(rawValue.value != null ? rawValue.value : '')
|
|
147
|
-
: rawValue != null
|
|
148
|
-
? String(rawValue)
|
|
149
|
-
: '';
|
|
150
|
-
|
|
151
|
-
const commit = (next: string) => {
|
|
152
|
-
if (next === '') {
|
|
153
|
-
// clear (only reachable when !disableClearable).
|
|
154
|
-
field.onChange(isObj ? null : '', field.name);
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
if (isObj) {
|
|
158
|
-
// resolve the SOURCE option object out of field.extra (matched by value/key) so
|
|
159
|
-
// form.output keeps receiving the object (GENDERS/TITLES parity).
|
|
160
|
-
const match = raw.find((o) => {
|
|
161
|
-
const n = normalizeOption(o);
|
|
162
|
-
return n.value === next;
|
|
163
|
-
});
|
|
164
|
-
field.onChange(match != null ? match : null, field.name);
|
|
165
|
-
} else {
|
|
166
|
-
// legacy getValue(): commit the {value,label} pair.
|
|
167
|
-
const chosen = options.find((o) => o.value === next);
|
|
168
|
-
field.onChange({ value: next, label: chosen ? chosen.label : next }, field.name);
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
|
|
172
|
-
// a clear option is prepended (mirrors MaterialAutocomplete's clear) unless disabled.
|
|
173
|
-
const menuOptions: DropdownOption[] =
|
|
174
|
-
disableClearable || !currentValue ? options : [{ value: '', label: '—' }, ...options];
|
|
175
|
-
|
|
176
|
-
return (
|
|
177
|
-
<div className={'mfd' + (className ? ' ' + className : '')} style={style}>
|
|
178
|
-
{label && !hideLabel ? <label className="md-label-sm mfield-label mfd-label">{label}</label> : null}
|
|
179
|
-
<Dropdown
|
|
180
|
-
value={currentValue}
|
|
181
|
-
options={menuOptions}
|
|
182
|
-
onChange={commit}
|
|
183
|
-
placeholder={label || '—'}
|
|
184
|
-
ariaLabel={label}
|
|
185
|
-
disabled={isDisabled}
|
|
186
|
-
className={hasError ? 'mfd-invalid' : undefined}
|
|
187
|
-
/>
|
|
188
|
-
{hasError ? <span className="mfield-error-text mfd-error">{field.error}</span> : null}
|
|
189
|
-
</div>
|
|
190
|
-
);
|
|
191
|
-
},
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
// ---------------------------------------------------------------------------------------------
|
|
195
|
-
// Multi-select — built on the same mselect-* classes as the base Dropdown, with a checklist
|
|
196
|
-
// menu and chips on the trigger. Value is a primitive string[] (legacy MaterialSelect parity:
|
|
197
|
-
// onChange(values, field.name); field.output keeps Array.isArray(values) ? values : null).
|
|
198
|
-
// ---------------------------------------------------------------------------------------------
|
|
199
|
-
interface MultiProps {
|
|
200
|
-
field: any;
|
|
201
|
-
options: DropdownOption[];
|
|
202
|
-
label: string;
|
|
203
|
-
hasError: boolean;
|
|
204
|
-
disabled: boolean;
|
|
205
|
-
ariaLabel: string;
|
|
206
|
-
style?: React.CSSProperties;
|
|
207
|
-
className?: string;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
const MultiDropdown: React.FunctionComponent<MultiProps> = observer(
|
|
211
|
-
({ field, options, label, hasError, disabled, ariaLabel, style, className }) => {
|
|
212
|
-
const [open, setOpen] = React.useState(false);
|
|
213
|
-
const rootRef = React.useRef<HTMLDivElement | null>(null);
|
|
214
|
-
const btnRef = React.useRef<HTMLButtonElement | null>(null);
|
|
215
|
-
|
|
216
|
-
const selected: string[] = Array.isArray(field.value) ? field.value.map(String) : [];
|
|
217
|
-
|
|
218
|
-
// click-away (guarded for SSR), matching the base Dropdown.
|
|
219
|
-
React.useEffect(() => {
|
|
220
|
-
if (!open || typeof document === 'undefined') return undefined;
|
|
221
|
-
const onDocMouseDown = (e: MouseEvent) => {
|
|
222
|
-
if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false);
|
|
223
|
-
};
|
|
224
|
-
document.addEventListener('mousedown', onDocMouseDown);
|
|
225
|
-
return () => document.removeEventListener('mousedown', onDocMouseDown);
|
|
226
|
-
}, [open]);
|
|
227
|
-
|
|
228
|
-
const toggle = (value: string) => {
|
|
229
|
-
if (disabled) return;
|
|
230
|
-
const next = selected.indexOf(value) > -1 ? selected.filter((v) => v !== value) : [...selected, value];
|
|
231
|
-
field.onChange(next, field.name);
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
const removeChip = (e: React.MouseEvent, value: string) => {
|
|
235
|
-
e.stopPropagation();
|
|
236
|
-
if (disabled) return;
|
|
237
|
-
field.onChange(selected.filter((v) => v !== value), field.name);
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
const onTriggerKeyDown = (e: React.KeyboardEvent) => {
|
|
241
|
-
if (disabled) return;
|
|
242
|
-
if (e.key === 'Escape') {
|
|
243
|
-
setOpen(false);
|
|
244
|
-
if (btnRef.current) btnRef.current.focus();
|
|
245
|
-
} else if (e.key === 'Tab') {
|
|
246
|
-
setOpen(false);
|
|
247
|
-
} else if (!open && (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ')) {
|
|
248
|
-
e.preventDefault();
|
|
249
|
-
setOpen(true);
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
const labelOf = (value: string) => {
|
|
254
|
-
const o = options.find((opt) => opt.value === value);
|
|
255
|
-
return o ? o.label : value;
|
|
256
|
-
};
|
|
257
|
-
|
|
258
|
-
return (
|
|
259
|
-
<div className={'mfd' + (className ? ' ' + className : '')} style={style}>
|
|
260
|
-
{label ? <label className="md-label-sm mfield-label mfd-label">{label}</label> : null}
|
|
261
|
-
<div className="mselect mselect--block mfd-multi" ref={rootRef}>
|
|
262
|
-
<button
|
|
263
|
-
ref={btnRef}
|
|
264
|
-
type="button"
|
|
265
|
-
className={'mselect-btn mfd-multi-btn' + (hasError ? ' mfd-invalid' : '')}
|
|
266
|
-
aria-haspopup="listbox"
|
|
267
|
-
aria-expanded={open}
|
|
268
|
-
aria-label={ariaLabel}
|
|
269
|
-
disabled={disabled}
|
|
270
|
-
onClick={() => setOpen((o) => !o)}
|
|
271
|
-
onKeyDown={onTriggerKeyDown}
|
|
272
|
-
>
|
|
273
|
-
{selected.length ? (
|
|
274
|
-
<span className="mfd-chips">
|
|
275
|
-
{selected.map((v) => (
|
|
276
|
-
<span className="mfd-chip" key={v}>
|
|
277
|
-
<span className="mfd-chip-label">{labelOf(v)}</span>
|
|
278
|
-
<span
|
|
279
|
-
className="mfd-chip-x"
|
|
280
|
-
role="button"
|
|
281
|
-
tabIndex={-1}
|
|
282
|
-
aria-label="remove"
|
|
283
|
-
onMouseDown={(e) => e.preventDefault()}
|
|
284
|
-
onClick={(e) => removeChip(e, v)}
|
|
285
|
-
>
|
|
286
|
-
<Icon name="x" size={13} />
|
|
287
|
-
</span>
|
|
288
|
-
</span>
|
|
289
|
-
))}
|
|
290
|
-
</span>
|
|
291
|
-
) : (
|
|
292
|
-
<span className="mselect-label mselect-label--ph">{label || '—'}</span>
|
|
293
|
-
)}
|
|
294
|
-
<Icon name="chevron-down" cls="mselect-chev" />
|
|
295
|
-
</button>
|
|
296
|
-
{open && (
|
|
297
|
-
<ul className="mselect-menu mfd-multi-menu" role="listbox" aria-multiselectable="true" tabIndex={-1}>
|
|
298
|
-
{options.map((opt, i) => {
|
|
299
|
-
const checked = selected.indexOf(opt.value) > -1;
|
|
300
|
-
return (
|
|
301
|
-
<li key={`${opt.value}_${i}`} role="presentation">
|
|
302
|
-
<button
|
|
303
|
-
type="button"
|
|
304
|
-
role="option"
|
|
305
|
-
aria-selected={checked}
|
|
306
|
-
disabled={opt.disabled}
|
|
307
|
-
className={'mselect-opt mfd-multi-opt' + (checked ? ' is-checked' : '')}
|
|
308
|
-
onClick={() => toggle(opt.value)}
|
|
309
|
-
>
|
|
310
|
-
<span className={'mfd-check' + (checked ? ' mfd-check--on' : '')}>
|
|
311
|
-
{checked ? <Icon name="check" size={14} /> : null}
|
|
312
|
-
</span>
|
|
313
|
-
<span className="mselect-opt-label">{opt.label}</span>
|
|
314
|
-
</button>
|
|
315
|
-
</li>
|
|
316
|
-
);
|
|
317
|
-
})}
|
|
318
|
-
</ul>
|
|
319
|
-
)}
|
|
320
|
-
</div>
|
|
321
|
-
{hasError ? <span className="mfield-error-text mfd-error">{field.error}</span> : null}
|
|
322
|
-
</div>
|
|
323
|
-
);
|
|
324
|
-
},
|
|
325
|
-
);
|
|
326
|
-
|
|
327
|
-
export default FormDropdown;
|
|
1
|
+
// Autobahn (auto.de redesign) — mobx-react-form-bound dropdown adapter.
|
|
2
|
+
//
|
|
3
|
+
// A drop-in md3 replacement for the legacy fe-ui-core FormDropDown
|
|
4
|
+
// (components/ui/FormDropDown/FormDropDown.tsx). It is the #1 form dependency
|
|
5
|
+
// (11+ pages, 60+ vehicle-form selects: BasicData/EngineData/Chassis/…,
|
|
6
|
+
// Settings gender/title, …). The visual control is the md3 `Dropdown`
|
|
7
|
+
// (single-select) reused as-is; multi-select is implemented here on the same
|
|
8
|
+
// `mselect-*` classes as a checklist with selected chips on the trigger.
|
|
9
|
+
//
|
|
10
|
+
// THE DATA CONTRACT MIRRORS THE LEGACY EXACTLY so validation/output/submit are
|
|
11
|
+
// unchanged — only the markup is re-skinned:
|
|
12
|
+
//
|
|
13
|
+
// • single (default): field.value is the option OBJECT `{value,label}` (legacy
|
|
14
|
+
// `getValue`). We read `field.value.value` and commit
|
|
15
|
+
// `field.onChange({value,label}, field.name)`; clear -> `onChange('', name)`.
|
|
16
|
+
// • isObj: field.value IS the source option object (e.g. a GENDERS item
|
|
17
|
+
// `{value:number,label}`). On change we resolve the matching object out of
|
|
18
|
+
// `field.extra` and `onChange(obj, field.name)` (legacy parity — form.output
|
|
19
|
+
// keeps the object).
|
|
20
|
+
// • isMulti: field.value is a primitive array; the menu is a checklist; the
|
|
21
|
+
// trigger shows the selected labels as chips; `onChange(values, field.name)`.
|
|
22
|
+
//
|
|
23
|
+
// Option shapes in `field.extra` are normalized: primitive lists (['2','3',…]),
|
|
24
|
+
// `{value,label}` and `{key,value}`. Label resolution mirrors the legacy
|
|
25
|
+
// getOptions(): with a namespace, 'cbd' -> t('cbd:'+opt), else a labelled option
|
|
26
|
+
// -> t(namespace+':'+label), else t(opt). When `isApiTranslated`, `field.extra`
|
|
27
|
+
// already carries translated labels, so they are used verbatim.
|
|
28
|
+
//
|
|
29
|
+
// observer-wrapped (re-renders on value/error). Renders correctly only inside a
|
|
30
|
+
// `.md3` subtree.
|
|
31
|
+
|
|
32
|
+
import * as React from 'react';
|
|
33
|
+
import { observer } from 'mobx-react';
|
|
34
|
+
|
|
35
|
+
import Icon from './Icon';
|
|
36
|
+
import Dropdown, { DropdownOption } from './Dropdown';
|
|
37
|
+
|
|
38
|
+
export interface FormDropdownProps {
|
|
39
|
+
/** mobx-react-form field (form.$('basicDataForm.mainData_make') etc.). Untyped — the lib ships no TS types. */
|
|
40
|
+
field: any;
|
|
41
|
+
/** i18n translate — resolves option labels and the field's placeholder/label key. */
|
|
42
|
+
t: (key: string, options?: object) => string;
|
|
43
|
+
/** translation namespace for option labels (e.g. 'common', 'cbd', 'mainData'). */
|
|
44
|
+
namespace?: string;
|
|
45
|
+
/** field.value is the source option OBJECT, not a scalar (GENDERS/TITLES item). */
|
|
46
|
+
isObj?: boolean;
|
|
47
|
+
/** option labels in field.extra are already translated (came from a request). */
|
|
48
|
+
isApiTranslated?: boolean;
|
|
49
|
+
/** multiple selection — value is a primitive array, rendered as chips + checklist. */
|
|
50
|
+
isMulti?: boolean;
|
|
51
|
+
/** hide the clear ("×") affordance on a single select. */
|
|
52
|
+
disableClearable?: boolean;
|
|
53
|
+
/** suppress the built-in label (when an outer wrapper — e.g. FormFieldDropDown — owns the label). */
|
|
54
|
+
hideLabel?: boolean;
|
|
55
|
+
/** accepted for legacy-surface parity (the md3 control never free-types). */
|
|
56
|
+
freeSolo?: boolean;
|
|
57
|
+
disabled?: boolean;
|
|
58
|
+
/** layout passthrough (e.g. grid-area), mirrors legacy `style`. */
|
|
59
|
+
style?: React.CSSProperties;
|
|
60
|
+
/** extra class on the wrapper (legacy `className`). */
|
|
61
|
+
className?: string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Raw option as it can appear in field.extra. */
|
|
65
|
+
type RawOption =
|
|
66
|
+
| string
|
|
67
|
+
| number
|
|
68
|
+
| { value: any; label?: any; key?: any; isDisabled?: boolean; isSeries?: boolean };
|
|
69
|
+
|
|
70
|
+
/** Normalize one raw option to a stable { value, label, disabled } shape (label not yet translated). */
|
|
71
|
+
function normalizeOption(opt: RawOption): { value: string; rawLabel: any; disabled: boolean } {
|
|
72
|
+
if (opt !== null && typeof opt === 'object') {
|
|
73
|
+
// {value,label} | {key,value} | {value,...}
|
|
74
|
+
const hasKey = 'key' in opt && !('label' in opt);
|
|
75
|
+
const value = hasKey ? (opt as any).key : (opt as any).value;
|
|
76
|
+
const rawLabel = hasKey
|
|
77
|
+
? (opt as any).value
|
|
78
|
+
: 'label' in opt && (opt as any).label != null
|
|
79
|
+
? (opt as any).label
|
|
80
|
+
: (opt as any).value;
|
|
81
|
+
const disabled = !!((opt as any).isDisabled || (opt as any).isSeries);
|
|
82
|
+
return { value: String(value), rawLabel, disabled };
|
|
83
|
+
}
|
|
84
|
+
// primitive
|
|
85
|
+
return { value: String(opt), rawLabel: opt, disabled: false };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const FormDropdown: React.FunctionComponent<FormDropdownProps> = observer(
|
|
89
|
+
({ field, t, namespace, isObj, isApiTranslated, isMulti, disableClearable, freeSolo, disabled, style, className, hideLabel }) => {
|
|
90
|
+
// ---- label resolution (legacy getOptions parity) -------------------------------------------
|
|
91
|
+
const labelFor = React.useCallback(
|
|
92
|
+
(rawLabel: any): string => {
|
|
93
|
+
const s = rawLabel == null ? '' : String(rawLabel);
|
|
94
|
+
if (isApiTranslated) return s; // already translated in field.extra
|
|
95
|
+
if (namespace) {
|
|
96
|
+
if (namespace === 'cbd') return t(`cbd:${s}`);
|
|
97
|
+
// a "labelled" option translates under the namespace; a bare primitive translates as-is.
|
|
98
|
+
return t(s) === s ? t(`${namespace}:${s}`) : t(s);
|
|
99
|
+
}
|
|
100
|
+
return t(s);
|
|
101
|
+
},
|
|
102
|
+
[t, namespace, isApiTranslated],
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
// ---- options (memoized off field.extra) -----------------------------------------------------
|
|
106
|
+
const raw: RawOption[] = Array.isArray(field.extra) ? field.extra : [];
|
|
107
|
+
const options: DropdownOption[] = React.useMemo(
|
|
108
|
+
() =>
|
|
109
|
+
raw.map((o) => {
|
|
110
|
+
const n = normalizeOption(o);
|
|
111
|
+
return { value: n.value, label: labelFor(n.rawLabel), disabled: n.disabled };
|
|
112
|
+
}),
|
|
113
|
+
// field.extra identity changes when the form `.set('extra', …)` runs (make->models).
|
|
114
|
+
[raw, labelFor],
|
|
115
|
+
);
|
|
116
|
+
|
|
117
|
+
const hasError = !!field.hasError && !!field.error;
|
|
118
|
+
const label = field.placeholder ? t(field.placeholder) : field.label ? t(field.label) : '';
|
|
119
|
+
const isDisabled = !!field.disabled || !!disabled;
|
|
120
|
+
|
|
121
|
+
// =========================================================================================
|
|
122
|
+
// MULTI — primitive array value, checklist menu, chips on the trigger.
|
|
123
|
+
// =========================================================================================
|
|
124
|
+
if (isMulti) {
|
|
125
|
+
return (
|
|
126
|
+
<MultiDropdown
|
|
127
|
+
field={field}
|
|
128
|
+
options={options}
|
|
129
|
+
label={hideLabel ? '' : label}
|
|
130
|
+
hasError={hasError}
|
|
131
|
+
disabled={isDisabled}
|
|
132
|
+
ariaLabel={label}
|
|
133
|
+
style={style}
|
|
134
|
+
className={className}
|
|
135
|
+
/>
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// =========================================================================================
|
|
140
|
+
// SINGLE — value is {value,label} (default) or the source object (isObj).
|
|
141
|
+
// =========================================================================================
|
|
142
|
+
// current scalar value to highlight in the menu (legacy reads value.value ?? value).
|
|
143
|
+
const rawValue = field.value;
|
|
144
|
+
const currentValue =
|
|
145
|
+
rawValue && typeof rawValue === 'object'
|
|
146
|
+
? String(rawValue.value != null ? rawValue.value : '')
|
|
147
|
+
: rawValue != null
|
|
148
|
+
? String(rawValue)
|
|
149
|
+
: '';
|
|
150
|
+
|
|
151
|
+
const commit = (next: string) => {
|
|
152
|
+
if (next === '') {
|
|
153
|
+
// clear (only reachable when !disableClearable).
|
|
154
|
+
field.onChange(isObj ? null : '', field.name);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (isObj) {
|
|
158
|
+
// resolve the SOURCE option object out of field.extra (matched by value/key) so
|
|
159
|
+
// form.output keeps receiving the object (GENDERS/TITLES parity).
|
|
160
|
+
const match = raw.find((o) => {
|
|
161
|
+
const n = normalizeOption(o);
|
|
162
|
+
return n.value === next;
|
|
163
|
+
});
|
|
164
|
+
field.onChange(match != null ? match : null, field.name);
|
|
165
|
+
} else {
|
|
166
|
+
// legacy getValue(): commit the {value,label} pair.
|
|
167
|
+
const chosen = options.find((o) => o.value === next);
|
|
168
|
+
field.onChange({ value: next, label: chosen ? chosen.label : next }, field.name);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// a clear option is prepended (mirrors MaterialAutocomplete's clear) unless disabled.
|
|
173
|
+
const menuOptions: DropdownOption[] =
|
|
174
|
+
disableClearable || !currentValue ? options : [{ value: '', label: '—' }, ...options];
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
<div className={'mfd' + (className ? ' ' + className : '')} style={style}>
|
|
178
|
+
{label && !hideLabel ? <label className="md-label-sm mfield-label mfd-label">{label}</label> : null}
|
|
179
|
+
<Dropdown
|
|
180
|
+
value={currentValue}
|
|
181
|
+
options={menuOptions}
|
|
182
|
+
onChange={commit}
|
|
183
|
+
placeholder={label || '—'}
|
|
184
|
+
ariaLabel={label}
|
|
185
|
+
disabled={isDisabled}
|
|
186
|
+
className={hasError ? 'mfd-invalid' : undefined}
|
|
187
|
+
/>
|
|
188
|
+
{hasError ? <span className="mfield-error-text mfd-error">{field.error}</span> : null}
|
|
189
|
+
</div>
|
|
190
|
+
);
|
|
191
|
+
},
|
|
192
|
+
);
|
|
193
|
+
|
|
194
|
+
// ---------------------------------------------------------------------------------------------
|
|
195
|
+
// Multi-select — built on the same mselect-* classes as the base Dropdown, with a checklist
|
|
196
|
+
// menu and chips on the trigger. Value is a primitive string[] (legacy MaterialSelect parity:
|
|
197
|
+
// onChange(values, field.name); field.output keeps Array.isArray(values) ? values : null).
|
|
198
|
+
// ---------------------------------------------------------------------------------------------
|
|
199
|
+
interface MultiProps {
|
|
200
|
+
field: any;
|
|
201
|
+
options: DropdownOption[];
|
|
202
|
+
label: string;
|
|
203
|
+
hasError: boolean;
|
|
204
|
+
disabled: boolean;
|
|
205
|
+
ariaLabel: string;
|
|
206
|
+
style?: React.CSSProperties;
|
|
207
|
+
className?: string;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const MultiDropdown: React.FunctionComponent<MultiProps> = observer(
|
|
211
|
+
({ field, options, label, hasError, disabled, ariaLabel, style, className }) => {
|
|
212
|
+
const [open, setOpen] = React.useState(false);
|
|
213
|
+
const rootRef = React.useRef<HTMLDivElement | null>(null);
|
|
214
|
+
const btnRef = React.useRef<HTMLButtonElement | null>(null);
|
|
215
|
+
|
|
216
|
+
const selected: string[] = Array.isArray(field.value) ? field.value.map(String) : [];
|
|
217
|
+
|
|
218
|
+
// click-away (guarded for SSR), matching the base Dropdown.
|
|
219
|
+
React.useEffect(() => {
|
|
220
|
+
if (!open || typeof document === 'undefined') return undefined;
|
|
221
|
+
const onDocMouseDown = (e: MouseEvent) => {
|
|
222
|
+
if (rootRef.current && !rootRef.current.contains(e.target as Node)) setOpen(false);
|
|
223
|
+
};
|
|
224
|
+
document.addEventListener('mousedown', onDocMouseDown);
|
|
225
|
+
return () => document.removeEventListener('mousedown', onDocMouseDown);
|
|
226
|
+
}, [open]);
|
|
227
|
+
|
|
228
|
+
const toggle = (value: string) => {
|
|
229
|
+
if (disabled) return;
|
|
230
|
+
const next = selected.indexOf(value) > -1 ? selected.filter((v) => v !== value) : [...selected, value];
|
|
231
|
+
field.onChange(next, field.name);
|
|
232
|
+
};
|
|
233
|
+
|
|
234
|
+
const removeChip = (e: React.MouseEvent, value: string) => {
|
|
235
|
+
e.stopPropagation();
|
|
236
|
+
if (disabled) return;
|
|
237
|
+
field.onChange(selected.filter((v) => v !== value), field.name);
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
const onTriggerKeyDown = (e: React.KeyboardEvent) => {
|
|
241
|
+
if (disabled) return;
|
|
242
|
+
if (e.key === 'Escape') {
|
|
243
|
+
setOpen(false);
|
|
244
|
+
if (btnRef.current) btnRef.current.focus();
|
|
245
|
+
} else if (e.key === 'Tab') {
|
|
246
|
+
setOpen(false);
|
|
247
|
+
} else if (!open && (e.key === 'ArrowDown' || e.key === 'Enter' || e.key === ' ')) {
|
|
248
|
+
e.preventDefault();
|
|
249
|
+
setOpen(true);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
const labelOf = (value: string) => {
|
|
254
|
+
const o = options.find((opt) => opt.value === value);
|
|
255
|
+
return o ? o.label : value;
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
return (
|
|
259
|
+
<div className={'mfd' + (className ? ' ' + className : '')} style={style}>
|
|
260
|
+
{label ? <label className="md-label-sm mfield-label mfd-label">{label}</label> : null}
|
|
261
|
+
<div className="mselect mselect--block mfd-multi" ref={rootRef}>
|
|
262
|
+
<button
|
|
263
|
+
ref={btnRef}
|
|
264
|
+
type="button"
|
|
265
|
+
className={'mselect-btn mfd-multi-btn' + (hasError ? ' mfd-invalid' : '')}
|
|
266
|
+
aria-haspopup="listbox"
|
|
267
|
+
aria-expanded={open}
|
|
268
|
+
aria-label={ariaLabel}
|
|
269
|
+
disabled={disabled}
|
|
270
|
+
onClick={() => setOpen((o) => !o)}
|
|
271
|
+
onKeyDown={onTriggerKeyDown}
|
|
272
|
+
>
|
|
273
|
+
{selected.length ? (
|
|
274
|
+
<span className="mfd-chips">
|
|
275
|
+
{selected.map((v) => (
|
|
276
|
+
<span className="mfd-chip" key={v}>
|
|
277
|
+
<span className="mfd-chip-label">{labelOf(v)}</span>
|
|
278
|
+
<span
|
|
279
|
+
className="mfd-chip-x"
|
|
280
|
+
role="button"
|
|
281
|
+
tabIndex={-1}
|
|
282
|
+
aria-label="remove"
|
|
283
|
+
onMouseDown={(e) => e.preventDefault()}
|
|
284
|
+
onClick={(e) => removeChip(e, v)}
|
|
285
|
+
>
|
|
286
|
+
<Icon name="x" size={13} />
|
|
287
|
+
</span>
|
|
288
|
+
</span>
|
|
289
|
+
))}
|
|
290
|
+
</span>
|
|
291
|
+
) : (
|
|
292
|
+
<span className="mselect-label mselect-label--ph">{label || '—'}</span>
|
|
293
|
+
)}
|
|
294
|
+
<Icon name="chevron-down" cls="mselect-chev" />
|
|
295
|
+
</button>
|
|
296
|
+
{open && (
|
|
297
|
+
<ul className="mselect-menu mfd-multi-menu" role="listbox" aria-multiselectable="true" tabIndex={-1}>
|
|
298
|
+
{options.map((opt, i) => {
|
|
299
|
+
const checked = selected.indexOf(opt.value) > -1;
|
|
300
|
+
return (
|
|
301
|
+
<li key={`${opt.value}_${i}`} role="presentation">
|
|
302
|
+
<button
|
|
303
|
+
type="button"
|
|
304
|
+
role="option"
|
|
305
|
+
aria-selected={checked}
|
|
306
|
+
disabled={opt.disabled}
|
|
307
|
+
className={'mselect-opt mfd-multi-opt' + (checked ? ' is-checked' : '')}
|
|
308
|
+
onClick={() => toggle(opt.value)}
|
|
309
|
+
>
|
|
310
|
+
<span className={'mfd-check' + (checked ? ' mfd-check--on' : '')}>
|
|
311
|
+
{checked ? <Icon name="check" size={14} /> : null}
|
|
312
|
+
</span>
|
|
313
|
+
<span className="mselect-opt-label">{opt.label}</span>
|
|
314
|
+
</button>
|
|
315
|
+
</li>
|
|
316
|
+
);
|
|
317
|
+
})}
|
|
318
|
+
</ul>
|
|
319
|
+
)}
|
|
320
|
+
</div>
|
|
321
|
+
{hasError ? <span className="mfield-error-text mfd-error">{field.error}</span> : null}
|
|
322
|
+
</div>
|
|
323
|
+
);
|
|
324
|
+
},
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
export default FormDropdown;
|