@evolve.ui/core-components 1.0.0 → 1.1.0
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/Checkbox.d.cts +1 -1
- package/Checkbox.d.mts +1 -1
- package/{DateInput-B8XQZPTx.d.cts → DateInput-CFxTZu3m.d.mts} +2 -2
- package/{DateInput-B8XQZPTx.d.cts.map → DateInput-CFxTZu3m.d.mts.map} +1 -1
- package/{DateInput-CfNmywqQ.d.mts → DateInput-DstMICTl.d.cts} +2 -2
- package/{DateInput-CfNmywqQ.d.mts.map → DateInput-DstMICTl.d.cts.map} +1 -1
- package/{FavoriteButton-CowOPoqo.d.cts → FavoriteButton-BGF-3dze.d.cts} +2 -2
- package/{FavoriteButton-BRY8FVpV.d.mts.map → FavoriteButton-BGF-3dze.d.cts.map} +1 -1
- package/{FavoriteButton-BRY8FVpV.d.mts → FavoriteButton-BZEGWrRo.d.mts} +2 -2
- package/{FavoriteButton-CowOPoqo.d.cts.map → FavoriteButton-BZEGWrRo.d.mts.map} +1 -1
- package/Input.d.cts +1 -1
- package/Input.d.mts +1 -1
- package/Radio.d.cts +1 -1
- package/Radio.d.mts +1 -1
- package/{TextInput-BhkeQZh4.d.cts → TextInput-B7lqQ1gh.d.cts} +3 -3
- package/{TextInput-BhkeQZh4.d.cts.map → TextInput-B7lqQ1gh.d.cts.map} +1 -1
- package/{TextInput-CWCeR18b.d.mts → TextInput-CxoT3np_.d.mts} +3 -3
- package/{TextInput-CWCeR18b.d.mts.map → TextInput-CxoT3np_.d.mts.map} +1 -1
- package/dateInput.d.cts +1 -1
- package/dateInput.d.mts +1 -1
- package/datePicker.d.cts +1 -1
- package/datePicker.d.mts +1 -1
- package/evolve-ui.entries.json +556 -0
- package/favoriteButton.d.cts +1 -1
- package/favoriteButton.d.mts +1 -1
- package/featureFlags/hooks.d.cts +1 -1
- package/featureFlags/hooks.d.mts +1 -1
- package/fileUpload/testUtils/mockFilesAndImages.d.cts +3 -3
- package/fileUpload/testUtils/mockFilesAndImages.d.cts.map +1 -1
- package/fileUpload/testUtils/mockFilesAndImages.d.mts +3 -3
- package/fileUpload/testUtils/mockFilesAndImages.d.mts.map +1 -1
- package/fileUpload/testUtils/testUtils.d.cts +1 -1
- package/fileUpload/testUtils/testUtils.d.cts.map +1 -1
- package/fileUpload/testUtils/testUtils.d.mts +1 -1
- package/fileUpload/testUtils/testUtils.d.mts.map +1 -1
- package/{index-BVb-FJDo.d.mts → index-BYPklw8m.d.mts} +2 -2
- package/{index-BVb-FJDo.d.mts.map → index-BYPklw8m.d.mts.map} +1 -1
- package/{index-3V0Y3AU3.d.mts → index-Bvn6svaT.d.cts} +2 -2
- package/{index-3V0Y3AU3.d.mts.map → index-Bvn6svaT.d.cts.map} +1 -1
- package/{index-Bu7c6X7O.d.mts → index-C2zPeUs9.d.mts} +5 -5
- package/{index-Bu7c6X7O.d.mts.map → index-C2zPeUs9.d.mts.map} +1 -1
- package/{index-BXz3rMMk.d.cts → index-Cmz2OD6x.d.cts} +2 -2
- package/{index-BXz3rMMk.d.cts.map → index-Cmz2OD6x.d.cts.map} +1 -1
- package/{index-kchg551L.d.cts → index-DsZAxqnF.d.mts} +2 -2
- package/{index-kchg551L.d.cts.map → index-DsZAxqnF.d.mts.map} +1 -1
- package/{index-BzN9RaXe.d.cts → index-QtMvgJcp.d.cts} +5 -5
- package/{index-BzN9RaXe.d.cts.map → index-QtMvgJcp.d.cts.map} +1 -1
- package/{index-dpfLYhgI.d.mts → index-hrztez-b.d.mts} +2 -2
- package/{index-DBYqF9Sr.d.cts.map → index-hrztez-b.d.mts.map} +1 -1
- package/{index-DBYqF9Sr.d.cts → index-o9dwzLLE.d.cts} +2 -2
- package/{index-dpfLYhgI.d.mts.map → index-o9dwzLLE.d.cts.map} +1 -1
- package/index.d.cts +7 -7
- package/index.d.mts +7 -7
- package/package.json +2 -2
- package/providers.d.cts +1 -1
- package/providers.d.mts +1 -1
- package/src/Accordion/Accordion.tsx +233 -0
- package/src/AddressDisplay/AddressDisplay.tsx +43 -0
- package/src/AddressDisplay/components/addressComponents.tsx +111 -0
- package/src/AddressDisplay/components/addressField.tsx +25 -0
- package/src/AddressDisplay/components/addressSection.tsx +8 -0
- package/src/AddressDisplay/components/getCountryValue.tsx +31 -0
- package/src/AddressDisplay/types.ts +26 -0
- package/src/AutomatedCarousel/AutomatedCarousel.tsx +163 -0
- package/src/AutomatedCarousel/automatedCarousel.types.ts +7 -0
- package/src/AutomatedCarousel/components/CarouselProgressBar/CarouselProgressBar.tsx +139 -0
- package/src/AutomatedCarousel/components/CarouselProgressBar/components/CarouselProgressBarUnit/CarouselProgressBarUnit.tsx +165 -0
- package/src/Badge/Badge.tsx +104 -0
- package/src/Badge/Badge.types.ts +58 -0
- package/src/Badge/ItemBadge.tsx +97 -0
- package/src/Badge/LiveStatusBadge.tsx +93 -0
- package/src/BannerNotification/BannerNotification.tsx +157 -0
- package/src/BannerNotification/components/BannerNotificationSkeleton.tsx +39 -0
- package/src/BannerNotification/components/CalloutIcon/BannerIcon.tsx +48 -0
- package/src/BannerNotification/utils/getRandomTooltipId.ts +3 -0
- package/src/BottomSheet/BottomSheet.tsx +476 -0
- package/src/BottomSheet/components/BottomSheetBackdrop/BottomSheetBackdrop.tsx +47 -0
- package/src/BottomSheet/components/BottomSheetContentArea/BottomSheetContentArea.tsx +92 -0
- package/src/BottomSheet/components/BottomSheetOverlay/BottomSheetOverlayTranslate3d.tsx +196 -0
- package/src/BottomSheet/components/SheetDescription/SheetDescription.tsx +22 -0
- package/src/BottomSheet/components/SheetTitle/SheetTitle.tsx +21 -0
- package/src/BottomSheet/components/index.tsx +5 -0
- package/src/BottomSheet/hooks/index.tsx +13 -0
- package/src/BottomSheet/hooks/useAriaHider.tsx +91 -0
- package/src/BottomSheet/hooks/useBottomSheetServices.tsx +224 -0
- package/src/BottomSheet/hooks/useDragHandler.tsx +282 -0
- package/src/BottomSheet/hooks/useFocusTrap.tsx +113 -0
- package/src/BottomSheet/hooks/useLayoutEffect.tsx +4 -0
- package/src/BottomSheet/hooks/useOptimizedResizeObserver.tsx +94 -0
- package/src/BottomSheet/hooks/useOptimizedScrollState.tsx +87 -0
- package/src/BottomSheet/hooks/useReady.tsx +34 -0
- package/src/BottomSheet/hooks/useReducedMotion.tsx +22 -0
- package/src/BottomSheet/hooks/useScrollLock.tsx +143 -0
- package/src/BottomSheet/hooks/useSnapPoints.tsx +355 -0
- package/src/BottomSheet/hooks/useSpring.tsx +47 -0
- package/src/BottomSheet/hooks/useSpringInterpolationsTranslate3d.tsx +101 -0
- package/src/BottomSheet/index.tsx +237 -0
- package/src/BottomSheet/state/atoms.ts +147 -0
- package/src/BottomSheet/state/useBottomSheetStateMachine.ts +246 -0
- package/src/BottomSheet/types.ts +172 -0
- package/src/BottomSheet/utils.ts +65 -0
- package/src/Breadcrumbs/Breadcrumbs.tsx +126 -0
- package/src/Button/Button.tsx +164 -0
- package/src/Button/Button.types.ts +80 -0
- package/src/Button/buttonColorClasses.ts +53 -0
- package/src/Callout/Callout.tsx +136 -0
- package/src/Callout/Callout.types.ts +29 -0
- package/src/Callout/components/CalloutIcon/CalloutIcon.tsx +56 -0
- package/src/Card/CardGrid.tsx +263 -0
- package/src/Card/SingleCard.tsx +22 -0
- package/src/Card/cardFactory.tsx +176 -0
- package/src/Card/components/createBadge.tsx +34 -0
- package/src/Card/components/createFavoriteButton.tsx +40 -0
- package/src/Card/components/createImage.tsx +64 -0
- package/src/Card/components/createInfo.tsx +84 -0
- package/src/Card/components/createName.tsx +63 -0
- package/src/Card/components/createPriceStatus.tsx +100 -0
- package/src/Card/components/types.ts +4 -0
- package/src/Card/hooks/useCardVisibilityTracking.ts +82 -0
- package/src/Card/sharedProps.ts +12 -0
- package/src/Card/types.ts +62 -0
- package/src/Carousel/Carousel.tsx +513 -0
- package/src/Carousel/Carousel.types.ts +43 -0
- package/src/Carousel/Carousel.utils.ts +63 -0
- package/src/Carousel/components/DotButton/DotButton.tsx +42 -0
- package/src/Carousel/components/NavigationButtons/NavigationButtons.tsx +77 -0
- package/src/Carousel/components/TitleSection/TitleSection.tsx +61 -0
- package/src/Carousel/components/TitleSection/components/SubHeaderLeft/SubHeaderLeft.tsx +53 -0
- package/src/Carousel/components/TitleSection/components/Title/Title.tsx +46 -0
- package/src/Carousel/index.ts +2 -0
- package/src/Carousel/testUtils.ts +10 -0
- package/src/Chips/Chip.tsx +153 -0
- package/src/Chips/ChipGroup.tsx +173 -0
- package/src/Chips/SuggestionChip.tsx +15 -0
- package/src/Chips/chipTypes.ts +113 -0
- package/src/Chips/index.ts +4 -0
- package/src/ChoiceListItem/Checkbox.tsx +69 -0
- package/src/ChoiceListItem/Radio.tsx +61 -0
- package/src/ChoiceListItem/choiceListItem.tsx +99 -0
- package/src/ChoiceListItem/common.tsx +148 -0
- package/src/ChoiceListItem/index.ts +3 -0
- package/src/Collapsible/Collapsible.tsx +58 -0
- package/src/Confetti/Confetti.tsx +270 -0
- package/src/Confetti/index.ts +2 -0
- package/src/ContentPager/ContentPager.tsx +189 -0
- package/src/ContentPager/components/Page.tsx +24 -0
- package/src/CookieConsent/components/CookieCategoryRow/CookieCategoryRow.tsx +30 -0
- package/src/CookieConsent/components/CookieConsent/CookieConsent.tsx +74 -0
- package/src/CookieConsent/components/CookieConsentBanner/CookieConsentBanner.tsx +51 -0
- package/src/CookieConsent/components/CookieConsentModal/CookieConsentModal.tsx +64 -0
- package/src/CookieConsent/hooks/useCookieConsent.ts +170 -0
- package/src/CookieConsent/hooks/useCookieConsentState.ts +142 -0
- package/src/CookieConsent/index.ts +16 -0
- package/src/CookieConsent/types/cookieConsent.types.ts +79 -0
- package/src/CookieConsent/types/index.ts +7 -0
- package/src/Countdown/Countdown.tsx +161 -0
- package/src/Countdown/Countdown.types.ts +4 -0
- package/src/Countdown/hooks/useGetCountdown.ts +103 -0
- package/src/DateTimeInput/dateInput/DateInput.tsx +199 -0
- package/src/DateTimeInput/datePicker/DatePicker.tsx +138 -0
- package/src/DateTimeInput/datePicker/components/calendar/Calendar.tsx +72 -0
- package/src/DateTimeInput/datePicker/index.ts +2 -0
- package/src/DateTimeInput/timeInput/TimeInput.tsx +128 -0
- package/src/DateTimeInput/timePicker/TimePicker.tsx +118 -0
- package/src/DateTimeInput/timePicker/components/TimePopover/AmPmSwitch.tsx +103 -0
- package/src/DateTimeInput/timePicker/components/TimePopover/TimeFieldInput.tsx +26 -0
- package/src/DateTimeInput/timePicker/components/TimePopover/TimePopover.tsx +84 -0
- package/src/DateTimeInput/timePicker/components/TimePopover/TimePopover.utils.ts +67 -0
- package/src/DateTimeInput/timePicker/components/TimePopover/TimePopoverActions.tsx +26 -0
- package/src/DateTimeInput/timePicker/index.ts +2 -0
- package/src/DateTimeInput/utils/getDisplayDate.ts +15 -0
- package/src/DateTimeInput/utils/getDisplayTime.ts +15 -0
- package/src/DateTimeInput/utils/index.ts +2 -0
- package/src/DateTimeInput/utils/parseTimeValue.ts +54 -0
- package/src/Drawer/Drawer.tsx +446 -0
- package/src/Drawer/atoms.ts +4 -0
- package/src/Drawer/components/DialogActions/DialogActions.tsx +33 -0
- package/src/Drawer/components/DialogContent/DialogContent.tsx +80 -0
- package/src/Drawer/components/DialogHeader/DialogHeader.tsx +68 -0
- package/src/EducationalPopover/EducationalPopover.tsx +174 -0
- package/src/FavoriteButton/FavoriteButton.tsx +64 -0
- package/src/FavoriteButton/components/IconOnlyFavoriteButton/IconOnlyFavoriteButton.tsx +80 -0
- package/src/FavoriteButton/components/LabeledAnimatedFavoriteButton/LabeledAnimatedFavoriteButton.tsx +179 -0
- package/src/FavoriteButton/components/LabeledFavoriteButton/LabeledFavoriteButton.tsx +71 -0
- package/src/FavoriteButton/components/SmallHeartStraightIcon/SmallHeartStraightIcon.tsx +14 -0
- package/src/FavoriteButton/hooks/useFavoriteButtonState.ts +30 -0
- package/src/FavoriteButton/index.ts +2 -0
- package/src/FavoriteButton/types/favoriteButton.ts +87 -0
- package/src/FeatureFlags/devTools/FeatureFlagDevToolsUI.tsx +226 -0
- package/src/FeatureFlags/devTools/getFeatureFlagCookieOverrides.ts +30 -0
- package/src/FeatureFlags/devTools/utils/cookies.ts +169 -0
- package/src/FeatureFlags/hooks/index.ts +2 -0
- package/src/FeatureFlags/hooks/useFeatureFlag.tsx +19 -0
- package/src/FeatureFlags/hooks/useFeatureFlags.tsx +15 -0
- package/src/FileUpload/components/FileCard/FileCard.tsx +50 -0
- package/src/FileUpload/components/FileDropzone/FileDropzone.tsx +221 -0
- package/src/FileUpload/components/FileDropzone/components/DropzoneContent/DropzoneContent.tsx +28 -0
- package/src/FileUpload/components/FileDropzone/components/DropzoneContent/DropzoneText.tsx +81 -0
- package/src/FileUpload/components/FileDropzone/components/FileDropzoneDebugger/FileDropzoneDebugger.tsx +40 -0
- package/src/FileUpload/components/FileDropzone/components/FileDropzoneDebugger/FileRejectionsDisplay.tsx +110 -0
- package/src/FileUpload/components/FileDropzoneOverlay/FileDropzoneOverlay.tsx +183 -0
- package/src/FileUpload/components/FileDropzoneOverlay/components/OverlayDropzoneContent.tsx +146 -0
- package/src/FileUpload/components/FileDropzoneOverlay/components/OverlayDropzoneDragText.tsx +42 -0
- package/src/FileUpload/components/FileDropzoneOverlay/styles.ts +79 -0
- package/src/FileUpload/components/FilePreviewList/FilePreviewList.tsx +251 -0
- package/src/FileUpload/components/FilePreviewList/virtualizerComponents/FilePreviewVirtualizedList/FilePreviewVirtualizedList.tsx +88 -0
- package/src/FileUpload/components/FileUpload/FileUpload.tsx +63 -0
- package/src/FileUpload/components/FileUploadCanvas/FileUploadCanvas.tsx +125 -0
- package/src/FileUpload/components/GridFileCard/GridFileCard.tsx +364 -0
- package/src/FileUpload/components/GridFileCard/utils/sortable.ts +48 -0
- package/src/FileUpload/components/ListFileCard/ListFileCard.tsx +259 -0
- package/src/FileUpload/components/types.ts +78 -0
- package/src/FileUpload/hooks/filePreview/useImageFilePreviewUrl.ts +62 -0
- package/src/FileUpload/hooks/index.ts +11 -0
- package/src/FileUpload/hooks/upload/useHandleDragEnter/useHandleDragEnter.ts +154 -0
- package/src/FileUpload/hooks/upload/useHandleDrop/createFileRejectionHelpers.ts +273 -0
- package/src/FileUpload/hooks/upload/useHandleDrop/useHandleDrop.ts +153 -0
- package/src/FileUpload/hooks/upload/useUploadAvailability/useUploadAvailability.ts +44 -0
- package/src/FileUpload/hooks/validation/createDropzoneValidator.ts +41 -0
- package/src/FileUpload/hooks/validation/useFileValidation.ts +25 -0
- package/src/FileUpload/hooks/validation/useFileValidationLogic.ts +107 -0
- package/src/FileUpload/hooks/validation/useValidationMessages.ts +92 -0
- package/src/FileUpload/hooks/validation/useValidationState.ts +171 -0
- package/src/FileUpload/index.ts +57 -0
- package/src/FileUpload/providers/FileUploadProvider.tsx +219 -0
- package/src/FileUpload/providers/UploadValidationProvider.tsx +159 -0
- package/src/FileUpload/testUtils/mockFilesAndImages.ts +64 -0
- package/src/FileUpload/testUtils/testUtils.ts +111 -0
- package/src/FileUpload/types/commonTypes.ts +267 -0
- package/src/FileUpload/types/index.ts +31 -0
- package/src/FileUpload/types/sharedTypes.ts +159 -0
- package/src/FileUpload/utils/constants.ts +79 -0
- package/src/FileUpload/utils/createMessageContext.ts +180 -0
- package/src/FileUpload/utils/getFileExtensionsFromAcceptedTypes.ts +73 -0
- package/src/FileUpload/utils/getFilePluralizationText.ts +68 -0
- package/src/FileUpload/utils/getMimeTypes.ts +26 -0
- package/src/FileUpload/utils/messageUtils.ts +41 -0
- package/src/FileUpload/utils/styles.ts +68 -0
- package/src/FormLabel/FormLabel.tsx +212 -0
- package/src/IconButton/IconButton.tsx +154 -0
- package/src/Icons/CreditCardIcon/CreditCardIcon.tsx +73 -0
- package/src/Icons/CreditCardIcon/cardIcons.tsx +270 -0
- package/src/Icons/IconBase.tsx +133 -0
- package/src/Icons/anyIcon.ts +3 -0
- package/src/Icons/generatedIcons/Archive.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowClockwise.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowDown.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowLeft.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowRight.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowSquareOut.tsx +51 -0
- package/src/Icons/generatedIcons/ArrowSquareRight.tsx +51 -0
- package/src/Icons/generatedIcons/ArrowUp.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowsCounterClockwise.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowsLeftRight.tsx +48 -0
- package/src/Icons/generatedIcons/ArrowsOutCardinal.tsx +48 -0
- package/src/Icons/generatedIcons/Bank.tsx +48 -0
- package/src/Icons/generatedIcons/Bell.tsx +51 -0
- package/src/Icons/generatedIcons/BookBookmark.tsx +51 -0
- package/src/Icons/generatedIcons/BookmarksSimple.tsx +51 -0
- package/src/Icons/generatedIcons/Broadcast.tsx +48 -0
- package/src/Icons/generatedIcons/CalendarBlank.tsx +48 -0
- package/src/Icons/generatedIcons/CalendarStar.tsx +51 -0
- package/src/Icons/generatedIcons/Camera.tsx +51 -0
- package/src/Icons/generatedIcons/CaretDown.tsx +48 -0
- package/src/Icons/generatedIcons/CaretLeft.tsx +48 -0
- package/src/Icons/generatedIcons/CaretRight.tsx +48 -0
- package/src/Icons/generatedIcons/CaretUp.tsx +48 -0
- package/src/Icons/generatedIcons/Certificate.tsx +51 -0
- package/src/Icons/generatedIcons/ChartBar.tsx +48 -0
- package/src/Icons/generatedIcons/Check.tsx +51 -0
- package/src/Icons/generatedIcons/CheckCircle.tsx +48 -0
- package/src/Icons/generatedIcons/CirclesFour.tsx +51 -0
- package/src/Icons/generatedIcons/Clock.tsx +48 -0
- package/src/Icons/generatedIcons/ClockCountdown.tsx +48 -0
- package/src/Icons/generatedIcons/Close.tsx +51 -0
- package/src/Icons/generatedIcons/CloudArrowUp.tsx +51 -0
- package/src/Icons/generatedIcons/CloudWarning.tsx +51 -0
- package/src/Icons/generatedIcons/Code.tsx +48 -0
- package/src/Icons/generatedIcons/Compass.tsx +51 -0
- package/src/Icons/generatedIcons/Confetti.tsx +51 -0
- package/src/Icons/generatedIcons/Copy.tsx +48 -0
- package/src/Icons/generatedIcons/CornersOut.tsx +48 -0
- package/src/Icons/generatedIcons/CreditCard.tsx +48 -0
- package/src/Icons/generatedIcons/Crown.tsx +51 -0
- package/src/Icons/generatedIcons/CrownSimple.tsx +51 -0
- package/src/Icons/generatedIcons/CurrencyCircleDollar.tsx +48 -0
- package/src/Icons/generatedIcons/CurrencyDollarSimple.tsx +51 -0
- package/src/Icons/generatedIcons/Desktop.tsx +51 -0
- package/src/Icons/generatedIcons/Detective.tsx +51 -0
- package/src/Icons/generatedIcons/DotOutline.tsx +46 -0
- package/src/Icons/generatedIcons/DotsSixVertical.tsx +51 -0
- package/src/Icons/generatedIcons/DotsThreeOutline.tsx +51 -0
- package/src/Icons/generatedIcons/DotsThreeOutlineVertical.tsx +51 -0
- package/src/Icons/generatedIcons/DownloadSimple.tsx +51 -0
- package/src/Icons/generatedIcons/EnvelopeSimple.tsx +48 -0
- package/src/Icons/generatedIcons/Eraser.tsx +51 -0
- package/src/Icons/generatedIcons/Eye.tsx +51 -0
- package/src/Icons/generatedIcons/EyeSlash.tsx +51 -0
- package/src/Icons/generatedIcons/FacebookLogo.tsx +48 -0
- package/src/Icons/generatedIcons/FileArchive.tsx +48 -0
- package/src/Icons/generatedIcons/FileArrowDown.tsx +48 -0
- package/src/Icons/generatedIcons/FileCsv.tsx +48 -0
- package/src/Icons/generatedIcons/FilePdf.tsx +48 -0
- package/src/Icons/generatedIcons/FileText.tsx +48 -0
- package/src/Icons/generatedIcons/Files.tsx +51 -0
- package/src/Icons/generatedIcons/Fire.tsx +51 -0
- package/src/Icons/generatedIcons/Flag.tsx +51 -0
- package/src/Icons/generatedIcons/FlagBannerFold.tsx +48 -0
- package/src/Icons/generatedIcons/FloppyDisk.tsx +51 -0
- package/src/Icons/generatedIcons/Gauge.tsx +51 -0
- package/src/Icons/generatedIcons/Gavel.tsx +51 -0
- package/src/Icons/generatedIcons/Gear.tsx +51 -0
- package/src/Icons/generatedIcons/GlobeHemisphereWest.tsx +51 -0
- package/src/Icons/generatedIcons/GoogleLogo.tsx +48 -0
- package/src/Icons/generatedIcons/GridNine.tsx +51 -0
- package/src/Icons/generatedIcons/HandCoins.tsx +51 -0
- package/src/Icons/generatedIcons/HandbagSimple.tsx +51 -0
- package/src/Icons/generatedIcons/Headset.tsx +51 -0
- package/src/Icons/generatedIcons/HeartStraight.tsx +51 -0
- package/src/Icons/generatedIcons/HourglassLow.tsx +48 -0
- package/src/Icons/generatedIcons/House.tsx +51 -0
- package/src/Icons/generatedIcons/Image.tsx +51 -0
- package/src/Icons/generatedIcons/ImageSquare.tsx +51 -0
- package/src/Icons/generatedIcons/ImagesSquare.tsx +51 -0
- package/src/Icons/generatedIcons/Info.tsx +48 -0
- package/src/Icons/generatedIcons/InstagramLogo.tsx +51 -0
- package/src/Icons/generatedIcons/Lightning.tsx +48 -0
- package/src/Icons/generatedIcons/Link.tsx +51 -0
- package/src/Icons/generatedIcons/LinkedinLogo.tsx +51 -0
- package/src/Icons/generatedIcons/List.tsx +48 -0
- package/src/Icons/generatedIcons/Lock.tsx +51 -0
- package/src/Icons/generatedIcons/LockOpen.tsx +51 -0
- package/src/Icons/generatedIcons/MagnifyingGlass.tsx +48 -0
- package/src/Icons/generatedIcons/MapPin.tsx +51 -0
- package/src/Icons/generatedIcons/MapPinSimpleArea.tsx +48 -0
- package/src/Icons/generatedIcons/Medal.tsx +48 -0
- package/src/Icons/generatedIcons/Megaphone.tsx +48 -0
- package/src/Icons/generatedIcons/Minus.tsx +45 -0
- package/src/Icons/generatedIcons/Money.tsx +51 -0
- package/src/Icons/generatedIcons/Notches.tsx +48 -0
- package/src/Icons/generatedIcons/NotePencil.tsx +48 -0
- package/src/Icons/generatedIcons/Package.tsx +51 -0
- package/src/Icons/generatedIcons/PaintBrush.tsx +51 -0
- package/src/Icons/generatedIcons/PaperPlaneTilt.tsx +51 -0
- package/src/Icons/generatedIcons/Paperclip.tsx +51 -0
- package/src/Icons/generatedIcons/Pause.tsx +51 -0
- package/src/Icons/generatedIcons/PencilLine.tsx +51 -0
- package/src/Icons/generatedIcons/PencilRuler.tsx +51 -0
- package/src/Icons/generatedIcons/PencilSimple.tsx +51 -0
- package/src/Icons/generatedIcons/Phone.tsx +51 -0
- package/src/Icons/generatedIcons/PinterestLogo.tsx +51 -0
- package/src/Icons/generatedIcons/Play.tsx +51 -0
- package/src/Icons/generatedIcons/Plus.tsx +51 -0
- package/src/Icons/generatedIcons/PlusCircle.tsx +48 -0
- package/src/Icons/generatedIcons/Printer.tsx +51 -0
- package/src/Icons/generatedIcons/Question.tsx +48 -0
- package/src/Icons/generatedIcons/Receipt.tsx +51 -0
- package/src/Icons/generatedIcons/Rows.tsx +51 -0
- package/src/Icons/generatedIcons/SealCheck.tsx +51 -0
- package/src/Icons/generatedIcons/SelectionSlash.tsx +48 -0
- package/src/Icons/generatedIcons/ShareNetwork.tsx +51 -0
- package/src/Icons/generatedIcons/ShieldCheck.tsx +51 -0
- package/src/Icons/generatedIcons/ShieldStar.tsx +51 -0
- package/src/Icons/generatedIcons/ShoppingCart.tsx +48 -0
- package/src/Icons/generatedIcons/ShuffleAngular.tsx +48 -0
- package/src/Icons/generatedIcons/SidebarSimple.tsx +48 -0
- package/src/Icons/generatedIcons/SlidersHorizontal.tsx +51 -0
- package/src/Icons/generatedIcons/Smiley.tsx +48 -0
- package/src/Icons/generatedIcons/Sparkle.tsx +51 -0
- package/src/Icons/generatedIcons/SpinnerGap.tsx +48 -0
- package/src/Icons/generatedIcons/StackPlus.tsx +48 -0
- package/src/Icons/generatedIcons/Star.tsx +51 -0
- package/src/Icons/generatedIcons/Storefront.tsx +51 -0
- package/src/Icons/generatedIcons/Swap.tsx +51 -0
- package/src/Icons/generatedIcons/Tag.tsx +51 -0
- package/src/Icons/generatedIcons/ThumbsDown.tsx +48 -0
- package/src/Icons/generatedIcons/ThumbsUp.tsx +48 -0
- package/src/Icons/generatedIcons/Toolbox.tsx +48 -0
- package/src/Icons/generatedIcons/Trash.tsx +48 -0
- package/src/Icons/generatedIcons/TrendUp.tsx +48 -0
- package/src/Icons/generatedIcons/Trophy.tsx +51 -0
- package/src/Icons/generatedIcons/Truck.tsx +51 -0
- package/src/Icons/generatedIcons/UploadSimple.tsx +51 -0
- package/src/Icons/generatedIcons/User.tsx +48 -0
- package/src/Icons/generatedIcons/Users.tsx +48 -0
- package/src/Icons/generatedIcons/UsersThree.tsx +51 -0
- package/src/Icons/generatedIcons/VideoCamera.tsx +51 -0
- package/src/Icons/generatedIcons/Warning.tsx +51 -0
- package/src/Icons/generatedIcons/WarningCircle.tsx +48 -0
- package/src/Icons/generatedIcons/WifiHigh.tsx +51 -0
- package/src/Icons/generatedIcons/XCircle.tsx +48 -0
- package/src/Icons/generatedIcons/XLogo.tsx +48 -0
- package/src/Icons/generatedIcons/YoutubeLogo.tsx +51 -0
- package/src/Icons/importedIcons.ts +152 -0
- package/src/Icons/index.ts +149 -0
- package/src/Icons/socialIcons/appleSocialIcon.tsx +50 -0
- package/src/Icons/socialIcons/facebookSocialIcon.tsx +41 -0
- package/src/Icons/socialIcons/googleSocialIcon.tsx +134 -0
- package/src/ImageCluster/ImageCluster.tsx +125 -0
- package/src/ImageSlider/ImageSlider.tsx +582 -0
- package/src/ImageSlider/ImageSlider.types.ts +90 -0
- package/src/ImageSlider/components/IndexIndicator/IndexIndicator.tsx +21 -0
- package/src/ImageSlider/components/NavigationButtons/NavigationButtons.tsx +113 -0
- package/src/ImageSlider/components/ResponsiveImage/ResponsiveImage.tsx +114 -0
- package/src/ImageSlider/components/ResponsiveImage/index.ts +1 -0
- package/src/ImageSlider/components/Thumbnails/Thumbnails.tsx +184 -0
- package/src/ImageSlider/constants.ts +59 -0
- package/src/ImageSlider/hooks/index.ts +3 -0
- package/src/ImageSlider/hooks/useImageSlider.ts +57 -0
- package/src/ImageSlider/hooks/useImageSliderNavigation.ts +133 -0
- package/src/ImageSlider/hooks/useImageSliderScrollHandler.ts +171 -0
- package/src/ImageSlider/index.ts +3 -0
- package/src/ImageSlider/utils/imageOptimization.ts +97 -0
- package/src/ImageSlider/utils/index.ts +1 -0
- package/src/InlineNotification/InlineNotification.tsx +95 -0
- package/src/JumpMenu/JumpMenu.tsx +395 -0
- package/src/JumpMenu/components/JumpMenuItem/JumpMenuItem.tsx +62 -0
- package/src/JumpMenu/hooks/useContainerTracking.ts +171 -0
- package/src/JumpMenu/hooks/useIntersectionObserver.ts +77 -0
- package/src/JumpMenu/hooks/useKeyboardNavigation.ts +102 -0
- package/src/JumpMenu/hooks/useResizeObserver.ts +53 -0
- package/src/JumpMenu/hooks/useSectionObserver.ts +102 -0
- package/src/JumpMenu/index.ts +2 -0
- package/src/JumpMenu/types/index.ts +19 -0
- package/src/Loading/Loading.tsx +39 -0
- package/src/Loading/components/LoadingDot/LoadingDot.tsx +16 -0
- package/src/LoadingSpinner/LoadingSpinner.tsx +20 -0
- package/src/Menu/Menu.tsx +372 -0
- package/src/Menu/components/MenuDivider/MenuDivider.tsx +5 -0
- package/src/Menu/components/MenuItem/MenuItem.tsx +298 -0
- package/src/Menu/context/menuContext.tsx +20 -0
- package/src/Menu/hooks/useMenu.tsx +18 -0
- package/src/Menu/index.ts +3 -0
- package/src/Modal/ComposableModal.tsx +313 -0
- package/src/Modal/Modal.tsx +231 -0
- package/src/Modal/components/BackButton/BackButton.tsx +43 -0
- package/src/Modal/components/Backdrop/Backdrop.tsx +62 -0
- package/src/Modal/components/CloseButton/CloseButton.tsx +55 -0
- package/src/Modal/components/ModalActions/ModalActions.tsx +135 -0
- package/src/Modal/components/ModalContent/ModalContent.tsx +163 -0
- package/src/Modal/components/ModalHeader/ModalHeader.tsx +84 -0
- package/src/Modal/components/ModalHeader/hooks/useHeaderAnimation.tsx +49 -0
- package/src/Modal/components/ModalProgressSteps/ModalProgressSteps.tsx +26 -0
- package/src/Modal/components/ModalSubTitle/ModalSubTitle.tsx +29 -0
- package/src/Modal/components/ModalTitle/ModalTitle.tsx +22 -0
- package/src/Modal/components/PreventModalScroll/PreventModalScroll.tsx +106 -0
- package/src/Modal/components/index.ts +12 -0
- package/src/Modal/context.ts +33 -0
- package/src/Modal/hooks/useCloseModal.ts +133 -0
- package/src/NotificationBadge/NotificationBadge.tsx +34 -0
- package/src/Pagination/AdvancedPagination.tsx +48 -0
- package/src/Pagination/Pagination.tsx +216 -0
- package/src/Pagination/components/AdvancedPaginator/AdvancedPaginator.tsx +52 -0
- package/src/Pagination/components/AdvancedPaginator/components/PageSelect/PageSelect.tsx +43 -0
- package/src/Pagination/components/ItemCountDisplay/ItemCountDisplay.tsx +32 -0
- package/src/Pagination/components/ItemCountSelect/ItemCountSelect.tsx +33 -0
- package/src/Pagination/index.tsx +3 -0
- package/src/Pagination/paginationProvider.tsx +234 -0
- package/src/Pagination/utils.tsx +36 -0
- package/src/PhoneInput/PhoneInput.tsx +509 -0
- package/src/PhoneInput/useDropdownLogic.tsx +163 -0
- package/src/ProgressCircle/ProgressCircle.tsx +246 -0
- package/src/ProgressCircle/hooks/useProgressStatusTransitions.ts +49 -0
- package/src/ProgressCircle/utils/progressCircle.constants.ts +27 -0
- package/src/ProgressSteps/ProgressSteps.tsx +160 -0
- package/src/SaveConfetti/SaveConfetti.tsx +277 -0
- package/src/SaveConfetti/index.ts +2 -0
- package/src/SearchInput/SearchInput.tsx +236 -0
- package/src/SegmentedControl/SegmentedControl.tsx +111 -0
- package/src/SegmentedControl/SegmentedControlGroup.tsx +94 -0
- package/src/SegmentedControl/index.ts +4 -0
- package/src/Select/Select.tsx +154 -0
- package/src/Select/SelectAsync.tsx +13 -0
- package/src/Select/SelectAsyncCreatable.tsx +14 -0
- package/src/Select/SelectCreatable.tsx +12 -0
- package/src/Select/reexportedComponents.tsx +5 -0
- package/src/Select/selectComponents.tsx +306 -0
- package/src/Skeleton/Skeleton.tsx +13 -0
- package/src/SplitButton/SplitButton.tsx +298 -0
- package/src/SplitButton/SplitButtonTrigger.tsx +55 -0
- package/src/StarRating/StarRating.tsx +165 -0
- package/src/StarRating/components/StarComponent/StarComponent.tsx +44 -0
- package/src/Table/Table.tsx +474 -0
- package/src/Table/components/TableHeader/TableHeader.tsx +166 -0
- package/src/Table/components/TablePagination/TablePagination.tsx +18 -0
- package/src/Table/components/TablePagination/components/ItemCountDisplay/ItemCountDisplay.tsx +17 -0
- package/src/Table/components/TablePagination/components/ItemCountSelect/ItemCountSelect.tsx +31 -0
- package/src/Table/components/TablePagination/components/TablePaginator/TablePaginator.tsx +37 -0
- package/src/Table/components/TablePagination/components/TablePaginator/components/PageSelect/PageSelect.tsx +32 -0
- package/src/Table/components/TableRow/TableRows.tsx +147 -0
- package/src/Table/components/TableRow/components/TableRowCell/TableRowCell.tsx +49 -0
- package/src/Table/components/TableShadow/TableShadow.tsx +46 -0
- package/src/Table/index.ts +2 -0
- package/src/Table/sharedState.ts +30 -0
- package/src/Table/sharedStyles.ts +1 -0
- package/src/Table/types.ts +55 -0
- package/src/Tabs/Tabs.tsx +358 -0
- package/src/TextArea/TextArea.tsx +157 -0
- package/src/TextInput/TextInput.tsx +173 -0
- package/src/Toast/Toast.tsx +64 -0
- package/src/Toast/components/ToastContainer/ToastContainer.tsx +48 -0
- package/src/Toast/index.ts +2 -0
- package/src/Toast/types/role.ts +1 -0
- package/src/Toast/utils/getIcon.tsx +41 -0
- package/src/ToggleSwitch/ToggleSwitch.tsx +188 -0
- package/src/Tooltip/InfoIconTooltip.tsx +47 -0
- package/src/Tooltip/Tooltip.tsx +41 -0
- package/src/Typography/InlineButton/InlineButton.tsx +166 -0
- package/src/Typography/Links/Links.tsx +113 -0
- package/src/Typography/Text/Text.tsx +239 -0
- package/src/ViewMore/ViewMore.tsx +226 -0
- package/src/WebRTCPlayer/WebRTCPlayer.tsx +325 -0
- package/src/WebRTCPlayer/adaptor/NativeWebRTCAdaptor.ts +588 -0
- package/src/WebRTCPlayer/hooks/useWebRTCStream.ts +571 -0
- package/src/WebRTCPlayer/index.ts +22 -0
- package/src/WebRTCPlayer/types.ts +95 -0
- package/src/breakpoints/index.tsx +1 -0
- package/src/breakpoints/utils.tsx +50 -0
- package/src/declarations.d.ts +7 -0
- package/src/grid/gridHighlighter.tsx +83 -0
- package/src/grid/index.ts +3 -0
- package/src/grid/pageGrid.tsx +37 -0
- package/src/grid/useSubGridCSS.tsx +214 -0
- package/src/hooks/useHorizontalScrollFade.ts +44 -0
- package/src/hooks/usePrevious.ts +14 -0
- package/src/index.ts +351 -0
- package/src/intl/index.ts +4 -0
- package/src/intl/utils.ts +67 -0
- package/src/mixins/horizontalScrollFadeMixin.ts +56 -0
- package/src/mixins/index.ts +18 -0
- package/src/mixins/propMixins.ts +389 -0
- package/src/providers/createContextProvider.ts +22 -0
- package/src/providers/designSystemProvider.tsx +218 -0
- package/src/providers/errorBoundaryProvider.tsx +179 -0
- package/src/providers/featureFlagProvider.tsx +18 -0
- package/src/providers/gridSizeProvider.tsx +23 -0
- package/src/providers/index.ts +12 -0
- package/src/providers/linkProvider.tsx +32 -0
- package/src/providers/normalize.tsx +93 -0
- package/src/providers/targets/DatePickerTarget.tsx +10 -0
- package/src/providers/targets/ModalTarget.tsx +14 -0
- package/src/providers/targets/TimePickerTarget.tsx +10 -0
- package/src/providers/themeContext.tsx +24 -0
- package/src/providers/windowSizeProvider.tsx +125 -0
- package/src/spacing/index.ts +1 -0
- package/src/spacing/spacing.ts +11 -0
- package/src/utils/countriesWithISOCodes.ts +1419 -0
- package/src/utils/dateTimeFormat.ts +257 -0
- package/src/utils/effectEventListener.ts +11 -0
- package/src/utils/formatFileSize.ts +18 -0
- package/src/utils/isClientSide.ts +1 -0
- package/src/utils/keepTransition.ts +15 -0
- package/src/utils/nodeEnv.ts +9 -0
- package/src/utils/smoothScrollTo.ts +47 -0
- package/src/utils/utilityTypes.ts +13 -0
- package/textInput.d.cts +1 -1
- package/textInput.d.mts +1 -1
- package/timePicker.d.cts +1 -1
- package/timePicker.d.mts +1 -1
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { memo } from 'react';
|
|
2
|
+
|
|
3
|
+
import { Button } from '../../../Button/Button';
|
|
4
|
+
import { CloseButton, ModalActions, ModalContent, ModalHeader } from '../../../Modal/components';
|
|
5
|
+
import { Modal } from '../../../Modal/Modal';
|
|
6
|
+
import { BodySecondary, H2 } from '../../../Typography/Text/Text';
|
|
7
|
+
import { ConsentCategories, CookieCategoryConfig, DEFAULT_COOKIE_CATEGORIES } from '../../types/cookieConsent.types';
|
|
8
|
+
import { CookieCategoryRow } from '../CookieCategoryRow/CookieCategoryRow';
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
categories?: CookieCategoryConfig[];
|
|
12
|
+
localConsent: ConsentCategories;
|
|
13
|
+
onClose: () => void;
|
|
14
|
+
onSave: () => void;
|
|
15
|
+
onToggle: (key: keyof ConsentCategories) => void;
|
|
16
|
+
show: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const CookieConsentModal = memo(
|
|
20
|
+
({ categories = DEFAULT_COOKIE_CATEGORIES, localConsent, onClose, onSave, onToggle, show }: Props) => (
|
|
21
|
+
<Modal
|
|
22
|
+
className="max-w-[588px]"
|
|
23
|
+
handleClose={onClose}
|
|
24
|
+
show={show}
|
|
25
|
+
type="composable"
|
|
26
|
+
>
|
|
27
|
+
<CloseButton />
|
|
28
|
+
<ModalHeader>
|
|
29
|
+
<H2>Cookie Preferences</H2>
|
|
30
|
+
</ModalHeader>
|
|
31
|
+
<ModalContent className="max-w-460px pb-sm">
|
|
32
|
+
<BodySecondary className="mb-sm">
|
|
33
|
+
Our platform uses various types of cookies, each of which has a specific function. Manage your
|
|
34
|
+
preferences below:
|
|
35
|
+
</BodySecondary>
|
|
36
|
+
<div className="border-b border-border-secondary pb-sm"></div>
|
|
37
|
+
<div className="flex flex-col">
|
|
38
|
+
{categories.map((cat) => (
|
|
39
|
+
<CookieCategoryRow
|
|
40
|
+
description={cat.description}
|
|
41
|
+
isToggled={cat.required ? true : localConsent[cat.key as keyof ConsentCategories]}
|
|
42
|
+
key={cat.key}
|
|
43
|
+
label={cat.label}
|
|
44
|
+
onToggleChange={
|
|
45
|
+
cat.required ? undefined : () => onToggle(cat.key as keyof ConsentCategories)
|
|
46
|
+
}
|
|
47
|
+
required={cat.required}
|
|
48
|
+
/>
|
|
49
|
+
))}
|
|
50
|
+
</div>
|
|
51
|
+
</ModalContent>
|
|
52
|
+
<ModalActions>
|
|
53
|
+
<Button
|
|
54
|
+
onClick={onSave}
|
|
55
|
+
size="md"
|
|
56
|
+
style="primary"
|
|
57
|
+
variant="filled"
|
|
58
|
+
>
|
|
59
|
+
SAVE PREFERENCES
|
|
60
|
+
</Button>
|
|
61
|
+
</ModalActions>
|
|
62
|
+
</Modal>
|
|
63
|
+
)
|
|
64
|
+
);
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { ConsentCategories, ConsentPayload } from '../types/cookieConsent.types';
|
|
4
|
+
|
|
5
|
+
export const DEFAULT_CONSENT_STORAGE_KEY = 'hui-cookie-consent';
|
|
6
|
+
|
|
7
|
+
const DEFAULT_CONSENT: ConsentCategories = {
|
|
8
|
+
marketing: false,
|
|
9
|
+
preferences: false,
|
|
10
|
+
statistics: false,
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Reads a previously persisted consent payload from localStorage.
|
|
15
|
+
* Returns `undefined` during SSR, when nothing is stored, or when the stored
|
|
16
|
+
* value is corrupt/unparseable (corrupt values are treated as "no response yet"
|
|
17
|
+
* so the banner shows again rather than trusting bad data).
|
|
18
|
+
*/
|
|
19
|
+
const readStoredConsent = (storageKey: string): ConsentCategories | undefined => {
|
|
20
|
+
/* istanbul ignore next -- @preserve: SSR guard; a React test renderer always runs with a defined `window`, so this branch is unreachable under jest/jsdom. */
|
|
21
|
+
if (typeof window === 'undefined') {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let raw: string | null = null;
|
|
26
|
+
try {
|
|
27
|
+
raw = window.localStorage.getItem(storageKey);
|
|
28
|
+
} catch {
|
|
29
|
+
// localStorage can throw (e.g. disabled in the browser) — treat as no response.
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!raw) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
const parsed: unknown = JSON.parse(raw);
|
|
39
|
+
if (
|
|
40
|
+
typeof parsed === 'object' &&
|
|
41
|
+
parsed !== null &&
|
|
42
|
+
typeof (parsed as ConsentPayload).marketing === 'boolean' &&
|
|
43
|
+
typeof (parsed as ConsentPayload).preferences === 'boolean' &&
|
|
44
|
+
typeof (parsed as ConsentPayload).statistics === 'boolean'
|
|
45
|
+
) {
|
|
46
|
+
const payload = parsed as ConsentPayload;
|
|
47
|
+
return {
|
|
48
|
+
marketing: payload.marketing,
|
|
49
|
+
preferences: payload.preferences,
|
|
50
|
+
statistics: payload.statistics,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
} catch {
|
|
54
|
+
// Corrupt JSON — fall through to undefined.
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return undefined;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Persists a consent payload to localStorage. No-ops during SSR or when
|
|
62
|
+
* localStorage is unavailable.
|
|
63
|
+
*/
|
|
64
|
+
const writeStoredConsent = (storageKey: string, categories: ConsentCategories) => {
|
|
65
|
+
/* istanbul ignore next -- @preserve: SSR guard; consent writes are user-triggered client-side actions and a React test renderer always has a defined `window`, so this branch is unreachable under jest/jsdom. */
|
|
66
|
+
if (typeof window === 'undefined') {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const payload: ConsentPayload = { ...categories, necessary: true };
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
window.localStorage.setItem(storageKey, JSON.stringify(payload));
|
|
74
|
+
} catch {
|
|
75
|
+
// localStorage unavailable — consent still applies for this session via state.
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/** Params for the useCookieConsent hook. */
|
|
80
|
+
export type UseCookieConsentParams = {
|
|
81
|
+
/**
|
|
82
|
+
* Controlled consent state. When provided, an external consent-management
|
|
83
|
+
* platform (CMP) owns the consent state: internal localStorage persistence
|
|
84
|
+
* is bypassed, the banner is never auto-shown, and consent reads reflect
|
|
85
|
+
* this value. Sync user changes back to the CMP via the component's
|
|
86
|
+
* `onConsentChange` callback.
|
|
87
|
+
*/
|
|
88
|
+
consent?: ConsentCategories;
|
|
89
|
+
/** localStorage key used to persist consent in uncontrolled mode. */
|
|
90
|
+
storageKey?: string;
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Low-level consent engine backed by localStorage.
|
|
95
|
+
*
|
|
96
|
+
* Uncontrolled (default) mode: on mount, reads any previously saved consent
|
|
97
|
+
* from localStorage. The banner is visible if and only if no stored consent
|
|
98
|
+
* exists. Action helpers (`acceptAll`, `declineAll`, `submitConsent`) persist
|
|
99
|
+
* the new consent payload and hide the banner.
|
|
100
|
+
*
|
|
101
|
+
* Controlled mode (`consent` param provided): an external CMP owns the state —
|
|
102
|
+
* nothing is read from or written to localStorage and the banner is never
|
|
103
|
+
* auto-shown; the preferences modal remains reachable via
|
|
104
|
+
* `CookieConsentHandle.openModal()`.
|
|
105
|
+
*
|
|
106
|
+
* Exposes `isBannerVisible`, current `consent` state, `hasResponse` (whether
|
|
107
|
+
* the user has already responded), and the action helpers.
|
|
108
|
+
*/
|
|
109
|
+
export const useCookieConsent = ({
|
|
110
|
+
consent: controlledConsent,
|
|
111
|
+
storageKey = DEFAULT_CONSENT_STORAGE_KEY,
|
|
112
|
+
}: UseCookieConsentParams = {}) => {
|
|
113
|
+
const isControlled = controlledConsent !== undefined;
|
|
114
|
+
|
|
115
|
+
const [isBannerVisible, setIsBannerVisible] = useState(false);
|
|
116
|
+
const [internalConsent, setInternalConsent] = useState<ConsentCategories>(DEFAULT_CONSENT);
|
|
117
|
+
const [hasStoredResponse, setHasStoredResponse] = useState(false);
|
|
118
|
+
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
if (isControlled) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const stored = readStoredConsent(storageKey);
|
|
125
|
+
if (stored) {
|
|
126
|
+
setInternalConsent(stored);
|
|
127
|
+
setHasStoredResponse(true);
|
|
128
|
+
setIsBannerVisible(false);
|
|
129
|
+
} else {
|
|
130
|
+
setIsBannerVisible(true);
|
|
131
|
+
}
|
|
132
|
+
}, [isControlled, storageKey]);
|
|
133
|
+
|
|
134
|
+
const applyConsent = useCallback(
|
|
135
|
+
(categories: ConsentCategories) => {
|
|
136
|
+
if (!isControlled) {
|
|
137
|
+
writeStoredConsent(storageKey, categories);
|
|
138
|
+
}
|
|
139
|
+
setInternalConsent(categories);
|
|
140
|
+
setHasStoredResponse(true);
|
|
141
|
+
setIsBannerVisible(false);
|
|
142
|
+
},
|
|
143
|
+
[isControlled, storageKey]
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const acceptAll = useCallback(() => {
|
|
147
|
+
applyConsent({ marketing: true, preferences: true, statistics: true });
|
|
148
|
+
}, [applyConsent]);
|
|
149
|
+
|
|
150
|
+
const declineAll = useCallback(() => {
|
|
151
|
+
applyConsent(DEFAULT_CONSENT);
|
|
152
|
+
}, [applyConsent]);
|
|
153
|
+
|
|
154
|
+
const submitConsent = useCallback(
|
|
155
|
+
(categories: ConsentCategories) => {
|
|
156
|
+
applyConsent(categories);
|
|
157
|
+
},
|
|
158
|
+
[applyConsent]
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
return {
|
|
162
|
+
acceptAll,
|
|
163
|
+
consent: isControlled ? controlledConsent : internalConsent,
|
|
164
|
+
declineAll,
|
|
165
|
+
/** Whether the user has already responded (controlled mode counts as responded). */
|
|
166
|
+
hasResponse: isControlled || hasStoredResponse,
|
|
167
|
+
isBannerVisible,
|
|
168
|
+
submitConsent,
|
|
169
|
+
};
|
|
170
|
+
};
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { AnimationEvent, useCallback, useEffect, useRef, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { toast } from '../../Toast';
|
|
4
|
+
import {
|
|
5
|
+
ConsentCategories,
|
|
6
|
+
ConsentPayload,
|
|
7
|
+
ConsentSource,
|
|
8
|
+
UseCookieConsentStateParams,
|
|
9
|
+
} from '../types/cookieConsent.types';
|
|
10
|
+
import { useCookieConsent } from './useCookieConsent';
|
|
11
|
+
|
|
12
|
+
const DEFAULT_LOCAL_CONSENT: ConsentCategories = {
|
|
13
|
+
marketing: true,
|
|
14
|
+
preferences: true,
|
|
15
|
+
statistics: true,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const buildConsentPayload = (consent: ConsentCategories): ConsentPayload => ({
|
|
19
|
+
...consent,
|
|
20
|
+
necessary: true,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* UI state manager for the CookieConsent component.
|
|
25
|
+
*
|
|
26
|
+
* Wraps `useCookieConsent` and owns banner/modal visibility, local consent
|
|
27
|
+
* toggle state, and all user interaction handlers (OK, save, toggle, open/close).
|
|
28
|
+
*
|
|
29
|
+
* Modal toggles default to all-ON (`DEFAULT_LOCAL_CONSENT`). When opening the
|
|
30
|
+
* modal, existing consent is read from the consent engine only if the user has
|
|
31
|
+
* already responded — before a response, consent initializes as all `false`,
|
|
32
|
+
* so we fall back to the all-ON default.
|
|
33
|
+
*/
|
|
34
|
+
export const useCookieConsentState = ({
|
|
35
|
+
consent: controlledConsent,
|
|
36
|
+
onConsentChange,
|
|
37
|
+
storageKey,
|
|
38
|
+
toastMessage,
|
|
39
|
+
tracking,
|
|
40
|
+
}: UseCookieConsentStateParams) => {
|
|
41
|
+
const { acceptAll, consent, hasResponse, isBannerVisible, submitConsent } = useCookieConsent({
|
|
42
|
+
consent: controlledConsent,
|
|
43
|
+
storageKey,
|
|
44
|
+
});
|
|
45
|
+
const trackingRef = useRef(tracking);
|
|
46
|
+
trackingRef.current = tracking;
|
|
47
|
+
|
|
48
|
+
const [showBanner, setShowBanner] = useState(false);
|
|
49
|
+
const [bannerExiting, setBannerExiting] = useState(false);
|
|
50
|
+
const [showDialog, setShowDialog] = useState(false);
|
|
51
|
+
const [localConsent, setLocalConsent] = useState(DEFAULT_LOCAL_CONSENT);
|
|
52
|
+
|
|
53
|
+
const readCurrentConsent = useCallback(
|
|
54
|
+
(): ConsentCategories => (hasResponse ? consent : DEFAULT_LOCAL_CONSENT),
|
|
55
|
+
[consent, hasResponse]
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
if (isBannerVisible) {
|
|
60
|
+
setShowBanner(true);
|
|
61
|
+
setBannerExiting(false);
|
|
62
|
+
trackingRef.current?.onBannerViewed?.();
|
|
63
|
+
}
|
|
64
|
+
}, [isBannerVisible]);
|
|
65
|
+
|
|
66
|
+
const openModal = useCallback(() => {
|
|
67
|
+
setLocalConsent(readCurrentConsent());
|
|
68
|
+
setShowDialog(true);
|
|
69
|
+
}, [readCurrentConsent]);
|
|
70
|
+
|
|
71
|
+
const handleBannerAnimationEnd = useCallback(
|
|
72
|
+
(e: AnimationEvent<HTMLDivElement>) => {
|
|
73
|
+
/* istanbul ignore next -- @preserve: `bannerExiting` is only ever set to false in this hook (faithful hammer parity), so the exit-animation cleanup branch is unreachable. Reported as latent dead code, not modified to preserve parity. */
|
|
74
|
+
if (bannerExiting && e.target === e.currentTarget) {
|
|
75
|
+
setShowBanner(false);
|
|
76
|
+
setBannerExiting(false);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
[bannerExiting]
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const openDialog = useCallback(() => {
|
|
83
|
+
setLocalConsent(readCurrentConsent());
|
|
84
|
+
setShowDialog(true);
|
|
85
|
+
setShowBanner(false);
|
|
86
|
+
setBannerExiting(false);
|
|
87
|
+
trackingRef.current?.onPreferencesOpened?.(ConsentSource.Banner);
|
|
88
|
+
}, [readCurrentConsent]);
|
|
89
|
+
|
|
90
|
+
const closeDialog = useCallback(() => {
|
|
91
|
+
setShowDialog(false);
|
|
92
|
+
trackingRef.current?.onPreferencesDismissed?.(ConsentSource.Modal);
|
|
93
|
+
if (isBannerVisible) {
|
|
94
|
+
setShowBanner(true);
|
|
95
|
+
setBannerExiting(false);
|
|
96
|
+
}
|
|
97
|
+
}, [isBannerVisible]);
|
|
98
|
+
|
|
99
|
+
const handleOk = useCallback(() => {
|
|
100
|
+
const allConsent: ConsentCategories = { marketing: true, preferences: true, statistics: true };
|
|
101
|
+
acceptAll();
|
|
102
|
+
onConsentChange?.(allConsent);
|
|
103
|
+
setShowBanner(false);
|
|
104
|
+
setBannerExiting(false);
|
|
105
|
+
toast('success', { title: toastMessage });
|
|
106
|
+
trackingRef.current?.onPreferencesSaved?.({
|
|
107
|
+
consent: buildConsentPayload(allConsent),
|
|
108
|
+
source: ConsentSource.Banner,
|
|
109
|
+
});
|
|
110
|
+
}, [acceptAll, onConsentChange, toastMessage]);
|
|
111
|
+
|
|
112
|
+
const handleSavePreferences = useCallback(() => {
|
|
113
|
+
submitConsent(localConsent);
|
|
114
|
+
onConsentChange?.(localConsent);
|
|
115
|
+
setShowDialog(false);
|
|
116
|
+
setShowBanner(false);
|
|
117
|
+
setBannerExiting(false);
|
|
118
|
+
toast('success', { title: toastMessage });
|
|
119
|
+
trackingRef.current?.onPreferencesSaved?.({
|
|
120
|
+
consent: buildConsentPayload(localConsent),
|
|
121
|
+
source: ConsentSource.Modal,
|
|
122
|
+
});
|
|
123
|
+
}, [localConsent, onConsentChange, submitConsent, toastMessage]);
|
|
124
|
+
|
|
125
|
+
const handleToggle = useCallback((key: keyof ConsentCategories) => {
|
|
126
|
+
setLocalConsent((prev) => ({ ...prev, [key]: !prev[key] }));
|
|
127
|
+
}, []);
|
|
128
|
+
|
|
129
|
+
return {
|
|
130
|
+
bannerExiting,
|
|
131
|
+
closeDialog,
|
|
132
|
+
handleBannerAnimationEnd,
|
|
133
|
+
handleOk,
|
|
134
|
+
handleSavePreferences,
|
|
135
|
+
handleToggle,
|
|
136
|
+
localConsent,
|
|
137
|
+
openDialog,
|
|
138
|
+
openModal,
|
|
139
|
+
showBanner,
|
|
140
|
+
showDialog,
|
|
141
|
+
};
|
|
142
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Components
|
|
2
|
+
export { CookieConsent } from './components/CookieConsent/CookieConsent';
|
|
3
|
+
export type { CookieConsentHandle } from './components/CookieConsent/CookieConsent';
|
|
4
|
+
|
|
5
|
+
// Hooks
|
|
6
|
+
export { useCookieConsent, DEFAULT_CONSENT_STORAGE_KEY } from './hooks/useCookieConsent';
|
|
7
|
+
export type { UseCookieConsentParams } from './hooks/useCookieConsent';
|
|
8
|
+
|
|
9
|
+
// Types
|
|
10
|
+
export { ConsentSource, DEFAULT_COOKIE_CATEGORIES } from './types/cookieConsent.types';
|
|
11
|
+
export type {
|
|
12
|
+
ConsentCategories,
|
|
13
|
+
CookieCategoryConfig,
|
|
14
|
+
CookieConsentTracking,
|
|
15
|
+
ConsentPayload,
|
|
16
|
+
} from './types/cookieConsent.types';
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three non-essential consent categories managed by this component.
|
|
3
|
+
* `necessary` is excluded because it's always implicitly granted.
|
|
4
|
+
*/
|
|
5
|
+
export type ConsentCategories = {
|
|
6
|
+
marketing: boolean;
|
|
7
|
+
preferences: boolean;
|
|
8
|
+
statistics: boolean;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
/** Full consent payload including the always-on `necessary` flag. */
|
|
12
|
+
export type ConsentPayload = ConsentCategories & { necessary: true };
|
|
13
|
+
|
|
14
|
+
/** Where the user interaction originated. */
|
|
15
|
+
export enum ConsentSource {
|
|
16
|
+
Banner = 'banner',
|
|
17
|
+
Modal = 'modal',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Tracking callbacks for cookie consent analytics. */
|
|
21
|
+
export type CookieConsentTracking = {
|
|
22
|
+
onBannerViewed?: () => void;
|
|
23
|
+
onPreferencesDismissed?: (source: ConsentSource) => void;
|
|
24
|
+
onPreferencesOpened?: (source: ConsentSource) => void;
|
|
25
|
+
onPreferencesSaved?: (payload: { consent: ConsentPayload; source: ConsentSource }) => void;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** Params for the useCookieConsentState hook. */
|
|
29
|
+
export type UseCookieConsentStateParams = {
|
|
30
|
+
/**
|
|
31
|
+
* Controlled consent state. When provided, an external consent-management
|
|
32
|
+
* platform owns the consent state and internal localStorage persistence is
|
|
33
|
+
* bypassed — sync changes back through `onConsentChange`.
|
|
34
|
+
*/
|
|
35
|
+
consent?: ConsentCategories;
|
|
36
|
+
onConsentChange?: (consent: ConsentCategories) => void;
|
|
37
|
+
/** localStorage key used to persist consent in uncontrolled mode. */
|
|
38
|
+
storageKey?: string;
|
|
39
|
+
toastMessage: string;
|
|
40
|
+
tracking?: CookieConsentTracking;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
/** Definition for a single row in the preferences modal. */
|
|
44
|
+
export type CookieCategoryConfig = {
|
|
45
|
+
description: string;
|
|
46
|
+
/** Must match a `ConsentCategories` key, or `'necessary'` for the always-on row. */
|
|
47
|
+
key: keyof ConsentCategories | 'necessary';
|
|
48
|
+
label: string;
|
|
49
|
+
/** When `true`, the toggle is locked on and the user cannot opt out. */
|
|
50
|
+
required?: boolean;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const DEFAULT_COOKIE_CATEGORIES: CookieCategoryConfig[] = [
|
|
54
|
+
{
|
|
55
|
+
description:
|
|
56
|
+
'Necessary cookies help make a website usable by enabling basic functions like page navigation and access to secure areas of the website. The website cannot function properly without these cookies.',
|
|
57
|
+
key: 'necessary',
|
|
58
|
+
label: 'Necessary',
|
|
59
|
+
required: true,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
description:
|
|
63
|
+
'Preference cookies enable a website to remember information that changes the way the website behaves or looks, like your preferred language or the region that you are in.',
|
|
64
|
+
key: 'preferences',
|
|
65
|
+
label: 'Preferences',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
description:
|
|
69
|
+
'Statistics cookies help website owners to understand how visitors interact with websites by collecting and reporting information anonymously.',
|
|
70
|
+
key: 'statistics',
|
|
71
|
+
label: 'Statistics',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
description:
|
|
75
|
+
'Marketing cookies are used to track visitors across websites. The intention is to display ads that are relevant and engaging for the individual user and thereby more valuable for publishers and third party advertisers.',
|
|
76
|
+
key: 'marketing',
|
|
77
|
+
label: 'Marketing',
|
|
78
|
+
},
|
|
79
|
+
];
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
import { BodySecondary, H3 } from '../Typography/Text/Text';
|
|
4
|
+
import { CountdownFlashpoint } from './Countdown.types';
|
|
5
|
+
import { useGetCountdown } from './hooks/useGetCountdown';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @property completionTime Timestamp (in ms) for when the countdown will first reach zero
|
|
9
|
+
* @property flashpoint Amount of time left before the countdown turns red (signalling urgency)
|
|
10
|
+
* @property label Additional information for the countdown. *e.g.* 5d 23h **Until the event begins!**
|
|
11
|
+
* @property onComplete Called when the countdown reaches zero.
|
|
12
|
+
* @property preLabel Information shown before the countdown numbers. Will not be shown unless countdown is small
|
|
13
|
+
* @property small If true, all text (the countdown numbers and the label) will be the same size
|
|
14
|
+
* @property startTime Represents the time from which the countdown is counting down from
|
|
15
|
+
* @property timeLabels Used for internationalization, defaults to d/h/m/s, represents days/hours/minutes/seconds
|
|
16
|
+
*/
|
|
17
|
+
export type CountdownProps = {
|
|
18
|
+
/* Timestamp (in ms) for when the countdown will first reach zero */
|
|
19
|
+
completionTime: number;
|
|
20
|
+
// Amount of time left before the countdown turns red (signalling urgency)
|
|
21
|
+
flashpoint?: CountdownFlashpoint;
|
|
22
|
+
// If true, the countdown will always display with seconds included
|
|
23
|
+
forceSeconds?: boolean;
|
|
24
|
+
// If true, the countdown will always render in the urgent/critical color regardless of time remaining
|
|
25
|
+
forceUrgent?: boolean;
|
|
26
|
+
// Additional information for the countdown. *e.g.* 5d 23h **Until the event begins!**
|
|
27
|
+
label?: string;
|
|
28
|
+
// Called when the countdown reaches zero.
|
|
29
|
+
onComplete?: () => void;
|
|
30
|
+
// Information shown before the countdown numbers. Will not be shown unless countdown is small
|
|
31
|
+
preLabel?: string;
|
|
32
|
+
// If true, all text (the countdown numbers and the label) will be the same size
|
|
33
|
+
small?: boolean;
|
|
34
|
+
// Represents the time from which the countdown is counting down from
|
|
35
|
+
startTime?: number;
|
|
36
|
+
// Used for internationalization, defaults to d/h/m/s, represents days/hours/minutes/seconds
|
|
37
|
+
timeLabels?: {
|
|
38
|
+
days?: string;
|
|
39
|
+
hours?: string;
|
|
40
|
+
minutes?: string;
|
|
41
|
+
seconds?: string;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const Countdown = ({
|
|
46
|
+
completionTime,
|
|
47
|
+
flashpoint,
|
|
48
|
+
forceSeconds,
|
|
49
|
+
forceUrgent,
|
|
50
|
+
label,
|
|
51
|
+
onComplete,
|
|
52
|
+
preLabel,
|
|
53
|
+
small,
|
|
54
|
+
startTime,
|
|
55
|
+
timeLabels,
|
|
56
|
+
}: CountdownProps) => {
|
|
57
|
+
const {
|
|
58
|
+
daysUntilEnd,
|
|
59
|
+
hoursUntilEnd,
|
|
60
|
+
isUrgent: isUrgentFromFlashpoint,
|
|
61
|
+
minutesUntilEnd,
|
|
62
|
+
secondsUntilEnd,
|
|
63
|
+
} = useGetCountdown({
|
|
64
|
+
completionTime,
|
|
65
|
+
flashpoint,
|
|
66
|
+
forceSeconds,
|
|
67
|
+
startTime,
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const isUrgent = forceUrgent || isUrgentFromFlashpoint;
|
|
71
|
+
|
|
72
|
+
const dayLabel = timeLabels?.days ?? 'd';
|
|
73
|
+
const hourLabel = timeLabels?.hours ?? 'h';
|
|
74
|
+
const minuteLabel = timeLabels?.minutes ?? 'm';
|
|
75
|
+
const secondLabel = timeLabels?.seconds ?? 's';
|
|
76
|
+
|
|
77
|
+
let primaryDurationValue = `${daysUntilEnd}${dayLabel}`;
|
|
78
|
+
let secondaryDurationValue: string | null = `${hoursUntilEnd}${hourLabel}`;
|
|
79
|
+
let altDurationValue = null;
|
|
80
|
+
|
|
81
|
+
// less than one day from end
|
|
82
|
+
if (daysUntilEnd === 0 && hoursUntilEnd !== 0) {
|
|
83
|
+
primaryDurationValue = `${hoursUntilEnd}${hourLabel}`;
|
|
84
|
+
secondaryDurationValue = `${minutesUntilEnd}${minuteLabel}`;
|
|
85
|
+
if (forceSeconds) {
|
|
86
|
+
altDurationValue = `${secondsUntilEnd}${secondLabel}`;
|
|
87
|
+
}
|
|
88
|
+
} else if (daysUntilEnd === 0 && hoursUntilEnd === 0 && minutesUntilEnd !== 0) {
|
|
89
|
+
primaryDurationValue = `${minutesUntilEnd}${minuteLabel}`;
|
|
90
|
+
secondaryDurationValue = `${secondsUntilEnd}${secondLabel}`;
|
|
91
|
+
} else if (daysUntilEnd === 0 && hoursUntilEnd === 0 && minutesUntilEnd === 0) {
|
|
92
|
+
primaryDurationValue = `${secondsUntilEnd}${secondLabel}`;
|
|
93
|
+
secondaryDurationValue = null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
useEffect(() => {
|
|
97
|
+
if (daysUntilEnd === 0 && hoursUntilEnd === 0 && minutesUntilEnd === 0 && secondsUntilEnd === 0) {
|
|
98
|
+
onComplete?.();
|
|
99
|
+
}
|
|
100
|
+
}, [daysUntilEnd, hoursUntilEnd, minutesUntilEnd, onComplete, secondsUntilEnd]);
|
|
101
|
+
|
|
102
|
+
if (small) {
|
|
103
|
+
return (
|
|
104
|
+
<div className="flex items-baseline whitespace-nowrap">
|
|
105
|
+
{Boolean(preLabel) && (
|
|
106
|
+
<>
|
|
107
|
+
<BodySecondary color={isUrgent ? 'critical' : 'primary'}>{preLabel}</BodySecondary>
|
|
108
|
+
|
|
109
|
+
</>
|
|
110
|
+
)}
|
|
111
|
+
<BodySecondary color={isUrgent ? 'critical' : 'primary'}>{primaryDurationValue}</BodySecondary>
|
|
112
|
+
{secondaryDurationValue && (
|
|
113
|
+
<>
|
|
114
|
+
|
|
115
|
+
<BodySecondary color={isUrgent ? 'critical' : 'primary'}>
|
|
116
|
+
{secondaryDurationValue}
|
|
117
|
+
</BodySecondary>
|
|
118
|
+
</>
|
|
119
|
+
)}
|
|
120
|
+
|
|
121
|
+
{altDurationValue && (
|
|
122
|
+
<>
|
|
123
|
+
<BodySecondary color={isUrgent ? 'critical' : 'primary'}>{altDurationValue}</BodySecondary>
|
|
124
|
+
|
|
125
|
+
</>
|
|
126
|
+
)}
|
|
127
|
+
<BodySecondary color={isUrgent ? 'critical' : 'primary'}>{label}</BodySecondary>
|
|
128
|
+
</div>
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return (
|
|
133
|
+
<div className="flex items-baseline whitespace-nowrap">
|
|
134
|
+
<span className={`hui-text-h1 text-${isUrgent ? 'text-critical' : 'text-primary'}`}>
|
|
135
|
+
{primaryDurationValue}
|
|
136
|
+
</span>
|
|
137
|
+
{secondaryDurationValue && (
|
|
138
|
+
<>
|
|
139
|
+
|
|
140
|
+
<span className={`hui-text-h1 text-${isUrgent ? 'text-critical' : 'text-primary'}`}>
|
|
141
|
+
{secondaryDurationValue}
|
|
142
|
+
</span>
|
|
143
|
+
</>
|
|
144
|
+
)}
|
|
145
|
+
{altDurationValue && (
|
|
146
|
+
<>
|
|
147
|
+
|
|
148
|
+
<span className={`hui-text-h1 text-${isUrgent ? 'text-critical' : 'text-primary'}`}>
|
|
149
|
+
{altDurationValue}
|
|
150
|
+
</span>
|
|
151
|
+
</>
|
|
152
|
+
)}
|
|
153
|
+
<H3
|
|
154
|
+
className="ml-2"
|
|
155
|
+
color="secondary"
|
|
156
|
+
>
|
|
157
|
+
{label}
|
|
158
|
+
</H3>
|
|
159
|
+
</div>
|
|
160
|
+
);
|
|
161
|
+
};
|