@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,21 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
/** Currently active page number (1-based) */
|
|
3
|
+
currentPage: number;
|
|
4
|
+
/** Total number of pages/images */
|
|
5
|
+
numberOfPages: number;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Displays a numeric index indicator (e.g., "1 of 11") for image gallery position.
|
|
10
|
+
* Used when thumbnailDisplay is 'index' instead of image thumbnails.
|
|
11
|
+
*/
|
|
12
|
+
export const IndexIndicator = ({ currentPage, numberOfPages }: Props) => (
|
|
13
|
+
<div
|
|
14
|
+
aria-label={`Image ${currentPage} of ${numberOfPages}`}
|
|
15
|
+
aria-live="polite"
|
|
16
|
+
className="hui-text-caption flex justify-center text-text-secondary"
|
|
17
|
+
role="status"
|
|
18
|
+
>
|
|
19
|
+
{currentPage} of {numberOfPages}
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { cn } from '@evolve.ui/theme-system';
|
|
2
|
+
|
|
3
|
+
import { IconButton } from '../../../IconButton/IconButton';
|
|
4
|
+
import { ArrowLeft, ArrowRight, CaretLeft, CaretRight } from '../../../Icons';
|
|
5
|
+
|
|
6
|
+
type Props = {
|
|
7
|
+
goToNextPage: () => void;
|
|
8
|
+
goToPreviousPage: () => void;
|
|
9
|
+
/** Shape of the navigation icons */
|
|
10
|
+
iconShape?: 'circle' | 'square';
|
|
11
|
+
/** Size of the navigation icons - sm=34px, md=42px, lg=54px */
|
|
12
|
+
iconSize?: 'sm' | 'md' | 'lg';
|
|
13
|
+
/** Type of icons to use for navigation */
|
|
14
|
+
iconType?: 'caret' | 'arrow';
|
|
15
|
+
/** Variant of the navigation icons */
|
|
16
|
+
iconVariant?: 'outlined' | 'transparent';
|
|
17
|
+
/** Whether the next button should be disabled */
|
|
18
|
+
isNextPageDisabled?: boolean;
|
|
19
|
+
/** Whether the previous button should be disabled */
|
|
20
|
+
isPreviousPageDisabled?: boolean;
|
|
21
|
+
/** For grid layout - which position this button should render (left or right) */
|
|
22
|
+
position?: 'left' | 'right';
|
|
23
|
+
showNextPageButton: boolean;
|
|
24
|
+
showPreviousPageButton: boolean;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export const NavigationButtons = ({
|
|
28
|
+
goToNextPage,
|
|
29
|
+
goToPreviousPage,
|
|
30
|
+
iconShape = 'circle',
|
|
31
|
+
iconSize = 'sm',
|
|
32
|
+
iconType = 'caret',
|
|
33
|
+
iconVariant = 'outlined',
|
|
34
|
+
isNextPageDisabled = false,
|
|
35
|
+
isPreviousPageDisabled = false,
|
|
36
|
+
position,
|
|
37
|
+
showNextPageButton,
|
|
38
|
+
showPreviousPageButton,
|
|
39
|
+
}: Props) => {
|
|
40
|
+
// Choose the correct icons based on iconType prop
|
|
41
|
+
const LeftIcon = iconType === 'arrow' ? ArrowLeft : CaretLeft;
|
|
42
|
+
const RightIcon = iconType === 'arrow' ? ArrowRight : CaretRight;
|
|
43
|
+
|
|
44
|
+
// For grid layout with outside positioning, render individual buttons
|
|
45
|
+
if (position) {
|
|
46
|
+
if (position === 'left') {
|
|
47
|
+
return showPreviousPageButton ? (
|
|
48
|
+
<IconButton
|
|
49
|
+
aria-label="Previous Page"
|
|
50
|
+
className="xsMax:hidden"
|
|
51
|
+
disabled={isPreviousPageDisabled}
|
|
52
|
+
hideTooltip
|
|
53
|
+
icon={LeftIcon}
|
|
54
|
+
onClick={goToPreviousPage}
|
|
55
|
+
shape={iconShape}
|
|
56
|
+
size={iconSize}
|
|
57
|
+
variant={iconVariant}
|
|
58
|
+
/>
|
|
59
|
+
) : null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// position === 'right'
|
|
63
|
+
return showNextPageButton ? (
|
|
64
|
+
<IconButton
|
|
65
|
+
aria-label="Next Page"
|
|
66
|
+
className="xsMax:hidden"
|
|
67
|
+
disabled={isNextPageDisabled}
|
|
68
|
+
hideTooltip
|
|
69
|
+
icon={RightIcon}
|
|
70
|
+
onClick={goToNextPage}
|
|
71
|
+
shape={iconShape}
|
|
72
|
+
size={iconSize}
|
|
73
|
+
variant={iconVariant}
|
|
74
|
+
/>
|
|
75
|
+
) : null;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Original layout for inside positioning or non-grid layouts
|
|
79
|
+
// For inside positioning: calculate from the top to put the button halfway down its parent relative to its own center.
|
|
80
|
+
// this will break if the size of the IconButton is ever changed,
|
|
81
|
+
const positionStyles = cn('absolute top-[calc(50%-21px)] w-full');
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<div className="z-10">
|
|
85
|
+
{showPreviousPageButton && (
|
|
86
|
+
<IconButton
|
|
87
|
+
aria-label="Previous Page"
|
|
88
|
+
className={cn(positionStyles, 'left-sm', 'xsMax:hidden')}
|
|
89
|
+
disabled={isPreviousPageDisabled}
|
|
90
|
+
hideTooltip
|
|
91
|
+
icon={LeftIcon}
|
|
92
|
+
onClick={goToPreviousPage}
|
|
93
|
+
shape={iconShape}
|
|
94
|
+
size={iconSize}
|
|
95
|
+
variant={iconVariant}
|
|
96
|
+
/>
|
|
97
|
+
)}
|
|
98
|
+
{showNextPageButton && (
|
|
99
|
+
<IconButton
|
|
100
|
+
aria-label="Next Page"
|
|
101
|
+
className={cn(positionStyles, 'right-sm', 'xsMax:hidden')}
|
|
102
|
+
disabled={isNextPageDisabled}
|
|
103
|
+
hideTooltip
|
|
104
|
+
icon={RightIcon}
|
|
105
|
+
onClick={goToNextPage}
|
|
106
|
+
shape={iconShape}
|
|
107
|
+
size={iconSize}
|
|
108
|
+
variant={iconVariant}
|
|
109
|
+
/>
|
|
110
|
+
)}
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { PLACEHOLDER_IMAGE_URL } from '../../constants';
|
|
2
|
+
import { ResponsiveImageConfig, ResponsiveImageData } from '../../ImageSlider.types';
|
|
3
|
+
import {
|
|
4
|
+
generateMainImageSrcSet,
|
|
5
|
+
generateSizesAttribute,
|
|
6
|
+
generateThumbnailSizesAttribute,
|
|
7
|
+
generateThumbnailSrcSet,
|
|
8
|
+
getImageSrc,
|
|
9
|
+
getThumbnailSrc,
|
|
10
|
+
} from '../../utils/imageOptimization';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Props for the ResponsiveImage component
|
|
14
|
+
*/
|
|
15
|
+
type Props = {
|
|
16
|
+
/** Additional CSS classes */
|
|
17
|
+
className?: string;
|
|
18
|
+
/** Whether the gallery has been hovered (for quality optimization) */
|
|
19
|
+
hasHoveredGallery?: boolean;
|
|
20
|
+
/** Image data containing alt, baseUrl, and title */
|
|
21
|
+
imageData: ResponsiveImageData;
|
|
22
|
+
/** Whether this image is currently active/visible */
|
|
23
|
+
isActiveImage?: boolean;
|
|
24
|
+
/** Whether this is a main image (not a thumbnail) */
|
|
25
|
+
isMainImage?: boolean;
|
|
26
|
+
/** Responsive image configuration */
|
|
27
|
+
responsiveImageConfig?: ResponsiveImageConfig;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Renders a responsive image with optimized loading priorities and srcSet
|
|
32
|
+
*/
|
|
33
|
+
export const ResponsiveImage = ({
|
|
34
|
+
className,
|
|
35
|
+
hasHoveredGallery = false,
|
|
36
|
+
imageData,
|
|
37
|
+
isActiveImage = false,
|
|
38
|
+
isMainImage = true,
|
|
39
|
+
responsiveImageConfig,
|
|
40
|
+
}: Props) => {
|
|
41
|
+
const { alt, baseUrl, title } = imageData;
|
|
42
|
+
|
|
43
|
+
if (!responsiveImageConfig) {
|
|
44
|
+
// Fallback to simple image if no config provided
|
|
45
|
+
return (
|
|
46
|
+
<img
|
|
47
|
+
alt={alt}
|
|
48
|
+
className={className}
|
|
49
|
+
onError={(e) => {
|
|
50
|
+
const target = e.target as HTMLImageElement;
|
|
51
|
+
if (target.src !== PLACEHOLDER_IMAGE_URL) {
|
|
52
|
+
target.src = PLACEHOLDER_IMAGE_URL;
|
|
53
|
+
}
|
|
54
|
+
}}
|
|
55
|
+
src={baseUrl}
|
|
56
|
+
title={title}
|
|
57
|
+
/>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (isMainImage) {
|
|
62
|
+
// Use high quality mode for all images once gallery has been hovered
|
|
63
|
+
const useHighQuality = hasHoveredGallery;
|
|
64
|
+
|
|
65
|
+
// Only use high quality URLs/srcSet after gallery has been hovered
|
|
66
|
+
// Active images get high priority/eager loading but still use responsive srcSet initially
|
|
67
|
+
const shouldLoadHighQuality = useHighQuality;
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<img
|
|
71
|
+
alt={alt}
|
|
72
|
+
className="h-full w-full bg-background-primary object-contain"
|
|
73
|
+
fetchPriority={isActiveImage || shouldLoadHighQuality ? 'high' : 'low'}
|
|
74
|
+
// Force React to create a new img element when switching to high quality
|
|
75
|
+
// This prevents the browser from loading both constrained and unconstrained versions
|
|
76
|
+
key={shouldLoadHighQuality && !isActiveImage ? 'high-quality' : 'standard-quality'}
|
|
77
|
+
loading={isActiveImage || shouldLoadHighQuality ? 'eager' : 'lazy'}
|
|
78
|
+
onError={(e) => {
|
|
79
|
+
const target = e.target as HTMLImageElement;
|
|
80
|
+
if (target.src !== PLACEHOLDER_IMAGE_URL) {
|
|
81
|
+
target.src = PLACEHOLDER_IMAGE_URL;
|
|
82
|
+
// Clear srcSet to prevent fallback to other sizes that might also fail
|
|
83
|
+
target.srcset = '';
|
|
84
|
+
}
|
|
85
|
+
}}
|
|
86
|
+
sizes={generateSizesAttribute(responsiveImageConfig, shouldLoadHighQuality)}
|
|
87
|
+
src={getImageSrc(baseUrl, responsiveImageConfig, shouldLoadHighQuality)}
|
|
88
|
+
srcSet={generateMainImageSrcSet(baseUrl, responsiveImageConfig, shouldLoadHighQuality)}
|
|
89
|
+
title={title}
|
|
90
|
+
/>
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Thumbnail image - responsive sizes
|
|
95
|
+
return (
|
|
96
|
+
<img
|
|
97
|
+
alt={alt}
|
|
98
|
+
className="h-full max-h-[111px] w-full max-w-[111px] object-cover"
|
|
99
|
+
loading="lazy"
|
|
100
|
+
onError={(e) => {
|
|
101
|
+
const target = e.target as HTMLImageElement;
|
|
102
|
+
if (target.src !== PLACEHOLDER_IMAGE_URL) {
|
|
103
|
+
target.src = PLACEHOLDER_IMAGE_URL;
|
|
104
|
+
// Clear srcSet to prevent fallback to other sizes that might also fail
|
|
105
|
+
target.srcset = '';
|
|
106
|
+
}
|
|
107
|
+
}}
|
|
108
|
+
sizes={generateThumbnailSizesAttribute()}
|
|
109
|
+
src={getThumbnailSrc(baseUrl)}
|
|
110
|
+
srcSet={generateThumbnailSrcSet(baseUrl)}
|
|
111
|
+
title={title}
|
|
112
|
+
/>
|
|
113
|
+
);
|
|
114
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ResponsiveImage } from './ResponsiveImage';
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { cn } from '@evolve.ui/theme-system';
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef } from 'react';
|
|
3
|
+
|
|
4
|
+
import { PLACEHOLDER_IMAGE_URL, THUMBNAIL } from '../../constants';
|
|
5
|
+
import { ImageSliderCard, ResponsiveImageData } from '../../ImageSlider.types';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Props for the Thumbnails component
|
|
9
|
+
*/
|
|
10
|
+
type Props = {
|
|
11
|
+
/** Array of image cards to display as thumbnails */
|
|
12
|
+
cards: ImageSliderCard[];
|
|
13
|
+
/** Currently active page number (1-based) */
|
|
14
|
+
currentPage: number;
|
|
15
|
+
/** Function to generate responsive thumbnail sizes attribute */
|
|
16
|
+
generateThumbnailSizesAttribute: () => string;
|
|
17
|
+
/** Function to generate responsive thumbnail srcSet */
|
|
18
|
+
generateThumbnailSrcSet: (baseUrl: string) => string;
|
|
19
|
+
/** Callback fired when a thumbnail is clicked */
|
|
20
|
+
onThumbnailClick: (pageNumber: number) => void;
|
|
21
|
+
/** Orientation of the thumbnail previews */
|
|
22
|
+
orientation: 'vertical' | 'horizontal';
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Thumbnails component displays clickable thumbnail previews for image navigation.
|
|
27
|
+
* Supports both vertical and horizontal orientations with consistent 111px sizing across all viewports.
|
|
28
|
+
*/
|
|
29
|
+
export const Thumbnails = ({
|
|
30
|
+
cards,
|
|
31
|
+
currentPage,
|
|
32
|
+
generateThumbnailSizesAttribute,
|
|
33
|
+
generateThumbnailSrcSet,
|
|
34
|
+
onThumbnailClick,
|
|
35
|
+
orientation,
|
|
36
|
+
}: Props) => {
|
|
37
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
38
|
+
const thumbnailRefs = useRef<(HTMLButtonElement | null)[]>([]);
|
|
39
|
+
const previousPageRef = useRef<number>(currentPage);
|
|
40
|
+
|
|
41
|
+
// Initialize refs array to match cards length - more efficient approach
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
// Only resize if length changed, don't create new array unnecessarily
|
|
44
|
+
if (thumbnailRefs.current.length !== cards.length) {
|
|
45
|
+
thumbnailRefs.current.length = cards.length;
|
|
46
|
+
}
|
|
47
|
+
}, [cards.length]);
|
|
48
|
+
|
|
49
|
+
// Helper function to modify baseUrl query parameters for quality and sharpening
|
|
50
|
+
// Memoized to avoid repeated URL object creation
|
|
51
|
+
const enhanceBaseUrl = useCallback((baseUrl: string) => {
|
|
52
|
+
// Use string manipulation instead of URL constructor for better performance
|
|
53
|
+
const hasParams = baseUrl.includes('?');
|
|
54
|
+
const separator = hasParams ? '&' : '?';
|
|
55
|
+
return `${baseUrl}${separator}quality=${THUMBNAIL.QUALITY}&sharpen=false`;
|
|
56
|
+
}, []);
|
|
57
|
+
|
|
58
|
+
// Helper function to render thumbnail images with low fetch priority
|
|
59
|
+
const renderThumbnailImage = useCallback(
|
|
60
|
+
(imageData: ResponsiveImageData, index: number, thumbnailSize: number) => {
|
|
61
|
+
const { alt, baseUrl, title } = imageData;
|
|
62
|
+
const enhancedBaseUrl = enhanceBaseUrl(baseUrl);
|
|
63
|
+
return (
|
|
64
|
+
<img
|
|
65
|
+
alt={alt}
|
|
66
|
+
className={`h-full max-h-[${thumbnailSize}px] w-full max-w-[${thumbnailSize}px] bg-background-primary object-contain`}
|
|
67
|
+
fetchPriority={index <= 5 ? 'high' : 'low'}
|
|
68
|
+
loading={index <= 5 ? 'eager' : 'lazy'}
|
|
69
|
+
onError={(e) => {
|
|
70
|
+
const target = e.target as HTMLImageElement;
|
|
71
|
+
if (target.src !== PLACEHOLDER_IMAGE_URL) {
|
|
72
|
+
target.src = PLACEHOLDER_IMAGE_URL;
|
|
73
|
+
// Clear srcSet to prevent fallback to other sizes that might also fail
|
|
74
|
+
target.srcset = '';
|
|
75
|
+
}
|
|
76
|
+
}}
|
|
77
|
+
sizes={generateThumbnailSizesAttribute()}
|
|
78
|
+
src={`${enhancedBaseUrl}&width=${thumbnailSize}`} // Fallback for browsers without srcSet support
|
|
79
|
+
srcSet={generateThumbnailSrcSet(enhancedBaseUrl)}
|
|
80
|
+
title={title}
|
|
81
|
+
/>
|
|
82
|
+
);
|
|
83
|
+
},
|
|
84
|
+
[generateThumbnailSrcSet, generateThumbnailSizesAttribute, enhanceBaseUrl]
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
// Auto-scroll the active thumbnail into view when currentPage changes
|
|
88
|
+
// Only scroll if the page actually changed (not on mount or remount from mobile → desktop)
|
|
89
|
+
useEffect(() => {
|
|
90
|
+
const pageChanged = previousPageRef.current !== currentPage;
|
|
91
|
+
|
|
92
|
+
// Update the ref for next comparison
|
|
93
|
+
previousPageRef.current = currentPage;
|
|
94
|
+
|
|
95
|
+
// Only scroll if the page actually changed
|
|
96
|
+
if (!pageChanged) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const activeIndex = currentPage - 1;
|
|
101
|
+
const activeThumbnail = thumbnailRefs.current[activeIndex];
|
|
102
|
+
|
|
103
|
+
if (activeThumbnail && containerRef.current) {
|
|
104
|
+
activeThumbnail.scrollIntoView({
|
|
105
|
+
behavior: 'smooth',
|
|
106
|
+
block: 'nearest',
|
|
107
|
+
inline: 'center',
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}, [currentPage, orientation]);
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Creates thumbnail preview images that can be clicked to navigate to specific images.
|
|
114
|
+
* Supports both horizontal and vertical orientations with configurable size and dimming.
|
|
115
|
+
* Supports both custom ReactNode cards and responsive imageData.
|
|
116
|
+
*/
|
|
117
|
+
const thumbnailPreviews = useMemo(() => {
|
|
118
|
+
const isHorizontal = orientation === 'horizontal';
|
|
119
|
+
const thumbnailSize = isHorizontal ? 48 : THUMBNAIL.SIZE;
|
|
120
|
+
|
|
121
|
+
return cards.map(({ card, imageData, key }, index) => {
|
|
122
|
+
const pageNumber = index + 1;
|
|
123
|
+
const isActive = currentPage === pageNumber;
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<button
|
|
127
|
+
aria-current={isActive ? 'true' : 'false'}
|
|
128
|
+
aria-label={`Go to image ${pageNumber}${imageData?.alt ? `: ${imageData.alt}` : ''}`}
|
|
129
|
+
aria-selected={isActive}
|
|
130
|
+
className={cn(
|
|
131
|
+
'box-border flex-shrink-0 cursor-pointer overflow-hidden rounded-md transition-all duration-100',
|
|
132
|
+
'hui-focus-visible-outline hover:opacity-80 focus:-outline-offset-4',
|
|
133
|
+
`aspect-square h-[${thumbnailSize}px] w-[${thumbnailSize}px] max-h-[${thumbnailSize}px] max-w-[${thumbnailSize}px]`,
|
|
134
|
+
// Use outline instead of border to avoid affecting box dimensions
|
|
135
|
+
isActive
|
|
136
|
+
? 'opacity-100 outline outline-2 -outline-offset-2 outline-border-selected'
|
|
137
|
+
: 'opacity-50 outline outline-1 -outline-offset-1 outline-border-secondary'
|
|
138
|
+
)}
|
|
139
|
+
data-active={isActive}
|
|
140
|
+
data-page={pageNumber}
|
|
141
|
+
key={key}
|
|
142
|
+
onClick={() => onThumbnailClick(pageNumber)}
|
|
143
|
+
ref={(el) => {
|
|
144
|
+
thumbnailRefs.current[index] = el;
|
|
145
|
+
}}
|
|
146
|
+
role="tab"
|
|
147
|
+
style={{
|
|
148
|
+
height: `${thumbnailSize}px`,
|
|
149
|
+
maxHeight: `${thumbnailSize}px`,
|
|
150
|
+
maxWidth: `${thumbnailSize}px`,
|
|
151
|
+
width: `${thumbnailSize}px`,
|
|
152
|
+
}}
|
|
153
|
+
type="button"
|
|
154
|
+
>
|
|
155
|
+
<div className="h-full w-full bg-background-primary">
|
|
156
|
+
{/* Render responsive image if imageData is provided, otherwise use custom card */}
|
|
157
|
+
{imageData ? renderThumbnailImage(imageData, index, thumbnailSize) : card}
|
|
158
|
+
</div>
|
|
159
|
+
</button>
|
|
160
|
+
);
|
|
161
|
+
});
|
|
162
|
+
}, [cards, currentPage, onThumbnailClick, renderThumbnailImage, orientation]);
|
|
163
|
+
|
|
164
|
+
const isHorizontal = orientation === 'horizontal';
|
|
165
|
+
|
|
166
|
+
return (
|
|
167
|
+
<div
|
|
168
|
+
aria-label="Image thumbnails"
|
|
169
|
+
className={cn(
|
|
170
|
+
'flex xsMax:hidden',
|
|
171
|
+
isHorizontal
|
|
172
|
+
? 'w-full flex-row justify-center overflow-x-auto overflow-y-hidden pb-2xs'
|
|
173
|
+
: 'h-full w-[136px] flex-col overflow-y-auto overflow-x-hidden pr-2xs mdMax:w-[128px]'
|
|
174
|
+
)}
|
|
175
|
+
ref={containerRef}
|
|
176
|
+
role="tablist"
|
|
177
|
+
style={{
|
|
178
|
+
scrollbarWidth: 'thin',
|
|
179
|
+
}}
|
|
180
|
+
>
|
|
181
|
+
<div className={cn('flex gap-xs', isHorizontal ? 'flex-row' : 'flex-col')}>{thumbnailPreviews}</div>
|
|
182
|
+
</div>
|
|
183
|
+
);
|
|
184
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { spacing } from '@evolve.ui/theme-system/themes/common';
|
|
2
|
+
|
|
3
|
+
import placeholderImage from './assets/placeholder.svg';
|
|
4
|
+
import { ImageSliderCard } from './ImageSlider.types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Constants used throughout the ImageSlider component
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Breakpoints
|
|
11
|
+
export const MOBILE_BREAKPOINT = 768;
|
|
12
|
+
export const MOBILE_BREAKPOINT_QUERY = `(max-width: ${MOBILE_BREAKPOINT}px)`;
|
|
13
|
+
|
|
14
|
+
// Spacing values (use design tokens)
|
|
15
|
+
export const SPACING = {
|
|
16
|
+
GAP_2XS: spacing.xxsValue, // gap-2xs (4px)
|
|
17
|
+
GAP_MD: spacing.mdValue, // gap-md (24px)
|
|
18
|
+
MARGIN_SM: spacing.smValue, // ml-sm, mr-sm (16px)
|
|
19
|
+
} as const;
|
|
20
|
+
|
|
21
|
+
// Thumbnail dimensions
|
|
22
|
+
export const THUMBNAIL = {
|
|
23
|
+
QUALITY: 50, // Thumbnail quality setting
|
|
24
|
+
SIZE: 111, // Fixed thumbnail size
|
|
25
|
+
WIDTH_PARAM: 107, // URL width parameter for thumbnails
|
|
26
|
+
} as const;
|
|
27
|
+
|
|
28
|
+
// Mobile card dimensions
|
|
29
|
+
export const MOBILE_CARD = {
|
|
30
|
+
MAX_WIDTH: 651, // Max card width
|
|
31
|
+
WIDTH_REDUCTION: 64, // calc(100% - 64px) to match container extension for optimal bleed effect
|
|
32
|
+
} as const;
|
|
33
|
+
|
|
34
|
+
// Animation timings
|
|
35
|
+
export const ANIMATION = {
|
|
36
|
+
DEBOUNCE_DELAY: 100, // Scroll handler debounce delay
|
|
37
|
+
SCROLL_TIMEOUT: 300, // Smooth scroll animation duration
|
|
38
|
+
} as const;
|
|
39
|
+
|
|
40
|
+
// Navigation button positioning
|
|
41
|
+
export const NAVIGATION = {
|
|
42
|
+
INSIDE_TOP_OFFSET: 21, // top-[calc(50%-21px)]
|
|
43
|
+
OUTSIDE_TOP_OFFSET: 17, // top-[calc(50%-17px)]
|
|
44
|
+
} as const;
|
|
45
|
+
|
|
46
|
+
// Bundled brand-neutral fallback (inlined as a data URI at build time) — the image-error
|
|
47
|
+
// fallback must never depend on an external CDN.
|
|
48
|
+
export const PLACEHOLDER_IMAGE_URL = placeholderImage;
|
|
49
|
+
|
|
50
|
+
export const PLACEHOLDER_EMPTY_CARDS: ImageSliderCard[] = [
|
|
51
|
+
{
|
|
52
|
+
imageData: {
|
|
53
|
+
alt: 'Placeholder empty card',
|
|
54
|
+
baseUrl: PLACEHOLDER_IMAGE_URL,
|
|
55
|
+
title: 'Placeholder empty card',
|
|
56
|
+
},
|
|
57
|
+
key: 'placeholder-empty-card-1',
|
|
58
|
+
},
|
|
59
|
+
];
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { useRef, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { useWindowIsMobile } from '../../providers';
|
|
4
|
+
import { ResponsiveImageConfig } from '../ImageSlider.types';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Props for the useImageSlider hook
|
|
8
|
+
*/
|
|
9
|
+
type UseImageSliderProps = {
|
|
10
|
+
/** Number of cards/images in the slider */
|
|
11
|
+
numberOfPages: number;
|
|
12
|
+
/** Responsive image configuration */
|
|
13
|
+
responsiveImageConfig: ResponsiveImageConfig;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Main hook for ImageSlider component that provides basic state and refs
|
|
18
|
+
* Navigation and scroll handling are managed separately to avoid circular dependencies
|
|
19
|
+
* @param props - ImageSlider configuration
|
|
20
|
+
* @returns Basic state and handlers needed for the ImageSlider component
|
|
21
|
+
*/
|
|
22
|
+
export const useImageSlider = ({ numberOfPages, responsiveImageConfig }: UseImageSliderProps) => {
|
|
23
|
+
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
24
|
+
const contentRef = useRef<HTMLDivElement | null>(null);
|
|
25
|
+
|
|
26
|
+
const [hasHoveredGallery, setHasHoveredGallery] = useState(false);
|
|
27
|
+
const isMobile = useWindowIsMobile();
|
|
28
|
+
|
|
29
|
+
const handleMouseOver = () => {
|
|
30
|
+
if (!isMobile && !hasHoveredGallery) {
|
|
31
|
+
setHasHoveredGallery(true);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
const handleMobileInteraction = () => {
|
|
36
|
+
if (isMobile && !hasHoveredGallery) {
|
|
37
|
+
setHasHoveredGallery(true);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
// Refs
|
|
43
|
+
containerRef,
|
|
44
|
+
contentRef,
|
|
45
|
+
|
|
46
|
+
// Event handlers
|
|
47
|
+
handleMobileInteraction,
|
|
48
|
+
handleMouseOver,
|
|
49
|
+
|
|
50
|
+
// State
|
|
51
|
+
hasHoveredGallery,
|
|
52
|
+
isMobile,
|
|
53
|
+
numberOfPages,
|
|
54
|
+
responsiveImageConfig,
|
|
55
|
+
setHasHoveredGallery,
|
|
56
|
+
};
|
|
57
|
+
};
|