@evolve.ui/core-components 1.0.1 → 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/evolve-ui.entries.json +556 -0
- 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/package.json +2 -2
- 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
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
import { cn } from '@evolve.ui/theme-system';
|
|
2
|
+
import { useCallback, useMemo, useState, type CSSProperties } from 'react';
|
|
3
|
+
|
|
4
|
+
import { IndexIndicator } from './components/IndexIndicator/IndexIndicator';
|
|
5
|
+
import { NavigationButtons } from './components/NavigationButtons/NavigationButtons';
|
|
6
|
+
import { ResponsiveImage } from './components/ResponsiveImage';
|
|
7
|
+
import { Thumbnails } from './components/Thumbnails/Thumbnails';
|
|
8
|
+
import { PLACEHOLDER_EMPTY_CARDS } from './constants';
|
|
9
|
+
import { useImageSlider } from './hooks/useImageSlider';
|
|
10
|
+
import { useImageSliderNavigation } from './hooks/useImageSliderNavigation';
|
|
11
|
+
import { useImageSliderScrollHandler } from './hooks/useImageSliderScrollHandler';
|
|
12
|
+
import {
|
|
13
|
+
ImageSliderAnalyticsEvent,
|
|
14
|
+
ImageSliderCard,
|
|
15
|
+
ResponsiveImageConfig,
|
|
16
|
+
ThumbnailDisplay,
|
|
17
|
+
} from './ImageSlider.types';
|
|
18
|
+
import { generateThumbnailSizesAttribute, generateThumbnailSrcSet } from './utils/imageOptimization';
|
|
19
|
+
|
|
20
|
+
type Props = {
|
|
21
|
+
/**
|
|
22
|
+
* The scrollable content of the image slider.
|
|
23
|
+
* Should be individual images.
|
|
24
|
+
*
|
|
25
|
+
* @property {ReactNode} card - The rendered image content
|
|
26
|
+
* @property {string} key - A unique identifier for the image
|
|
27
|
+
*/
|
|
28
|
+
cards: ImageSliderCard[];
|
|
29
|
+
/**
|
|
30
|
+
* Class name for the image gallery container.
|
|
31
|
+
*/
|
|
32
|
+
className?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Optional key to identify when content has changed (e.g., an item id).
|
|
35
|
+
* When this key changes, the slider will reset to the first image.
|
|
36
|
+
* If not provided, will reset whenever the cards array reference changes.
|
|
37
|
+
*/
|
|
38
|
+
contentKey?: string | number;
|
|
39
|
+
/**
|
|
40
|
+
* Shape of the navigation icons.
|
|
41
|
+
* 'circle' creates round buttons, 'square' creates square buttons.
|
|
42
|
+
*
|
|
43
|
+
* @default 'circle'
|
|
44
|
+
*/
|
|
45
|
+
iconShape?: 'circle' | 'square';
|
|
46
|
+
/**
|
|
47
|
+
* Size of the navigation icons - sm=34px, md=42px, lg=54px.
|
|
48
|
+
* For horizontal thumbnails, 'lg' (54px) is recommended.
|
|
49
|
+
*
|
|
50
|
+
* @default 'sm'
|
|
51
|
+
*/
|
|
52
|
+
iconSize?: 'sm' | 'md' | 'lg';
|
|
53
|
+
/**
|
|
54
|
+
* Type of icons to use for navigation.
|
|
55
|
+
* 'caret' uses CaretLeft/CaretRight, 'arrow' uses ArrowLeft/ArrowRight.
|
|
56
|
+
*
|
|
57
|
+
* @default 'caret'
|
|
58
|
+
*/
|
|
59
|
+
iconType?: 'caret' | 'arrow';
|
|
60
|
+
/**
|
|
61
|
+
* Variant of the navigation icons.
|
|
62
|
+
* 'outlined' shows buttons with borders, 'transparent' shows borderless buttons.
|
|
63
|
+
*
|
|
64
|
+
* @default 'outlined'
|
|
65
|
+
*/
|
|
66
|
+
iconVariant?: 'outlined' | 'transparent';
|
|
67
|
+
/**
|
|
68
|
+
* When thumbnailDisplay is 'index', position of the numeric indicator relative to the main image.
|
|
69
|
+
*
|
|
70
|
+
* @default 'bottom'
|
|
71
|
+
*/
|
|
72
|
+
indexPosition?: 'top' | 'bottom';
|
|
73
|
+
/**
|
|
74
|
+
* Callback fired when an analytics event occurs in the image slider.
|
|
75
|
+
* Receives interaction type, current image position (1-based), and total image count.
|
|
76
|
+
* Does not fire for mobile swipe navigation, only for button/thumbnail clicks and lightbox opens.
|
|
77
|
+
*/
|
|
78
|
+
onAnalyticsEventTriggered?: (event: ImageSliderAnalyticsEvent) => void;
|
|
79
|
+
/**
|
|
80
|
+
* Callback fired when an image is clicked (mouse) or activated via keyboard (Enter/Space).
|
|
81
|
+
* Receives the index of the image and the mouse or keyboard event.
|
|
82
|
+
*/
|
|
83
|
+
onImageClick?: (
|
|
84
|
+
imageIndex: number,
|
|
85
|
+
event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>
|
|
86
|
+
) => void;
|
|
87
|
+
/**
|
|
88
|
+
* Callback fired when an image is hovered (mouse) or focused (keyboard/screen reader).
|
|
89
|
+
* Receives the index of the image and the mouse or focus event.
|
|
90
|
+
*/
|
|
91
|
+
onImageMouseOver?: (
|
|
92
|
+
imageIndex: number,
|
|
93
|
+
event: React.MouseEvent<HTMLElement> | React.FocusEvent<HTMLElement>
|
|
94
|
+
) => void;
|
|
95
|
+
/**
|
|
96
|
+
* Configuration for responsive image loading when using imageData in cards.
|
|
97
|
+
* Defines mobile/desktop sizes and breakpoint for optimal image loading.
|
|
98
|
+
*/
|
|
99
|
+
responsiveImageConfig?: ResponsiveImageConfig;
|
|
100
|
+
/**
|
|
101
|
+
* Displays thumbnail previews on the left side of the slider.
|
|
102
|
+
* Clicking a thumbnail will navigate to the corresponding image.
|
|
103
|
+
* The current image thumbnail will have a border highlight.
|
|
104
|
+
*
|
|
105
|
+
* @default true
|
|
106
|
+
*/
|
|
107
|
+
showThumbnails?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Display mode for image navigation controls.
|
|
110
|
+
* 'thumbnails' shows image previews (vertical or horizontal per thumbnailOrientation).
|
|
111
|
+
* 'index' shows a numeric indicator (e.g., "1 of 11") above or below the main image per indexPosition.
|
|
112
|
+
*
|
|
113
|
+
* @default ThumbnailDisplay.Thumbnails
|
|
114
|
+
*/
|
|
115
|
+
thumbnailDisplay?: ThumbnailDisplay;
|
|
116
|
+
/**
|
|
117
|
+
* Orientation of the thumbnail previews when showThumbnails is true.
|
|
118
|
+
* 'vertical' displays thumbnails on the left side, 'horizontal' displays them below the image.
|
|
119
|
+
*
|
|
120
|
+
* @default 'vertical'
|
|
121
|
+
*/
|
|
122
|
+
thumbnailOrientation?: 'vertical' | 'horizontal';
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Displays a single image at a time with navigation controls.
|
|
127
|
+
* Allows navigation via buttons, dots (pagination), or touch gestures (on mobile).
|
|
128
|
+
*/
|
|
129
|
+
// Default responsive image configuration
|
|
130
|
+
const DEFAULT_RESPONSIVE_CONFIG: ResponsiveImageConfig = {
|
|
131
|
+
breakpoint: 768,
|
|
132
|
+
desktopSize: 651,
|
|
133
|
+
mobileSize: 366,
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
export const ImageSlider = ({
|
|
137
|
+
cards: initialCards,
|
|
138
|
+
className,
|
|
139
|
+
contentKey,
|
|
140
|
+
iconShape = 'circle',
|
|
141
|
+
iconSize = 'sm',
|
|
142
|
+
iconType = 'caret',
|
|
143
|
+
iconVariant = 'outlined',
|
|
144
|
+
indexPosition = 'bottom',
|
|
145
|
+
onAnalyticsEventTriggered,
|
|
146
|
+
onImageClick,
|
|
147
|
+
onImageMouseOver,
|
|
148
|
+
responsiveImageConfig = DEFAULT_RESPONSIVE_CONFIG,
|
|
149
|
+
showThumbnails = true,
|
|
150
|
+
thumbnailDisplay = ThumbnailDisplay.Thumbnails,
|
|
151
|
+
thumbnailOrientation = 'vertical',
|
|
152
|
+
}: Props) => {
|
|
153
|
+
// When an item doesn't have images, the cards array will be empty.
|
|
154
|
+
// We need to show a placeholder empty card in this case.
|
|
155
|
+
const cards = useMemo(() => {
|
|
156
|
+
if (initialCards.length === 0) {
|
|
157
|
+
return PLACEHOLDER_EMPTY_CARDS;
|
|
158
|
+
}
|
|
159
|
+
return initialCards;
|
|
160
|
+
}, [initialCards]);
|
|
161
|
+
|
|
162
|
+
const numberOfPages = cards.length;
|
|
163
|
+
|
|
164
|
+
// Initialize base slider state and refs
|
|
165
|
+
const {
|
|
166
|
+
containerRef,
|
|
167
|
+
contentRef,
|
|
168
|
+
handleMobileInteraction,
|
|
169
|
+
handleMouseOver,
|
|
170
|
+
hasHoveredGallery,
|
|
171
|
+
isMobile,
|
|
172
|
+
setHasHoveredGallery,
|
|
173
|
+
} = useImageSlider({
|
|
174
|
+
numberOfPages,
|
|
175
|
+
responsiveImageConfig,
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// Manage scrolling state locally to avoid circular dependency
|
|
179
|
+
const [isScrolling, setIsScrolling] = useState(false);
|
|
180
|
+
|
|
181
|
+
// Initialize navigation state and handlers
|
|
182
|
+
const navigation = useImageSliderNavigation({
|
|
183
|
+
cards,
|
|
184
|
+
contentKey,
|
|
185
|
+
contentRef,
|
|
186
|
+
isScrolling,
|
|
187
|
+
numberOfPages,
|
|
188
|
+
setHasHoveredGallery,
|
|
189
|
+
thumbnailDisplay,
|
|
190
|
+
thumbnailOrientation,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// Initialize scroll handling with navigation state and local setIsScrolling
|
|
194
|
+
const { onScrollCards } = useImageSliderScrollHandler({
|
|
195
|
+
contentRef,
|
|
196
|
+
currentPage: navigation.currentPage,
|
|
197
|
+
maxMobileCardWidth: responsiveImageConfig.desktopSize,
|
|
198
|
+
numberOfPages,
|
|
199
|
+
setCurrentPage: navigation.setCurrentPage,
|
|
200
|
+
setIsScrolling,
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// Extract all the values we need
|
|
204
|
+
const {
|
|
205
|
+
currentPage,
|
|
206
|
+
goToNextPage,
|
|
207
|
+
goToPreviousPage,
|
|
208
|
+
handleThumbnailClick,
|
|
209
|
+
isNextPageDisabled,
|
|
210
|
+
isPreviousPageDisabled,
|
|
211
|
+
onKeyNavigation,
|
|
212
|
+
showNextPageButton,
|
|
213
|
+
showPreviousPageButton,
|
|
214
|
+
} = navigation;
|
|
215
|
+
|
|
216
|
+
// Wrap navigation handlers to trigger analytics
|
|
217
|
+
const goToNextPageWithAnalytics = useCallback(() => {
|
|
218
|
+
goToNextPage();
|
|
219
|
+
onAnalyticsEventTriggered?.({
|
|
220
|
+
imagePosition: currentPage < numberOfPages ? currentPage + 1 : 1,
|
|
221
|
+
interactionType: 'Next',
|
|
222
|
+
totalImages: numberOfPages,
|
|
223
|
+
});
|
|
224
|
+
}, [goToNextPage, onAnalyticsEventTriggered, currentPage, numberOfPages]);
|
|
225
|
+
|
|
226
|
+
const goToPreviousPageWithAnalytics = useCallback(() => {
|
|
227
|
+
goToPreviousPage();
|
|
228
|
+
onAnalyticsEventTriggered?.({
|
|
229
|
+
imagePosition: currentPage > 1 ? currentPage - 1 : numberOfPages,
|
|
230
|
+
interactionType: 'Prev',
|
|
231
|
+
totalImages: numberOfPages,
|
|
232
|
+
});
|
|
233
|
+
}, [goToPreviousPage, onAnalyticsEventTriggered, currentPage, numberOfPages]);
|
|
234
|
+
|
|
235
|
+
const handleThumbnailClickWithAnalytics = useCallback(
|
|
236
|
+
(pageNumber: number) => {
|
|
237
|
+
// Only trigger analytics if navigating to a different image
|
|
238
|
+
if (pageNumber !== currentPage && onAnalyticsEventTriggered) {
|
|
239
|
+
onAnalyticsEventTriggered({
|
|
240
|
+
imagePosition: pageNumber,
|
|
241
|
+
interactionType: 'Thumbnail Click',
|
|
242
|
+
totalImages: numberOfPages,
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
handleThumbnailClick(pageNumber);
|
|
246
|
+
},
|
|
247
|
+
[currentPage, handleThumbnailClick, onAnalyticsEventTriggered, numberOfPages]
|
|
248
|
+
);
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* These images are wrapped in a div and displayed one at a time with proper snap behavior.
|
|
252
|
+
* When showImageOverflow is enabled on mobile, images take partial width to show overflow.
|
|
253
|
+
* Supports both custom ReactNode cards and responsive imageData.
|
|
254
|
+
* Images are re-rendered when currentPage changes to ensure active image gets full quality.
|
|
255
|
+
*
|
|
256
|
+
* On desktop before hover: Only render first image to avoid loading second image unnecessarily.
|
|
257
|
+
* On mobile: Always render all images for swipe functionality.
|
|
258
|
+
* After hover on desktop: Render all images for navigation.
|
|
259
|
+
*/
|
|
260
|
+
const carouselCards = useMemo(() => {
|
|
261
|
+
// On desktop before hover, only render the first image to prevent unnecessary loading
|
|
262
|
+
// On mobile or after hover, render all images
|
|
263
|
+
const cardsToRender = !isMobile && !hasHoveredGallery ? cards.slice(0, 1) : cards;
|
|
264
|
+
|
|
265
|
+
return cardsToRender.map(({ card, imageData, key }, index) => {
|
|
266
|
+
// For the sliced scenario, we need to get the actual index from the original cards array
|
|
267
|
+
const actualIndex = !isMobile && !hasHoveredGallery ? 0 : index;
|
|
268
|
+
const isActive = actualIndex + 1 === currentPage;
|
|
269
|
+
|
|
270
|
+
return (
|
|
271
|
+
<div
|
|
272
|
+
aria-current={isActive ? 'true' : 'false'}
|
|
273
|
+
aria-label={`Image ${actualIndex + 1} of ${cards.length}${imageData?.alt ? `: ${imageData.alt}` : ''}`}
|
|
274
|
+
className={cn(
|
|
275
|
+
'flex w-full flex-none snap-center items-center justify-center bg-background-primary',
|
|
276
|
+
onImageClick ? 'cursor-zoom-in' : 'cursor-default',
|
|
277
|
+
// Desktop: full height
|
|
278
|
+
'smMin:h-full',
|
|
279
|
+
// Mobile-specific styling (xsMax) — max dimensions follow responsiveImageConfig.desktopSize via --slider-size
|
|
280
|
+
'xsMax:aspect-square xsMax:max-h-[var(--slider-size)] xsMax:max-w-[var(--slider-size)] xsMax:overflow-hidden xsMax:rounded-lg xsMax:border xsMax:border-border-secondary',
|
|
281
|
+
// Apply width reduction only when there are multiple cards for bleed effect
|
|
282
|
+
numberOfPages > 1
|
|
283
|
+
? 'xsMax:w-[calc(100%-64px)] xsMax:max-w-[var(--slider-size)]'
|
|
284
|
+
: 'xsMax:w-full xsMax:max-w-[var(--slider-size)]',
|
|
285
|
+
{
|
|
286
|
+
'ml-sm': actualIndex === 0,
|
|
287
|
+
'mr-sm': actualIndex === cards.length - 1,
|
|
288
|
+
}
|
|
289
|
+
)}
|
|
290
|
+
key={key} // Use stable key to avoid unnecessary DOM recreations
|
|
291
|
+
onClick={(event) => {
|
|
292
|
+
// Trigger mobile interaction for high-quality loading
|
|
293
|
+
handleMobileInteraction();
|
|
294
|
+
// Trigger analytics for lightbox open
|
|
295
|
+
if (onAnalyticsEventTriggered) {
|
|
296
|
+
onAnalyticsEventTriggered({
|
|
297
|
+
imagePosition: actualIndex + 1,
|
|
298
|
+
interactionType: 'Open Lightbox',
|
|
299
|
+
totalImages: numberOfPages,
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
// Call optional user-provided handler
|
|
303
|
+
onImageClick?.(actualIndex, event);
|
|
304
|
+
}}
|
|
305
|
+
onFocus={(event) => {
|
|
306
|
+
// Trigger mobile interaction for high-quality loading
|
|
307
|
+
handleMobileInteraction();
|
|
308
|
+
// Call optional user-provided handler
|
|
309
|
+
onImageMouseOver?.(actualIndex, event);
|
|
310
|
+
}}
|
|
311
|
+
onKeyUp={
|
|
312
|
+
onImageClick
|
|
313
|
+
? (event) => {
|
|
314
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
315
|
+
event.preventDefault();
|
|
316
|
+
// Trigger analytics for lightbox open via keyboard
|
|
317
|
+
if (onAnalyticsEventTriggered) {
|
|
318
|
+
onAnalyticsEventTriggered({
|
|
319
|
+
imagePosition: actualIndex + 1,
|
|
320
|
+
interactionType: 'Open Lightbox',
|
|
321
|
+
totalImages: numberOfPages,
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
if (event.key === 'Enter') {
|
|
325
|
+
onImageClick(actualIndex, event);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
: undefined
|
|
330
|
+
}
|
|
331
|
+
onMouseOver={(event) => {
|
|
332
|
+
// Always trigger gallery hover state for high-quality loading
|
|
333
|
+
handleMouseOver();
|
|
334
|
+
// Call optional user-provided handler
|
|
335
|
+
if (onImageMouseOver) {
|
|
336
|
+
onImageMouseOver(actualIndex, event);
|
|
337
|
+
}
|
|
338
|
+
}}
|
|
339
|
+
onTouchStart={() => {
|
|
340
|
+
// Trigger mobile interaction for high-quality loading on touch/drag
|
|
341
|
+
handleMobileInteraction();
|
|
342
|
+
}}
|
|
343
|
+
role={onImageClick ? 'button' : undefined}
|
|
344
|
+
tabIndex={onImageClick ? 0 : undefined}
|
|
345
|
+
>
|
|
346
|
+
{/* Render responsive image if imageData is provided, otherwise use custom card */}
|
|
347
|
+
{imageData ? (
|
|
348
|
+
<ResponsiveImage
|
|
349
|
+
hasHoveredGallery={hasHoveredGallery}
|
|
350
|
+
imageData={imageData}
|
|
351
|
+
isActiveImage={isActive}
|
|
352
|
+
isMainImage
|
|
353
|
+
responsiveImageConfig={responsiveImageConfig}
|
|
354
|
+
/>
|
|
355
|
+
) : (
|
|
356
|
+
card || null
|
|
357
|
+
)}
|
|
358
|
+
</div>
|
|
359
|
+
);
|
|
360
|
+
});
|
|
361
|
+
}, [
|
|
362
|
+
cards,
|
|
363
|
+
currentPage,
|
|
364
|
+
handleMobileInteraction,
|
|
365
|
+
handleMouseOver,
|
|
366
|
+
hasHoveredGallery,
|
|
367
|
+
isMobile,
|
|
368
|
+
numberOfPages,
|
|
369
|
+
onAnalyticsEventTriggered,
|
|
370
|
+
onImageClick,
|
|
371
|
+
onImageMouseOver,
|
|
372
|
+
responsiveImageConfig,
|
|
373
|
+
]);
|
|
374
|
+
|
|
375
|
+
const isIndexDisplay = thumbnailDisplay === ThumbnailDisplay.Index;
|
|
376
|
+
const isHorizontalThumbnailsDisplay =
|
|
377
|
+
thumbnailDisplay === ThumbnailDisplay.Thumbnails && thumbnailOrientation === 'horizontal';
|
|
378
|
+
|
|
379
|
+
return (
|
|
380
|
+
// eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/mouse-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/tabindex-no-positive
|
|
381
|
+
<section
|
|
382
|
+
aria-label="Image gallery"
|
|
383
|
+
aria-roledescription="carousel"
|
|
384
|
+
className={cn(
|
|
385
|
+
'relative mx-auto w-full pr-lg outline-none smMax:pr-0',
|
|
386
|
+
// Only extend beyond viewport for bleed effect when there are multiple cards
|
|
387
|
+
{ 'xsMax:-ml-sm xsMax:w-[calc(100%+32px)]': numberOfPages > 1 },
|
|
388
|
+
className
|
|
389
|
+
)}
|
|
390
|
+
onClick={() => containerRef.current?.focus()}
|
|
391
|
+
onKeyUp={onKeyNavigation}
|
|
392
|
+
onMouseOver={handleMouseOver}
|
|
393
|
+
ref={containerRef}
|
|
394
|
+
role="application"
|
|
395
|
+
style={
|
|
396
|
+
{
|
|
397
|
+
'--slider-size': `${responsiveImageConfig.desktopSize}px`,
|
|
398
|
+
} as CSSProperties
|
|
399
|
+
}
|
|
400
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
401
|
+
tabIndex={0}
|
|
402
|
+
>
|
|
403
|
+
<div
|
|
404
|
+
className={cn(
|
|
405
|
+
'flex flex-col',
|
|
406
|
+
// Dynamic gap that scales smoothly from ~58px down to smaller sizes
|
|
407
|
+
'gap-[58px] mdMax:gap-xl smMax:gap-[38px] xsMax:gap-[28px]'
|
|
408
|
+
)}
|
|
409
|
+
>
|
|
410
|
+
{/* Image Gallery Container */}
|
|
411
|
+
<div
|
|
412
|
+
className={cn(
|
|
413
|
+
'flex w-full',
|
|
414
|
+
thumbnailDisplay === ThumbnailDisplay.Index
|
|
415
|
+
? 'flex-col items-center justify-center gap-2xs'
|
|
416
|
+
: thumbnailOrientation === 'horizontal'
|
|
417
|
+
? 'flex-col items-center justify-center gap-xs'
|
|
418
|
+
: 'relative items-center justify-center gap-[28px]'
|
|
419
|
+
)}
|
|
420
|
+
>
|
|
421
|
+
{/* Index indicator - above main image when thumbnailDisplay is 'index' and indexPosition is 'top' */}
|
|
422
|
+
{thumbnailDisplay === ThumbnailDisplay.Index && indexPosition === 'top' && (
|
|
423
|
+
<IndexIndicator
|
|
424
|
+
currentPage={currentPage}
|
|
425
|
+
numberOfPages={numberOfPages}
|
|
426
|
+
/>
|
|
427
|
+
)}
|
|
428
|
+
|
|
429
|
+
{/* Vertical Thumbnails Container - Absolutely positioned */}
|
|
430
|
+
{showThumbnails &&
|
|
431
|
+
thumbnailDisplay === ThumbnailDisplay.Thumbnails &&
|
|
432
|
+
thumbnailOrientation === 'vertical' && (
|
|
433
|
+
<div className="absolute bottom-0 left-0 top-0 z-10 xsMax:hidden">
|
|
434
|
+
<Thumbnails
|
|
435
|
+
cards={cards}
|
|
436
|
+
currentPage={currentPage}
|
|
437
|
+
generateThumbnailSizesAttribute={generateThumbnailSizesAttribute}
|
|
438
|
+
generateThumbnailSrcSet={generateThumbnailSrcSet}
|
|
439
|
+
onThumbnailClick={handleThumbnailClickWithAnalytics}
|
|
440
|
+
orientation="vertical"
|
|
441
|
+
/>
|
|
442
|
+
</div>
|
|
443
|
+
)}
|
|
444
|
+
|
|
445
|
+
{/* Main Image Area */}
|
|
446
|
+
<div
|
|
447
|
+
className={cn(
|
|
448
|
+
'flex items-center',
|
|
449
|
+
isIndexDisplay
|
|
450
|
+
? 'relative w-full justify-center gap-md smMin:max-w-[780px] xsMax:w-full'
|
|
451
|
+
: isHorizontalThumbnailsDisplay
|
|
452
|
+
? 'max-w-[606px] gap-md xsMax:w-full'
|
|
453
|
+
: cn(
|
|
454
|
+
'w-full justify-between gap-sm',
|
|
455
|
+
showThumbnails ? 'pl-[146px] mdMax:pl-[139px] xsMax:pl-0' : ''
|
|
456
|
+
)
|
|
457
|
+
)}
|
|
458
|
+
data-testid="image-slider-hero-controls"
|
|
459
|
+
>
|
|
460
|
+
{/* Desktop navigation buttons (left) - hidden on mobile */}
|
|
461
|
+
<div className="hidden smMin:block">
|
|
462
|
+
<NavigationButtons
|
|
463
|
+
goToNextPage={goToNextPageWithAnalytics}
|
|
464
|
+
goToPreviousPage={goToPreviousPageWithAnalytics}
|
|
465
|
+
iconShape={iconShape}
|
|
466
|
+
iconSize={iconSize}
|
|
467
|
+
iconType={iconType}
|
|
468
|
+
iconVariant={iconVariant}
|
|
469
|
+
isNextPageDisabled={isNextPageDisabled}
|
|
470
|
+
isPreviousPageDisabled={isPreviousPageDisabled}
|
|
471
|
+
position="left"
|
|
472
|
+
showNextPageButton={showNextPageButton}
|
|
473
|
+
showPreviousPageButton={showPreviousPageButton}
|
|
474
|
+
/>
|
|
475
|
+
</div>
|
|
476
|
+
|
|
477
|
+
{/* Main image container - responsive layout */}
|
|
478
|
+
<div
|
|
479
|
+
className={cn(
|
|
480
|
+
// Shared: relative container with consistent max dimensions
|
|
481
|
+
'relative',
|
|
482
|
+
isIndexDisplay
|
|
483
|
+
? 'max-h-[var(--slider-size)] smMin:flex smMin:aspect-square smMin:max-w-[var(--slider-size)] smMin:flex-1 smMin:justify-center smMin:overflow-hidden xsMax:w-full'
|
|
484
|
+
: isHorizontalThumbnailsDisplay
|
|
485
|
+
? 'max-h-[400px] smMin:flex smMin:aspect-square smMin:max-w-[400px] smMin:flex-1 smMin:justify-center smMin:overflow-hidden xsMax:w-full'
|
|
486
|
+
: 'max-h-[var(--slider-size)] smMin:flex smMin:aspect-square smMin:max-w-[var(--slider-size)] smMin:flex-1 smMin:justify-center smMin:overflow-hidden xsMax:w-full'
|
|
487
|
+
)}
|
|
488
|
+
data-testid="image-slider-media-frame"
|
|
489
|
+
>
|
|
490
|
+
{/* Mobile navigation buttons - hidden on desktop */}
|
|
491
|
+
<div className="smMin:hidden">
|
|
492
|
+
<NavigationButtons
|
|
493
|
+
goToNextPage={goToNextPageWithAnalytics}
|
|
494
|
+
goToPreviousPage={goToPreviousPageWithAnalytics}
|
|
495
|
+
iconShape={iconShape}
|
|
496
|
+
iconSize={iconSize}
|
|
497
|
+
iconType={iconType}
|
|
498
|
+
iconVariant={iconVariant}
|
|
499
|
+
isNextPageDisabled={isNextPageDisabled}
|
|
500
|
+
isPreviousPageDisabled={isPreviousPageDisabled}
|
|
501
|
+
showNextPageButton={showNextPageButton}
|
|
502
|
+
showPreviousPageButton={showPreviousPageButton}
|
|
503
|
+
/>
|
|
504
|
+
</div>
|
|
505
|
+
|
|
506
|
+
{/* Responsive scroll container wrapper */}
|
|
507
|
+
<div
|
|
508
|
+
className={cn(
|
|
509
|
+
// Shared: primary background and full width
|
|
510
|
+
'w-full bg-background-primary',
|
|
511
|
+
// Desktop: full height and hidden overflow
|
|
512
|
+
'smMin:h-full smMin:overflow-hidden'
|
|
513
|
+
)}
|
|
514
|
+
>
|
|
515
|
+
<div
|
|
516
|
+
aria-atomic="false"
|
|
517
|
+
aria-live="polite"
|
|
518
|
+
className={cn(
|
|
519
|
+
'flex w-full snap-x snap-mandatory overflow-y-hidden overflow-x-scroll',
|
|
520
|
+
// Desktop: full height and 24px gap
|
|
521
|
+
'smMin:h-full smMin:gap-md',
|
|
522
|
+
// Mobile: 2xs gap, let aspect-square control height
|
|
523
|
+
'xsMax:gap-2xs'
|
|
524
|
+
)}
|
|
525
|
+
onScroll={onScrollCards}
|
|
526
|
+
ref={contentRef}
|
|
527
|
+
role="region"
|
|
528
|
+
style={{
|
|
529
|
+
scrollbarWidth: 'none',
|
|
530
|
+
}}
|
|
531
|
+
>
|
|
532
|
+
{carouselCards}
|
|
533
|
+
</div>
|
|
534
|
+
</div>
|
|
535
|
+
</div>
|
|
536
|
+
|
|
537
|
+
{/* Desktop navigation buttons (right) - hidden on mobile */}
|
|
538
|
+
<div className="hidden smMin:block">
|
|
539
|
+
<NavigationButtons
|
|
540
|
+
goToNextPage={goToNextPageWithAnalytics}
|
|
541
|
+
goToPreviousPage={goToPreviousPageWithAnalytics}
|
|
542
|
+
iconShape={iconShape}
|
|
543
|
+
iconSize={iconSize}
|
|
544
|
+
iconType={iconType}
|
|
545
|
+
iconVariant={iconVariant}
|
|
546
|
+
isNextPageDisabled={isNextPageDisabled}
|
|
547
|
+
isPreviousPageDisabled={isPreviousPageDisabled}
|
|
548
|
+
position="right"
|
|
549
|
+
showNextPageButton={showNextPageButton}
|
|
550
|
+
showPreviousPageButton={showPreviousPageButton}
|
|
551
|
+
/>
|
|
552
|
+
</div>
|
|
553
|
+
</div>
|
|
554
|
+
|
|
555
|
+
{/* Horizontal Thumbnails Container - Below image */}
|
|
556
|
+
{showThumbnails &&
|
|
557
|
+
thumbnailDisplay === ThumbnailDisplay.Thumbnails &&
|
|
558
|
+
thumbnailOrientation === 'horizontal' && (
|
|
559
|
+
<div className="w-full xsMax:hidden">
|
|
560
|
+
<Thumbnails
|
|
561
|
+
cards={cards}
|
|
562
|
+
currentPage={currentPage}
|
|
563
|
+
generateThumbnailSizesAttribute={generateThumbnailSizesAttribute}
|
|
564
|
+
generateThumbnailSrcSet={generateThumbnailSrcSet}
|
|
565
|
+
onThumbnailClick={handleThumbnailClickWithAnalytics}
|
|
566
|
+
orientation="horizontal"
|
|
567
|
+
/>
|
|
568
|
+
</div>
|
|
569
|
+
)}
|
|
570
|
+
|
|
571
|
+
{/* Index indicator - below main image when thumbnailDisplay is 'index' and indexPosition is 'bottom' */}
|
|
572
|
+
{thumbnailDisplay === ThumbnailDisplay.Index && indexPosition === 'bottom' && (
|
|
573
|
+
<IndexIndicator
|
|
574
|
+
currentPage={currentPage}
|
|
575
|
+
numberOfPages={numberOfPages}
|
|
576
|
+
/>
|
|
577
|
+
)}
|
|
578
|
+
</div>
|
|
579
|
+
</div>
|
|
580
|
+
</section>
|
|
581
|
+
);
|
|
582
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Display mode for thumbnail navigation
|
|
5
|
+
*/
|
|
6
|
+
export enum ThumbnailDisplay {
|
|
7
|
+
Index = 'index',
|
|
8
|
+
Thumbnails = 'thumbnails',
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Analytics event data for ImageSlider interactions
|
|
13
|
+
*/
|
|
14
|
+
export type ImageSliderAnalyticsEvent = {
|
|
15
|
+
/** Current image position (1-based index) */
|
|
16
|
+
imagePosition: number;
|
|
17
|
+
/** Type of interaction that triggered the event */
|
|
18
|
+
interactionType: 'Thumbnail Click' | 'Next' | 'Prev' | 'Open Lightbox';
|
|
19
|
+
/** Total number of images in the slider */
|
|
20
|
+
totalImages: number;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Responsive image data for optimized loading
|
|
25
|
+
*/
|
|
26
|
+
export type ResponsiveImageData = {
|
|
27
|
+
/**
|
|
28
|
+
* Alt text for the image
|
|
29
|
+
*/
|
|
30
|
+
alt: string;
|
|
31
|
+
/**
|
|
32
|
+
* Base URL for the image (without width parameters)
|
|
33
|
+
*/
|
|
34
|
+
baseUrl: string;
|
|
35
|
+
/**
|
|
36
|
+
* Optional title for the image
|
|
37
|
+
*/
|
|
38
|
+
title?: string;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Configuration for responsive image sizes and breakpoints
|
|
43
|
+
*/
|
|
44
|
+
export type ResponsiveImageConfig = {
|
|
45
|
+
/**
|
|
46
|
+
* Breakpoint width in pixels where mobile switches to desktop
|
|
47
|
+
* @default 768
|
|
48
|
+
*/
|
|
49
|
+
breakpoint: number;
|
|
50
|
+
/**
|
|
51
|
+
* Desktop image width in pixels
|
|
52
|
+
* @default 651
|
|
53
|
+
*/
|
|
54
|
+
desktopSize: number;
|
|
55
|
+
/**
|
|
56
|
+
* Mobile image width in pixels
|
|
57
|
+
* @default 366
|
|
58
|
+
*/
|
|
59
|
+
mobileSize: number;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Card for the ImageSlider - supports both custom ReactNode and responsive images
|
|
64
|
+
*/
|
|
65
|
+
export type ImageSliderCard = {
|
|
66
|
+
/**
|
|
67
|
+
* The rendered content of the card or image.
|
|
68
|
+
* Optional when using imageData.
|
|
69
|
+
*/
|
|
70
|
+
card?: ReactNode;
|
|
71
|
+
/**
|
|
72
|
+
* Responsive image data for automatic srcset/sizes optimization.
|
|
73
|
+
* When provided, `card` will be ignored and an optimized <img> will be rendered.
|
|
74
|
+
* Optional when using custom card content.
|
|
75
|
+
*/
|
|
76
|
+
imageData?: ResponsiveImageData;
|
|
77
|
+
/**
|
|
78
|
+
* The unique identifier for the card
|
|
79
|
+
*/
|
|
80
|
+
key: string;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export type ImageSliderPageInfo = {
|
|
84
|
+
breakpoints: number[];
|
|
85
|
+
cardsPerPage: number;
|
|
86
|
+
numberOfPages: number;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// this is the px size of the MD gap (kept for potential future use)
|
|
90
|
+
export const CAROUSEL_CARD_GAP_NUM = 24;
|