@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,273 @@
|
|
|
1
|
+
import { UploadValidationContextType } from '../../../providers/UploadValidationProvider';
|
|
2
|
+
import {
|
|
3
|
+
ContextAwareMessage,
|
|
4
|
+
DynamicMessageContext,
|
|
5
|
+
FileError,
|
|
6
|
+
FileRejection,
|
|
7
|
+
FileResource,
|
|
8
|
+
ValidationError,
|
|
9
|
+
} from '../../../types/commonTypes';
|
|
10
|
+
import { builtInErrorCodes } from '../../../utils/constants';
|
|
11
|
+
import { createMessageContext } from '../../../utils/createMessageContext';
|
|
12
|
+
import { resolveContextAwareMessage } from '../../../utils/messageUtils';
|
|
13
|
+
|
|
14
|
+
// Type for tracking error groups
|
|
15
|
+
export type ErrorGroup = {
|
|
16
|
+
count: number;
|
|
17
|
+
files: File[];
|
|
18
|
+
message: ContextAwareMessage<DynamicMessageContext>;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Creates helper functions for processing file rejections and formatting error messages
|
|
23
|
+
* @param validation Validation context containing message formatters and validation rules
|
|
24
|
+
* @returns Object with helper functions for processing file rejections
|
|
25
|
+
*/
|
|
26
|
+
export const createRejectionHelpers = (validation: UploadValidationContextType) => {
|
|
27
|
+
const { accept, formattedMaxSize, getValidationMessage, maxFiles, maxSize, strictValidation, validateFileCount } =
|
|
28
|
+
validation;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Ensures an error group exists for the given code, creating one if necessary
|
|
32
|
+
*
|
|
33
|
+
* @param errorGroups - Record of existing error groups indexed by error code
|
|
34
|
+
* @param code - The error code to get or create a group for
|
|
35
|
+
* @param message - Optional error message to use when creating a new group
|
|
36
|
+
* @returns The existing or newly created error group for the specified code
|
|
37
|
+
* @remarks
|
|
38
|
+
* - Error groups track files that failed with the same error code
|
|
39
|
+
* - Each group maintains a count of files, file references, and a shared message
|
|
40
|
+
* - New groups are initialized with empty arrays and zero counts
|
|
41
|
+
*/
|
|
42
|
+
const getOrCreateErrorGroup = (
|
|
43
|
+
errorGroups: Record<string, ErrorGroup>,
|
|
44
|
+
code: string,
|
|
45
|
+
message?: ContextAwareMessage<DynamicMessageContext>
|
|
46
|
+
): ErrorGroup => {
|
|
47
|
+
if (!(code in errorGroups)) {
|
|
48
|
+
errorGroups[code] = {
|
|
49
|
+
count: 0,
|
|
50
|
+
files: [],
|
|
51
|
+
message: message ?? '',
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return errorGroups[code];
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
/**
|
|
59
|
+
* Formats a human-readable error message for display based on error code and grouped files
|
|
60
|
+
*
|
|
61
|
+
* This function handles two types of validation errors:
|
|
62
|
+
*
|
|
63
|
+
* 1. System errors (built-in): For standard error codes like 'file-too-large' or 'too-many-files',
|
|
64
|
+
* it uses the built-in message system with appropriate pluralization and formatting.
|
|
65
|
+
*
|
|
66
|
+
* 2. Custom validator errors: For custom error codes from user-defined validators,
|
|
67
|
+
* it enriches the message with context about the rejected files (count, names, etc.).
|
|
68
|
+
*
|
|
69
|
+
* Used in two key scenarios:
|
|
70
|
+
* - Creating consolidated error messages for the UI (one message per error type)
|
|
71
|
+
* - Formatting individual file rejection messages for callbacks
|
|
72
|
+
*
|
|
73
|
+
* @param code - The error code identifying the validation failure
|
|
74
|
+
* @param error - The error object containing the message (string or function)
|
|
75
|
+
* @param errorGroups - Record of grouped errors with counts and file references
|
|
76
|
+
* @returns A formatted, human-readable error message ready for display
|
|
77
|
+
*/
|
|
78
|
+
getFormattedErrorGroupMessage: (
|
|
79
|
+
code: string,
|
|
80
|
+
error: ValidationError,
|
|
81
|
+
errorGroups: Record<string, ErrorGroup>
|
|
82
|
+
) => {
|
|
83
|
+
const isSystemError = builtInErrorCodes.includes(code);
|
|
84
|
+
const errorGroup = errorGroups[code];
|
|
85
|
+
|
|
86
|
+
// For system errors, use getValidationMessage directly
|
|
87
|
+
if (isSystemError) {
|
|
88
|
+
return getValidationMessage({
|
|
89
|
+
code,
|
|
90
|
+
count: errorGroup.count,
|
|
91
|
+
messageType: 'drop',
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// For custom errors, we need to provide context about the rejected files
|
|
96
|
+
const messageContext = createMessageContext({
|
|
97
|
+
accept,
|
|
98
|
+
code,
|
|
99
|
+
count: errorGroup.count,
|
|
100
|
+
dropFiles: errorGroup.files,
|
|
101
|
+
formattedMaxSize,
|
|
102
|
+
maxFiles,
|
|
103
|
+
maxSize,
|
|
104
|
+
messageType: 'drop',
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Resolve the message function with proper context containing all grouped files
|
|
108
|
+
return resolveContextAwareMessage(error.message, messageContext);
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
getOrCreateErrorGroup,
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Handles file count limits and returns updated accepted/rejected files
|
|
115
|
+
*
|
|
116
|
+
* This function enforces the maxFiles constraint by calculating whether adding
|
|
117
|
+
* new files would exceed the configured limit.
|
|
118
|
+
*
|
|
119
|
+
* @param currentFiles - Existing files already uploaded or selected
|
|
120
|
+
* @param droppedAcceptedFiles - New files that passed initial type/size validation
|
|
121
|
+
* @param droppedRejectedFiles - New files that already failed validation for other reasons
|
|
122
|
+
* @returns Object containing the final accepted and rejected files after limit checks
|
|
123
|
+
* @remarks
|
|
124
|
+
* - Considers both existing files and newly dropped files when checking limits
|
|
125
|
+
* - Handles two validation modes:
|
|
126
|
+
* 1. Strict validation (strictValidation: true):
|
|
127
|
+
* If adding any files would exceed the limit, ALL files are rejected
|
|
128
|
+
* 2. Partial upload (strictValidation: false):
|
|
129
|
+
* Accepts files up to the remaining limit, rejecting only overflow files
|
|
130
|
+
* - Calculates remaining slots as (maxFiles - currentFiles.length)
|
|
131
|
+
* - When no maxFiles is defined, accepts all files (Infinity limit)
|
|
132
|
+
* - Adds appropriate error metadata to the rejected files for UI feedback
|
|
133
|
+
*/
|
|
134
|
+
handleFileCountLimits: (
|
|
135
|
+
currentFiles: FileResource[],
|
|
136
|
+
droppedAcceptedFiles: File[],
|
|
137
|
+
droppedRejectedFiles: FileRejection[]
|
|
138
|
+
) => {
|
|
139
|
+
let acceptedResult = droppedAcceptedFiles;
|
|
140
|
+
let rejectionsResult = [...droppedRejectedFiles];
|
|
141
|
+
|
|
142
|
+
// Check if the total number of files (including both accepted and rejected) would exceed the limit
|
|
143
|
+
// This ensures users see the maxFiles error even if some files are rejected for other reasons
|
|
144
|
+
const totalDroppedFiles = droppedAcceptedFiles.length + droppedRejectedFiles.length;
|
|
145
|
+
const wouldExceedLimit = !validateFileCount(currentFiles.length, totalDroppedFiles);
|
|
146
|
+
const remainingSlots = maxFiles ? maxFiles - currentFiles.length : Infinity;
|
|
147
|
+
|
|
148
|
+
if (wouldExceedLimit) {
|
|
149
|
+
// Calculate how many files exceed the limit, considering all dropped files
|
|
150
|
+
const overflowCount = currentFiles.length + totalDroppedFiles - (maxFiles ?? Infinity);
|
|
151
|
+
const errorCode = 'too-many-files';
|
|
152
|
+
const errorMessage = getValidationMessage({
|
|
153
|
+
code: errorCode,
|
|
154
|
+
count: overflowCount,
|
|
155
|
+
messageType: 'drop',
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
const maxFilesError: FileError = {
|
|
159
|
+
code: errorCode,
|
|
160
|
+
message: errorMessage,
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// Add the error to all files that exceed the limit
|
|
164
|
+
// Start with files that were already accepted (they passed other validations)
|
|
165
|
+
const fileCountRejections = acceptedResult.slice(remainingSlots).map((file) => ({
|
|
166
|
+
errors: [maxFilesError],
|
|
167
|
+
file,
|
|
168
|
+
}));
|
|
169
|
+
|
|
170
|
+
// Add these new rejections to the existing ones
|
|
171
|
+
rejectionsResult = [...rejectionsResult, ...fileCountRejections];
|
|
172
|
+
|
|
173
|
+
if (!strictValidation) {
|
|
174
|
+
// In partial upload mode, only accept files up to the max file limit
|
|
175
|
+
acceptedResult = acceptedResult.slice(0, remainingSlots);
|
|
176
|
+
} else {
|
|
177
|
+
// In strict mode, reject all files if the total count exceeds the limit
|
|
178
|
+
acceptedResult = [];
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return { allAcceptedFiles: acceptedResult, allRejections: rejectionsResult };
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Handles file size validation and returns updated accepted/rejected files
|
|
187
|
+
*
|
|
188
|
+
* This function checks if files exceed the maximum allowed size (maxSize)
|
|
189
|
+
* and updates accept/reject lists accordingly.
|
|
190
|
+
*
|
|
191
|
+
* @param acceptedFiles - Files that have passed previous validation steps
|
|
192
|
+
* @returns Object containing validated files and size-related rejections
|
|
193
|
+
* @remarks
|
|
194
|
+
* - Files exceeding maxSize are identified and grouped with a 'file-too-large' error
|
|
195
|
+
* - Handles two validation modes:
|
|
196
|
+
* 1. Strict validation (strictValidation: true):
|
|
197
|
+
* If ANY file exceeds the size limit, ALL files are rejected
|
|
198
|
+
* 2. Partial upload (strictValidation: false):
|
|
199
|
+
* Only oversized files are rejected, others proceed normally
|
|
200
|
+
* - When maxSize is undefined, all files pass size validation
|
|
201
|
+
* - Adds appropriate error metadata to rejected files for UI feedback
|
|
202
|
+
* - The returned object has separate lists for valid files and size rejections
|
|
203
|
+
*/
|
|
204
|
+
handleFileSizeValidation: (acceptedFiles: File[]) => {
|
|
205
|
+
let validFiles = [...acceptedFiles];
|
|
206
|
+
let sizeRejections: FileRejection[] = [];
|
|
207
|
+
|
|
208
|
+
// Check for oversized files
|
|
209
|
+
const oversizedFiles = acceptedFiles.filter((file) => maxSize && file.size > maxSize);
|
|
210
|
+
|
|
211
|
+
if (oversizedFiles.length > 0) {
|
|
212
|
+
const errorCode = 'file-too-large';
|
|
213
|
+
const errorMessage = getValidationMessage({
|
|
214
|
+
code: errorCode,
|
|
215
|
+
count: oversizedFiles.length,
|
|
216
|
+
messageType: 'drop',
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
const fileSizeError: FileError = {
|
|
220
|
+
code: errorCode,
|
|
221
|
+
message: errorMessage,
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
// Add to rejections
|
|
225
|
+
sizeRejections = oversizedFiles.map((file) => ({
|
|
226
|
+
errors: [fileSizeError],
|
|
227
|
+
file,
|
|
228
|
+
}));
|
|
229
|
+
|
|
230
|
+
if (!strictValidation) {
|
|
231
|
+
// In partial upload mode, filter out oversized files
|
|
232
|
+
validFiles = acceptedFiles.filter((file) => !maxSize || file.size <= maxSize);
|
|
233
|
+
} else {
|
|
234
|
+
// In strict mode, reject all files if any are oversized
|
|
235
|
+
validFiles = [];
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return { sizeRejections, validFiles };
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Processes file rejections and groups them by error code
|
|
244
|
+
*
|
|
245
|
+
* This function takes an array of file rejections and organizes them into
|
|
246
|
+
* error groups based on the error codes. Each group tracks a count of affected
|
|
247
|
+
* files and the file references.
|
|
248
|
+
*
|
|
249
|
+
* @param rejections - Array of file rejections to process
|
|
250
|
+
* @returns A record of error groups indexed by error code
|
|
251
|
+
* @remarks
|
|
252
|
+
* - Multiple files with the same error code are consolidated into a single group
|
|
253
|
+
* - A file can appear in multiple groups if it has multiple error codes
|
|
254
|
+
* - Each group tracks:
|
|
255
|
+
* - count: Number of files affected by this error
|
|
256
|
+
* - files: References to the affected files
|
|
257
|
+
* - message: The error message (shared across the group)
|
|
258
|
+
* - Used for generating consolidated error messages and UI summaries
|
|
259
|
+
*/
|
|
260
|
+
processRejections: (rejections: FileRejection[]): Record<string, ErrorGroup> => {
|
|
261
|
+
const groups: Record<string, ErrorGroup> = {};
|
|
262
|
+
rejections.forEach((rejection) => {
|
|
263
|
+
rejection.errors.forEach((error) => {
|
|
264
|
+
const group = getOrCreateErrorGroup(groups, error.code, error.message);
|
|
265
|
+
group.count++;
|
|
266
|
+
group.files.push(rejection.file);
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
return groups;
|
|
271
|
+
},
|
|
272
|
+
};
|
|
273
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import { UploadValidationContextType } from '../../../providers/UploadValidationProvider';
|
|
4
|
+
import { FileRejection, FileResource } from '../../../types/commonTypes';
|
|
5
|
+
import { createRejectionHelpers } from './createFileRejectionHelpers';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Hook that handles file validation and processing when files are dropped
|
|
9
|
+
* @param props Object containing:
|
|
10
|
+
* - files: Currently selected files in the uploader
|
|
11
|
+
* - onDrop: Optional callback triggered for both accepted and rejected files
|
|
12
|
+
* - onDropAccepted: Optional callback triggered only for accepted files
|
|
13
|
+
* - onDropRejected: Optional callback triggered only for rejected files
|
|
14
|
+
* - setFiles: Function to update the files state with newly accepted files
|
|
15
|
+
* - validation: Validation context (from either provider or local validation)
|
|
16
|
+
* @returns Callback function for handling file drop events from react-dropzone
|
|
17
|
+
* @remarks
|
|
18
|
+
* - Performs validation in a specific sequence: file types → file sizes → file count
|
|
19
|
+
* - Groups and formats error messages for consistent UI display
|
|
20
|
+
* - Handles strict vs. partial validation modes differently:
|
|
21
|
+
* - Strict: Rejects all files if any would be invalid
|
|
22
|
+
* - Partial: Accepts valid files while rejecting invalid ones
|
|
23
|
+
* - Updates file state only for valid files
|
|
24
|
+
* - Clears validation state on completely successful drops
|
|
25
|
+
* - Calls appropriate callbacks with processed files
|
|
26
|
+
* - Sets validation errors in the validation context for UI display
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
export type UseHandleDropProps = {
|
|
30
|
+
/** Current files in the upload area */
|
|
31
|
+
files: FileResource[];
|
|
32
|
+
/** Callback when files are dropped */
|
|
33
|
+
onDrop?: (acceptedFiles: File[], rejectedFiles: FileRejection[]) => void;
|
|
34
|
+
/** Callback when files are accepted */
|
|
35
|
+
onDropAccepted?: (acceptedFiles: File[]) => void;
|
|
36
|
+
/** Callback when files are rejected */
|
|
37
|
+
onDropRejected?: (rejectedFiles: FileRejection[]) => void;
|
|
38
|
+
/** Function to update the files state */
|
|
39
|
+
setFiles: (files: FileResource[]) => void;
|
|
40
|
+
/** Validation context */
|
|
41
|
+
validation: UploadValidationContextType;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const useHandleDrop = ({
|
|
45
|
+
files,
|
|
46
|
+
onDrop,
|
|
47
|
+
onDropAccepted,
|
|
48
|
+
onDropRejected,
|
|
49
|
+
setFiles,
|
|
50
|
+
validation,
|
|
51
|
+
}: UseHandleDropProps) => {
|
|
52
|
+
const { clearAllValidation, setDropValidationErrors, setFileRejections, strictValidation } = validation;
|
|
53
|
+
|
|
54
|
+
return useCallback(
|
|
55
|
+
(acceptedFiles: File[], rejectedFiles: FileRejection[]) => {
|
|
56
|
+
const {
|
|
57
|
+
getFormattedErrorGroupMessage,
|
|
58
|
+
handleFileCountLimits,
|
|
59
|
+
handleFileSizeValidation,
|
|
60
|
+
processRejections,
|
|
61
|
+
} = createRejectionHelpers(validation);
|
|
62
|
+
|
|
63
|
+
// Step 1: Validate file sizes
|
|
64
|
+
// Note: acceptedFiles have already passed type validation by react-dropzone
|
|
65
|
+
const { sizeRejections, validFiles } = handleFileSizeValidation(acceptedFiles);
|
|
66
|
+
|
|
67
|
+
// Filter out only File objects from current files for validation
|
|
68
|
+
// This is needed because FileResource can include RemoteFile objects
|
|
69
|
+
const currentFileObjects = files.filter((file): file is File => file instanceof File);
|
|
70
|
+
|
|
71
|
+
// Step 2: Handle file count limits with all validated files
|
|
72
|
+
// This combines all rejections from previous validation steps, including custom validator errors
|
|
73
|
+
const { allAcceptedFiles, allRejections } = handleFileCountLimits(currentFileObjects, validFiles, [
|
|
74
|
+
...rejectedFiles, // Already includes custom validation errors
|
|
75
|
+
...sizeRejections,
|
|
76
|
+
]);
|
|
77
|
+
|
|
78
|
+
// Step 3: Process all rejections and group by error code
|
|
79
|
+
// This creates a dictionary of error groups for better UI presentation
|
|
80
|
+
// Message functions are preserved at this stage for proper grouping
|
|
81
|
+
const errorGroups = processRejections(allRejections);
|
|
82
|
+
|
|
83
|
+
// Step 4: Extract errors for UI display, now resolving messages with proper context
|
|
84
|
+
// We need one error message per error type for the UI
|
|
85
|
+
const errors = Object.entries(errorGroups).map(([code]) => ({
|
|
86
|
+
code,
|
|
87
|
+
message: getFormattedErrorGroupMessage(code, { code, message: errorGroups[code].message }, errorGroups),
|
|
88
|
+
}));
|
|
89
|
+
|
|
90
|
+
// Step 5: Format rejections for callbacks - maintain file-to-errors relationship
|
|
91
|
+
// These preserve the connection between each file and its specific rejection reasons
|
|
92
|
+
const processedRejections = allRejections.map((rejection) => ({
|
|
93
|
+
errors: rejection.errors.map((error) => ({
|
|
94
|
+
code: error.code,
|
|
95
|
+
message: getFormattedErrorGroupMessage(error.code, error, errorGroups),
|
|
96
|
+
})),
|
|
97
|
+
file: rejection.file,
|
|
98
|
+
}));
|
|
99
|
+
|
|
100
|
+
const hasRejections = processedRejections.length > 0;
|
|
101
|
+
|
|
102
|
+
// Step 6: Handle strict validation - reject all files if there are any rejections
|
|
103
|
+
if (strictValidation && hasRejections) {
|
|
104
|
+
// In strict mode, even valid files are rejected if any file has issues
|
|
105
|
+
const strictRejections = [
|
|
106
|
+
...processedRejections,
|
|
107
|
+
...allAcceptedFiles.map((file) => ({
|
|
108
|
+
errors,
|
|
109
|
+
file,
|
|
110
|
+
})),
|
|
111
|
+
];
|
|
112
|
+
|
|
113
|
+
setFileRejections(strictRejections);
|
|
114
|
+
setDropValidationErrors(errors);
|
|
115
|
+
onDropRejected?.(strictRejections);
|
|
116
|
+
onDrop?.([], strictRejections);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Step 7: Handle partial upload mode (OR no rejections)
|
|
121
|
+
setFileRejections(processedRejections);
|
|
122
|
+
setDropValidationErrors(errors);
|
|
123
|
+
onDropRejected?.(processedRejections);
|
|
124
|
+
|
|
125
|
+
// Step 8: Handle successful file uploads
|
|
126
|
+
if (allAcceptedFiles.length > 0) {
|
|
127
|
+
if (!hasRejections) {
|
|
128
|
+
// Clear validation only if there are no rejections
|
|
129
|
+
clearAllValidation();
|
|
130
|
+
}
|
|
131
|
+
// Update file state with new files (as FileResource[])
|
|
132
|
+
const newFileResources: FileResource[] = [...files, ...allAcceptedFiles];
|
|
133
|
+
setFiles(newFileResources);
|
|
134
|
+
onDropAccepted?.(allAcceptedFiles);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Always call onDrop with both sets of files
|
|
138
|
+
onDrop?.(allAcceptedFiles, processedRejections);
|
|
139
|
+
},
|
|
140
|
+
[
|
|
141
|
+
files,
|
|
142
|
+
clearAllValidation,
|
|
143
|
+
setDropValidationErrors,
|
|
144
|
+
setFiles,
|
|
145
|
+
onDrop,
|
|
146
|
+
onDropAccepted,
|
|
147
|
+
onDropRejected,
|
|
148
|
+
setFileRejections,
|
|
149
|
+
strictValidation,
|
|
150
|
+
validation,
|
|
151
|
+
]
|
|
152
|
+
);
|
|
153
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { FileResource } from '../../../types/commonTypes';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hook that determines if file uploads are currently available/disabled
|
|
5
|
+
* @param props Object containing:
|
|
6
|
+
* - disabled: Optional flag to manually disable uploads
|
|
7
|
+
* - files: Currently selected files
|
|
8
|
+
* - maxFiles: Optional maximum number of files allowed
|
|
9
|
+
* @returns Object containing:
|
|
10
|
+
* - hasReachedFileLimit: Whether max file count has been reached
|
|
11
|
+
* - isDisabled: Whether uploads are currently disabled
|
|
12
|
+
* @remarks
|
|
13
|
+
* - Combines both manual disable state and file limit restrictions
|
|
14
|
+
* - Used to prevent uploads when either condition is met
|
|
15
|
+
*/
|
|
16
|
+
export type UploadAvailabilityParams = {
|
|
17
|
+
/** Whether the upload is disabled */
|
|
18
|
+
disabled?: boolean;
|
|
19
|
+
/** Current files in the upload area */
|
|
20
|
+
files: FileResource[];
|
|
21
|
+
/** Maximum number of files allowed */
|
|
22
|
+
maxFiles?: number;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
type UploadAvailability = {
|
|
26
|
+
hasReachedFileLimit: boolean;
|
|
27
|
+
isDisabled: boolean;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const useUploadAvailability = ({
|
|
31
|
+
disabled = false,
|
|
32
|
+
files,
|
|
33
|
+
maxFiles,
|
|
34
|
+
}: UploadAvailabilityParams): UploadAvailability => {
|
|
35
|
+
// Calculate if we've reached the file limit
|
|
36
|
+
const hasReachedFileLimit = maxFiles !== undefined && files.length >= maxFiles;
|
|
37
|
+
// Consider both local and provider disabled states
|
|
38
|
+
const isDisabled = disabled || hasReachedFileLimit;
|
|
39
|
+
|
|
40
|
+
return {
|
|
41
|
+
hasReachedFileLimit,
|
|
42
|
+
isDisabled,
|
|
43
|
+
};
|
|
44
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { UploadValidationContextType } from '../../providers/UploadValidationProvider';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates an optimized validator function for React-Dropzone that preserves
|
|
5
|
+
* function-based validation messages for later resolution
|
|
6
|
+
*
|
|
7
|
+
* @param validationContext - The validation context containing the custom validator
|
|
8
|
+
* @returns A validator function compatible with React-Dropzone
|
|
9
|
+
*/
|
|
10
|
+
export const createDropzoneValidator = (validationContext: UploadValidationContextType) => {
|
|
11
|
+
// Extract the custom validator function
|
|
12
|
+
const { validateCustomRules } = validationContext;
|
|
13
|
+
|
|
14
|
+
// Return undefined if no custom validator exists
|
|
15
|
+
if (typeof validateCustomRules !== 'function') {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Return the actual validator function
|
|
20
|
+
return (file: File) => {
|
|
21
|
+
// Run the custom validator
|
|
22
|
+
const validationResult = validateCustomRules(file);
|
|
23
|
+
|
|
24
|
+
// If no errors, return null (valid)
|
|
25
|
+
if (!validationResult) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// If no errors in array, return null
|
|
30
|
+
if (validationResult.length === 0) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Return errors with message functions preserved
|
|
35
|
+
// This allows for proper error grouping before message resolution
|
|
36
|
+
return validationResult.map((error) => ({
|
|
37
|
+
code: error.code,
|
|
38
|
+
message: error.message,
|
|
39
|
+
}));
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
import { UploadValidationContext, UploadValidationContextType } from '../../providers/UploadValidationProvider';
|
|
4
|
+
import { ValidationConfig } from '../../types/commonTypes';
|
|
5
|
+
import { useFileValidationLogic } from './useFileValidationLogic';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Hook that provides file validation functionality by either using a shared validation context
|
|
9
|
+
* or falling back to local validation logic
|
|
10
|
+
* @param config - Optional validation configuration for file constraints (size, type, etc.)
|
|
11
|
+
* @returns Validation context containing validation state and useful validation methods
|
|
12
|
+
* @remarks
|
|
13
|
+
* - If used within an UploadValidationProvider, returns the shared validation context
|
|
14
|
+
* - Otherwise, creates a local validation context using useFileValidationLogic
|
|
15
|
+
* - This allows components to work with or without a shared validation context
|
|
16
|
+
*/
|
|
17
|
+
export const useFileValidation = (config?: ValidationConfig): UploadValidationContextType => {
|
|
18
|
+
const validationContext = useContext<UploadValidationContextType | undefined>(UploadValidationContext);
|
|
19
|
+
|
|
20
|
+
// Create local validation logic
|
|
21
|
+
const localValidation = useFileValidationLogic(config);
|
|
22
|
+
|
|
23
|
+
// Return the context if it exists, otherwise use local validation
|
|
24
|
+
return validationContext ?? localValidation;
|
|
25
|
+
};
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import { ValidationConfig } from '../../types/commonTypes';
|
|
4
|
+
import { useValidationMessages } from './useValidationMessages';
|
|
5
|
+
import { useValidationState } from './useValidationState';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Hook that implements core file validation logic and state management
|
|
9
|
+
*
|
|
10
|
+
* This hook serves as the foundation for file validation throughout the upload system.
|
|
11
|
+
* It combines validation state management with validation logic functions, allowing
|
|
12
|
+
* for comprehensive file validation with customizable rules.
|
|
13
|
+
*
|
|
14
|
+
* @param config - Optional validation configuration object containing:
|
|
15
|
+
* - accept: Optional array of accepted file types or preset categories
|
|
16
|
+
* - error: Custom error object to override default validation errors
|
|
17
|
+
* - maxFiles: Maximum number of files allowed (1 for single file upload)
|
|
18
|
+
* - maxSize: Maximum file size in bytes
|
|
19
|
+
* - strictValidation: When true, all files are rejected if any fail validation
|
|
20
|
+
* - validator: Custom validation function for additional rules
|
|
21
|
+
*
|
|
22
|
+
* @returns An object containing:
|
|
23
|
+
* - Validation state (dragValidationError, dropValidationErrors)
|
|
24
|
+
* - State management methods (clearDragValidation, clearDropValidation, etc.)
|
|
25
|
+
* - formattedMaxSize: Human-readable size limit (e.g., "5 MB")
|
|
26
|
+
* - getValidationMessage: Function to generate context-aware error messages
|
|
27
|
+
* - Validation methods:
|
|
28
|
+
* - validateFileType: Checks if a file type is allowed
|
|
29
|
+
* - validateFileSize: Checks if a file is within size limits
|
|
30
|
+
* - validateFileCount: Checks if adding files would exceed limit
|
|
31
|
+
* - validateCustomRules: Applies custom validation function if provided
|
|
32
|
+
*/
|
|
33
|
+
export const useFileValidationLogic = (config?: ValidationConfig) => {
|
|
34
|
+
const { accept, error, maxFiles, maxSize, strictValidation, validator } = config ?? {};
|
|
35
|
+
|
|
36
|
+
// Get message formatting and validation message utilities
|
|
37
|
+
const { formattedMaxSize, getValidationMessage } = useValidationMessages({
|
|
38
|
+
...config,
|
|
39
|
+
accept,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Initialize validation state, optionally with custom error
|
|
43
|
+
const validationState = useValidationState(error, getValidationMessage);
|
|
44
|
+
|
|
45
|
+
// Validation methods
|
|
46
|
+
// Check if a file type is allowed given mimeTypes mapping
|
|
47
|
+
const validateFileType = useCallback((fileType: string, mimeTypes?: Record<string, string[]>) => {
|
|
48
|
+
if (!mimeTypes) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
return Object.keys(mimeTypes).includes(fileType);
|
|
52
|
+
}, []);
|
|
53
|
+
|
|
54
|
+
// Check if file size is within configured limit
|
|
55
|
+
const validateFileSize = useCallback(
|
|
56
|
+
(fileSize: number) => {
|
|
57
|
+
if (!maxSize) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return fileSize <= maxSize;
|
|
61
|
+
},
|
|
62
|
+
[maxSize]
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// Check if adding files would exceed maximum count
|
|
66
|
+
const validateFileCount = useCallback(
|
|
67
|
+
(currentCount: number, newCount: number) => {
|
|
68
|
+
if (!maxFiles) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
return currentCount + newCount <= maxFiles;
|
|
72
|
+
},
|
|
73
|
+
[maxFiles]
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// Run custom validator function if provided
|
|
77
|
+
const validateCustomRules = useCallback(
|
|
78
|
+
(file: File | DataTransferItem) => {
|
|
79
|
+
if (!validator) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
const validationResult = validator(file);
|
|
83
|
+
|
|
84
|
+
// If validation result is null or empty array, return null
|
|
85
|
+
if (!validationResult || validationResult.length === 0) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Return the array of errors
|
|
90
|
+
return validationResult;
|
|
91
|
+
},
|
|
92
|
+
[validator]
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
...validationState,
|
|
97
|
+
formattedMaxSize,
|
|
98
|
+
getValidationMessage,
|
|
99
|
+
maxFiles,
|
|
100
|
+
maxSize,
|
|
101
|
+
strictValidation,
|
|
102
|
+
validateCustomRules,
|
|
103
|
+
validateFileCount,
|
|
104
|
+
validateFileSize,
|
|
105
|
+
validateFileType,
|
|
106
|
+
};
|
|
107
|
+
};
|