@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,259 @@
|
|
|
1
|
+
import { cn } from '@evolve.ui/theme-system';
|
|
2
|
+
import { ChangeEvent } from 'react';
|
|
3
|
+
|
|
4
|
+
import { Checkbox } from '../../../ChoiceListItem';
|
|
5
|
+
import { IconButton } from '../../../IconButton/IconButton';
|
|
6
|
+
import { DotsSixVertical, Paperclip, Trash } from '../../../Icons';
|
|
7
|
+
import { ProgressCircle } from '../../../ProgressCircle/ProgressCircle';
|
|
8
|
+
import { BodyPrimary, BodySecondary } from '../../../Typography/Text/Text';
|
|
9
|
+
import { formatFileSize } from '../../../utils/formatFileSize';
|
|
10
|
+
import { useImageFilePreviewUrl } from '../../hooks/filePreview/useImageFilePreviewUrl';
|
|
11
|
+
import { BaseFileCardProps, ListFileCardStyle } from '../types';
|
|
12
|
+
|
|
13
|
+
export type ListFileCardProps = BaseFileCardProps & {
|
|
14
|
+
cardStyle?: ListFileCardStyle;
|
|
15
|
+
'data-testid'?: string;
|
|
16
|
+
showActionsOnHover?: boolean;
|
|
17
|
+
statusText?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const ListFileCard = ({
|
|
21
|
+
actions,
|
|
22
|
+
cardStyle,
|
|
23
|
+
className,
|
|
24
|
+
'data-testid': dataTestId = 'list-file-card',
|
|
25
|
+
draggable,
|
|
26
|
+
errorMessage,
|
|
27
|
+
fileName,
|
|
28
|
+
hideFileName = false,
|
|
29
|
+
hideFileSize = false,
|
|
30
|
+
hideFileStatus = false,
|
|
31
|
+
imageSource,
|
|
32
|
+
isSelected,
|
|
33
|
+
onDelete,
|
|
34
|
+
onImageError,
|
|
35
|
+
onSelect,
|
|
36
|
+
progress,
|
|
37
|
+
selectable,
|
|
38
|
+
showActionsOnHover,
|
|
39
|
+
status = 'default',
|
|
40
|
+
statusIcon,
|
|
41
|
+
statusText,
|
|
42
|
+
}: ListFileCardProps) => {
|
|
43
|
+
const previewUrl = useImageFilePreviewUrl(imageSource);
|
|
44
|
+
|
|
45
|
+
const isRemoteFile = 'url' in imageSource;
|
|
46
|
+
const fileSize = isRemoteFile ? '' : formatFileSize(imageSource.size);
|
|
47
|
+
|
|
48
|
+
// Automatically hide file size for URLs, respect the prop for Files
|
|
49
|
+
const shouldHideFileSize = hideFileSize || isRemoteFile;
|
|
50
|
+
|
|
51
|
+
const defaultFileName = isRemoteFile ? (imageSource.url.split('/').pop() ?? 'image') : imageSource.name;
|
|
52
|
+
const fileDisplayName = fileName ?? defaultFileName;
|
|
53
|
+
|
|
54
|
+
// Status checks
|
|
55
|
+
const isError = status === 'error';
|
|
56
|
+
const isPending = status === 'pending';
|
|
57
|
+
const isProgressing = status === 'progressing';
|
|
58
|
+
const isComplete = status === 'complete';
|
|
59
|
+
const isDragging = false; // ListFileCard doesn't currently support sortable YET, but adding for consistency with GridFileCard
|
|
60
|
+
|
|
61
|
+
// Determine when to auto-render ProgressCircle
|
|
62
|
+
// Only when statusIcon is not provided AND status is pending/progressing/complete
|
|
63
|
+
const shouldShowProgressCircle = !statusIcon && (isPending || isProgressing || isComplete);
|
|
64
|
+
|
|
65
|
+
// Determine what to show below the file name (priority: error > progressing > size)
|
|
66
|
+
let fileStatusText = null;
|
|
67
|
+
|
|
68
|
+
if (isError && errorMessage && !hideFileStatus) {
|
|
69
|
+
fileStatusText = <BodySecondary className="text-text-critical">{errorMessage}</BodySecondary>;
|
|
70
|
+
} else if ((isProgressing || isPending) && !hideFileStatus) {
|
|
71
|
+
// Use custom statusText if provided, otherwise use default
|
|
72
|
+
const defaultStatusText = isPending ? 'Pending' : 'Uploading';
|
|
73
|
+
const displayStatusText = statusText ?? defaultStatusText;
|
|
74
|
+
fileStatusText = <BodySecondary color="secondary">{displayStatusText}</BodySecondary>;
|
|
75
|
+
} else if (!shouldHideFileSize) {
|
|
76
|
+
fileStatusText = <BodySecondary color={isError ? 'critical' : 'secondary'}>{fileSize}</BodySecondary>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const actionBtnClasses = showActionsOnHover
|
|
80
|
+
? cn(
|
|
81
|
+
'opacity-0 group-focus-within/list-file-card:opacity-100 group-hover/list-file-card:opacity-100',
|
|
82
|
+
'focus:opacity-100',
|
|
83
|
+
'transition-opacity duration-200'
|
|
84
|
+
)
|
|
85
|
+
: '';
|
|
86
|
+
|
|
87
|
+
const isProcessing = isPending || isProgressing;
|
|
88
|
+
|
|
89
|
+
// Map status to ProgressCircle-compatible status (only needed when shouldShowProgressCircle is true)
|
|
90
|
+
let progressCircleStatus: 'pending' | 'progressing' | 'complete';
|
|
91
|
+
if (isPending) {
|
|
92
|
+
progressCircleStatus = 'pending';
|
|
93
|
+
} else if (isProgressing) {
|
|
94
|
+
progressCircleStatus = 'progressing';
|
|
95
|
+
} else {
|
|
96
|
+
progressCircleStatus = 'complete';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<div
|
|
101
|
+
aria-busy={isProcessing || undefined}
|
|
102
|
+
className={cn(
|
|
103
|
+
'group/list-file-card flex w-full min-w-0 cursor-pointer items-center justify-between p-xs',
|
|
104
|
+
'transition-all duration-200',
|
|
105
|
+
{
|
|
106
|
+
// Error state
|
|
107
|
+
'bg-background-critical-light': isError && !isDragging,
|
|
108
|
+
// Default state
|
|
109
|
+
'bg-background-primary': !isError && !isDragging,
|
|
110
|
+
// Drag state
|
|
111
|
+
'z-50 scale-105 border-border-selected bg-background-secondary shadow-01': isDragging,
|
|
112
|
+
},
|
|
113
|
+
// List View (BorderContained) vs Table View (Single Border)
|
|
114
|
+
cardStyle === 'contained'
|
|
115
|
+
? cn('rounded-container border', {
|
|
116
|
+
// Error state
|
|
117
|
+
'border-border-critical hover:border-border-critical hover:bg-background-critical-light':
|
|
118
|
+
isError && !isDragging,
|
|
119
|
+
// Default state
|
|
120
|
+
'border-border-secondary hover:border-border-secondary hover:bg-background-hover':
|
|
121
|
+
!isError && !isDragging,
|
|
122
|
+
})
|
|
123
|
+
: cn('rounded-b-none border-b', {
|
|
124
|
+
// Error state
|
|
125
|
+
'border-b-border-critical focus-within:border-b-border-critical hover:bg-background-critical-light':
|
|
126
|
+
isError && !isDragging,
|
|
127
|
+
// Default state
|
|
128
|
+
'border-b-border-secondary hover:bg-background-hover': !isError && !isDragging,
|
|
129
|
+
}),
|
|
130
|
+
className
|
|
131
|
+
)}
|
|
132
|
+
data-testid={dataTestId}
|
|
133
|
+
>
|
|
134
|
+
<div className="flex min-w-0 flex-1 items-center gap-xs">
|
|
135
|
+
<div className="flex items-center gap-[4px]">
|
|
136
|
+
{/* Show either Checkbox or DragHandle, not both */}
|
|
137
|
+
{selectable ? (
|
|
138
|
+
<Checkbox.Option
|
|
139
|
+
checked={isSelected}
|
|
140
|
+
className="![grid-template-columns:24px_0px_1fr]"
|
|
141
|
+
data-testid="list-file-card-select-checkbox"
|
|
142
|
+
onChange={(e: ChangeEvent<HTMLInputElement>) => {
|
|
143
|
+
e.stopPropagation();
|
|
144
|
+
onSelect?.(imageSource, e.target.checked);
|
|
145
|
+
}}
|
|
146
|
+
/>
|
|
147
|
+
) : draggable ? (
|
|
148
|
+
<DotsSixVertical
|
|
149
|
+
color="primary"
|
|
150
|
+
size="sm"
|
|
151
|
+
style="bold"
|
|
152
|
+
/>
|
|
153
|
+
) : null}
|
|
154
|
+
{previewUrl ? (
|
|
155
|
+
<div className="relative h-xl w-xl items-center justify-center overflow-hidden rounded-container bg-background-subdued">
|
|
156
|
+
<img
|
|
157
|
+
alt={fileDisplayName}
|
|
158
|
+
className="absolute inset-0 h-full w-full object-cover"
|
|
159
|
+
onError={() => {
|
|
160
|
+
onImageError?.(imageSource);
|
|
161
|
+
}}
|
|
162
|
+
src={previewUrl}
|
|
163
|
+
/>
|
|
164
|
+
</div>
|
|
165
|
+
) : (
|
|
166
|
+
<div className="flex aspect-square min-w-xl items-center justify-center rounded-container bg-background-subdued">
|
|
167
|
+
<Paperclip
|
|
168
|
+
color="primary"
|
|
169
|
+
size="sm"
|
|
170
|
+
/>
|
|
171
|
+
</div>
|
|
172
|
+
)}
|
|
173
|
+
</div>
|
|
174
|
+
<div className="flex min-w-0 flex-1 flex-col gap-[2px]">
|
|
175
|
+
{!hideFileName && (
|
|
176
|
+
<BodyPrimary
|
|
177
|
+
className="truncate"
|
|
178
|
+
color={isError ? 'critical' : 'primary'}
|
|
179
|
+
>
|
|
180
|
+
{fileDisplayName}
|
|
181
|
+
</BodyPrimary>
|
|
182
|
+
)}
|
|
183
|
+
{fileStatusText}
|
|
184
|
+
</div>
|
|
185
|
+
</div>
|
|
186
|
+
{/* Actions */}
|
|
187
|
+
<div className="flex items-center gap-[4px]">
|
|
188
|
+
{actions?.map((action, index) => (
|
|
189
|
+
<IconButton
|
|
190
|
+
aria-label={action.name}
|
|
191
|
+
className={actionBtnClasses}
|
|
192
|
+
disabled={isProcessing}
|
|
193
|
+
icon={action.icon}
|
|
194
|
+
key={`${action.name}-${index}`}
|
|
195
|
+
onClick={(e) => {
|
|
196
|
+
e.stopPropagation();
|
|
197
|
+
action.onClick(e, imageSource);
|
|
198
|
+
}}
|
|
199
|
+
size="sm"
|
|
200
|
+
type="button"
|
|
201
|
+
/>
|
|
202
|
+
))}
|
|
203
|
+
{onDelete && (
|
|
204
|
+
<IconButton
|
|
205
|
+
aria-label="Remove file"
|
|
206
|
+
className={actionBtnClasses}
|
|
207
|
+
data-testid="remove-file-button"
|
|
208
|
+
disabled={isProcessing}
|
|
209
|
+
icon={Trash}
|
|
210
|
+
onClick={() => onDelete(imageSource)}
|
|
211
|
+
size="sm"
|
|
212
|
+
type="button"
|
|
213
|
+
/>
|
|
214
|
+
)}
|
|
215
|
+
{shouldShowProgressCircle ? (
|
|
216
|
+
<div
|
|
217
|
+
className="flex items-center"
|
|
218
|
+
data-testid="list-file-card-progress-circle"
|
|
219
|
+
>
|
|
220
|
+
<ProgressCircle
|
|
221
|
+
progress={progress}
|
|
222
|
+
size="sm"
|
|
223
|
+
status={progressCircleStatus}
|
|
224
|
+
/>
|
|
225
|
+
</div>
|
|
226
|
+
) : statusIcon ? (
|
|
227
|
+
statusIcon.type === 'progressCircle' ? (
|
|
228
|
+
<div
|
|
229
|
+
className="flex items-center"
|
|
230
|
+
data-testid="list-file-card-progress-circle"
|
|
231
|
+
>
|
|
232
|
+
<ProgressCircle
|
|
233
|
+
centerIcon={statusIcon.centerIcon}
|
|
234
|
+
color={statusIcon.color}
|
|
235
|
+
indeterminateAnimation={statusIcon.indeterminateAnimation}
|
|
236
|
+
progress={progress}
|
|
237
|
+
size="sm"
|
|
238
|
+
status={progressCircleStatus}
|
|
239
|
+
/>
|
|
240
|
+
</div>
|
|
241
|
+
) : (
|
|
242
|
+
<div
|
|
243
|
+
className="flex items-center"
|
|
244
|
+
data-testid="list-file-card-status-icon"
|
|
245
|
+
>
|
|
246
|
+
<statusIcon.icon
|
|
247
|
+
color={statusIcon.color}
|
|
248
|
+
size="md"
|
|
249
|
+
style={statusIcon.style}
|
|
250
|
+
/>
|
|
251
|
+
</div>
|
|
252
|
+
)
|
|
253
|
+
) : null}
|
|
254
|
+
</div>
|
|
255
|
+
</div>
|
|
256
|
+
);
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
ListFileCard.displayName = 'ListFileCard';
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
//should table be called 'page' or 'row'?
|
|
2
|
+
|
|
3
|
+
import { DraggableAttributes } from '@dnd-kit/core';
|
|
4
|
+
import { SyntheticListenerMap } from '@dnd-kit/core/dist/hooks/utilities';
|
|
5
|
+
import { ComponentProps, CSSProperties } from 'react';
|
|
6
|
+
|
|
7
|
+
import { AnyIcon } from '../../Icons/anyIcon';
|
|
8
|
+
import { IconProps } from '../../Icons/IconBase';
|
|
9
|
+
import { LoadingSpinner } from '../../LoadingSpinner/LoadingSpinner';
|
|
10
|
+
import { ProgressCircle } from '../../ProgressCircle/ProgressCircle';
|
|
11
|
+
import { FileResource } from '../types';
|
|
12
|
+
|
|
13
|
+
export type FileCardAction = {
|
|
14
|
+
icon: AnyIcon;
|
|
15
|
+
iconStyle?: IconProps['style'];
|
|
16
|
+
name: string;
|
|
17
|
+
onClick: (e: React.MouseEvent<HTMLElement>, fileResource: FileResource) => void;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type FileStatusIconConfig = {
|
|
21
|
+
color?: IconProps['color'];
|
|
22
|
+
icon: AnyIcon | typeof LoadingSpinner;
|
|
23
|
+
style?: IconProps['style'];
|
|
24
|
+
type: 'icon';
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type FileProgressCircleConfig = {
|
|
28
|
+
centerIcon?: ComponentProps<typeof ProgressCircle>['centerIcon'];
|
|
29
|
+
color?: ComponentProps<typeof ProgressCircle>['color'];
|
|
30
|
+
indeterminateAnimation?: ComponentProps<typeof ProgressCircle>['indeterminateAnimation'];
|
|
31
|
+
type: 'progressCircle';
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type FileStatusIcon = FileStatusIconConfig | FileProgressCircleConfig;
|
|
35
|
+
|
|
36
|
+
export type FileStatusConfig = {
|
|
37
|
+
errorMessage?: string;
|
|
38
|
+
progress?: number;
|
|
39
|
+
status?: 'default' | 'pending' | 'progressing' | 'complete' | 'error';
|
|
40
|
+
statusIcon?: FileStatusIcon;
|
|
41
|
+
statusText?: string;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type PreviewStyle = 'list' | 'compactList' | 'grid';
|
|
45
|
+
export type BaseFileCardStyle = 'contained' | 'compact' | 'card';
|
|
46
|
+
export type ListFileCardStyle = 'contained' | 'compact';
|
|
47
|
+
|
|
48
|
+
export type BaseFileCardProps = {
|
|
49
|
+
/**
|
|
50
|
+
* GridCard Only: First 3 actions will be visible buttons,
|
|
51
|
+
* remaining will appear in overflow menu.
|
|
52
|
+
*/
|
|
53
|
+
actions?: FileCardAction[];
|
|
54
|
+
className?: string;
|
|
55
|
+
draggable?: boolean;
|
|
56
|
+
errorMessage?: string;
|
|
57
|
+
fileName?: string;
|
|
58
|
+
hideFileName?: boolean;
|
|
59
|
+
hideFileSize?: boolean;
|
|
60
|
+
hideFileStatus?: boolean;
|
|
61
|
+
imageSource: FileResource;
|
|
62
|
+
isSelected?: boolean;
|
|
63
|
+
onDelete?: (fileResource: FileResource) => void;
|
|
64
|
+
onImageError?: (fileResource: FileResource) => void;
|
|
65
|
+
onSelect?: (fileResource: FileResource, isSelected: boolean) => void;
|
|
66
|
+
/** Progress percentage (0-100) for the file upload/processing */
|
|
67
|
+
progress?: number;
|
|
68
|
+
selectable?: boolean;
|
|
69
|
+
sortable?: {
|
|
70
|
+
attributes?: DraggableAttributes;
|
|
71
|
+
isDragging?: boolean;
|
|
72
|
+
listeners?: SyntheticListenerMap;
|
|
73
|
+
setNodeRef: (node: HTMLElement | null) => void;
|
|
74
|
+
styles?: CSSProperties;
|
|
75
|
+
};
|
|
76
|
+
status?: 'default' | 'pending' | 'progressing' | 'complete' | 'error';
|
|
77
|
+
statusIcon?: FileStatusIcon;
|
|
78
|
+
} & ({ isSelected: boolean; selectable: true } | { isSelected?: boolean; selectable?: false });
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { FileResource } from '../../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Hook to manage file preview URLs with proper cleanup
|
|
7
|
+
* @param file - File to preview
|
|
8
|
+
* @returns Preview URL for image files, undefined for non-image files
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// --> Cleans up any existing URL before creating a new one
|
|
12
|
+
// --> Handles cleanup when the file prop changes
|
|
13
|
+
// --> Is more memory-efficient since it immediately revokes unused URLs
|
|
14
|
+
// --> URLs are created only when needed (in the view)
|
|
15
|
+
// --> Cleanup is tied directly to component lifecycle - handles cleanup on unmount
|
|
16
|
+
// --> URLs are managed closer to where they're actually used
|
|
17
|
+
// --> It's more efficient since previews are only created for visible components
|
|
18
|
+
|
|
19
|
+
export const useImageFilePreviewUrl = (file?: FileResource) => {
|
|
20
|
+
const [previewUrl, setPreviewUrl] = useState<string | undefined>();
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
if (!file) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// If the file is a RemoteFile (has url property), use the url directly
|
|
28
|
+
if ('url' in file && file.url) {
|
|
29
|
+
setPreviewUrl(file.url);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// At this point, file must be a File object
|
|
34
|
+
const fileObj = file as File;
|
|
35
|
+
const isImageFile = fileObj.type.startsWith('image/');
|
|
36
|
+
|
|
37
|
+
// Only create URL for image files
|
|
38
|
+
if (!isImageFile) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Clean up previous URL before creating new one
|
|
43
|
+
if (previewUrl) {
|
|
44
|
+
URL.revokeObjectURL(previewUrl);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Create preview URL
|
|
48
|
+
const url = URL.createObjectURL(fileObj);
|
|
49
|
+
setPreviewUrl(url);
|
|
50
|
+
|
|
51
|
+
// Cleanup
|
|
52
|
+
return () => {
|
|
53
|
+
if (url) {
|
|
54
|
+
URL.revokeObjectURL(url);
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
//Ignore, as this is a cleanup function - adding previewUrl could cause infinite re-renders
|
|
58
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
59
|
+
}, [file]);
|
|
60
|
+
|
|
61
|
+
return previewUrl;
|
|
62
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @package @evolve.ui/core-components/fileUpload/hooks
|
|
3
|
+
* Custom hooks for file upload functionality
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
* Exports:
|
|
7
|
+
* - useFileValidation: Handles file validation with support for size, type, and custom rules
|
|
8
|
+
* - useImageFilePreviewUrl: Generates preview URLs for image files with automatic cleanup
|
|
9
|
+
*/
|
|
10
|
+
export { useFileValidation } from './validation/useFileValidation';
|
|
11
|
+
export { useImageFilePreviewUrl } from './filePreview/useImageFilePreviewUrl';
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { useCallback } from 'react';
|
|
2
|
+
|
|
3
|
+
import { UploadValidationContextType } from '../../../providers/UploadValidationProvider';
|
|
4
|
+
import { FileResource, FileValidator } from '../../../types/commonTypes';
|
|
5
|
+
import { createMessageContext } from '../../../utils/createMessageContext';
|
|
6
|
+
import { resolveContextAwareMessage } from '../../../utils/messageUtils';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Hook that handles file validation during drag events over a drop zone
|
|
10
|
+
* @param props Object containing:
|
|
11
|
+
* - files: Currently selected files in the uploader
|
|
12
|
+
* - mimeTypes: Optional mapping of accepted file types to their MIME type arrays
|
|
13
|
+
* - validation: Validation context (from either UploadValidationProvider
|
|
14
|
+
* or local useFileValidationLogic hook)
|
|
15
|
+
* - validator: Optional custom validation function to perform additional checks
|
|
16
|
+
* @returns Callback function for handling dragenter events with early validation feedback
|
|
17
|
+
* @remarks
|
|
18
|
+
* - Provides immediate validation feedback while files are being dragged over the drop zone
|
|
19
|
+
* - File size validation is not possible during drag events as file data is not yet available
|
|
20
|
+
* - Validates in a specific priority order: custom validator → file count → file type
|
|
21
|
+
* - Clears all validation state when drag starts
|
|
22
|
+
* - Sets appropriate validation error messages for display in the UI
|
|
23
|
+
* - Works with the ValidationContext to maintain validation state
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
type UseHandleDragEnterProps = {
|
|
27
|
+
/** Current files in the upload area */
|
|
28
|
+
files: FileResource[];
|
|
29
|
+
/** MIME types to accept */
|
|
30
|
+
mimeTypes?: Record<string, string[]>;
|
|
31
|
+
/** Validation context */
|
|
32
|
+
validation: UploadValidationContextType;
|
|
33
|
+
/** Custom validator function */
|
|
34
|
+
validator?: FileValidator;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Fires when a user drags files over the upload zone - provides early feedback on file type and max file limit
|
|
38
|
+
// Note: We cannot early-validate file size here since we don't have access to the file content during drag events, only after drop.
|
|
39
|
+
export const useHandleDragEnter = ({ files, mimeTypes, validation, validator }: UseHandleDragEnterProps) => {
|
|
40
|
+
const {
|
|
41
|
+
accept,
|
|
42
|
+
clearAllValidation,
|
|
43
|
+
formattedMaxSize,
|
|
44
|
+
getValidationMessage,
|
|
45
|
+
maxFiles,
|
|
46
|
+
maxSize,
|
|
47
|
+
setDragValidationError,
|
|
48
|
+
validateCustomRules,
|
|
49
|
+
validateFileCount,
|
|
50
|
+
validateFileType,
|
|
51
|
+
} = validation;
|
|
52
|
+
|
|
53
|
+
return useCallback(
|
|
54
|
+
(event: React.DragEvent<HTMLElement>) => {
|
|
55
|
+
// Clear all previous validation errors when a new drag event occurs
|
|
56
|
+
clearAllValidation();
|
|
57
|
+
|
|
58
|
+
const items = event.dataTransfer.items;
|
|
59
|
+
if (items.length === 0) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Validation priority follows a specific order with early returns:
|
|
64
|
+
// 1. Custom validator (highest priority)
|
|
65
|
+
if (validator) {
|
|
66
|
+
// Drag validation for custom validator uses the first dragged item
|
|
67
|
+
const file = items[0];
|
|
68
|
+
const validationResult = validateCustomRules(file);
|
|
69
|
+
if (validationResult) {
|
|
70
|
+
// Use the first error in the array
|
|
71
|
+
const result = validationResult[0];
|
|
72
|
+
|
|
73
|
+
// Create context with all necessary data for the error message
|
|
74
|
+
const messageContext = createMessageContext({
|
|
75
|
+
accept,
|
|
76
|
+
code: result.code,
|
|
77
|
+
count: items.length,
|
|
78
|
+
dragItems: items,
|
|
79
|
+
formattedMaxSize,
|
|
80
|
+
maxFiles,
|
|
81
|
+
maxSize,
|
|
82
|
+
messageType: 'drag',
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
// Set the error with a properly formatted message
|
|
86
|
+
setDragValidationError({
|
|
87
|
+
code: result.code,
|
|
88
|
+
message: resolveContextAwareMessage(result.message, messageContext),
|
|
89
|
+
});
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// 2. File count validation (second priority)
|
|
95
|
+
if (!validateFileCount(files.length, items.length)) {
|
|
96
|
+
const overflowCount = files.length + items.length - (maxFiles ?? Infinity);
|
|
97
|
+
|
|
98
|
+
const errorCode = 'too-many-files';
|
|
99
|
+
const errorMessage = getValidationMessage({
|
|
100
|
+
code: errorCode,
|
|
101
|
+
count: overflowCount,
|
|
102
|
+
messageType: 'drag',
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
setDragValidationError({
|
|
106
|
+
code: errorCode,
|
|
107
|
+
message: errorMessage,
|
|
108
|
+
});
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// 3. File type validation (lowest priority)
|
|
113
|
+
const invalidTypeFiles = Array.from(items).filter((item) => {
|
|
114
|
+
// Skip directories in validation (no type or kind is 'directory')
|
|
115
|
+
if (!item.type || item.kind === 'directory') {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
return !validateFileType(item.type, mimeTypes);
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
if (invalidTypeFiles.length > 0) {
|
|
122
|
+
const errorCode = 'file-invalid-type';
|
|
123
|
+
const errorMessage = getValidationMessage({
|
|
124
|
+
code: errorCode,
|
|
125
|
+
count: invalidTypeFiles.length,
|
|
126
|
+
messageType: 'drag',
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
setDragValidationError({
|
|
130
|
+
code: errorCode,
|
|
131
|
+
message: errorMessage,
|
|
132
|
+
});
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// If we reach here, all validation passed - no error is set
|
|
137
|
+
},
|
|
138
|
+
[
|
|
139
|
+
files.length,
|
|
140
|
+
mimeTypes,
|
|
141
|
+
clearAllValidation,
|
|
142
|
+
setDragValidationError,
|
|
143
|
+
getValidationMessage,
|
|
144
|
+
validateFileCount,
|
|
145
|
+
maxFiles,
|
|
146
|
+
validateFileType,
|
|
147
|
+
validateCustomRules,
|
|
148
|
+
validator,
|
|
149
|
+
accept,
|
|
150
|
+
formattedMaxSize,
|
|
151
|
+
maxSize,
|
|
152
|
+
]
|
|
153
|
+
);
|
|
154
|
+
};
|