@evolve.ui/core-components 1.0.1 → 1.2.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/{BottomSheet-ZV_eq3xt.mjs → BottomSheet-CNVLnEoD.mjs} +3 -3
- package/BottomSheet-CNVLnEoD.mjs.map +1 -0
- package/{BottomSheet-emWP9Fct.cjs → BottomSheet-D5w0WZDl.cjs} +3 -3
- package/BottomSheet-D5w0WZDl.cjs.map +1 -0
- package/Button.cjs +1 -1
- package/Button.mjs +1 -1
- package/{CookieConsent-CIwm0bTz.mjs → CookieConsent-B9dg9WdC.mjs} +2 -2
- package/{CookieConsent-CIwm0bTz.mjs.map → CookieConsent-B9dg9WdC.mjs.map} +1 -1
- package/{CookieConsent-PIglB_bb.cjs → CookieConsent-BSXJHMwX.cjs} +2 -2
- package/{CookieConsent-PIglB_bb.cjs.map → CookieConsent-BSXJHMwX.cjs.map} +1 -1
- package/{Drawer-9HFG45OA.cjs → Drawer-3rA9dGCl.cjs} +2 -2
- package/{Drawer-9HFG45OA.cjs.map → Drawer-3rA9dGCl.cjs.map} +1 -1
- package/Drawer-CFZbwg0R.d.cts.map +1 -1
- package/Drawer-CFZbwg0R.d.mts.map +1 -1
- package/{Drawer-BkCPfK6P.mjs → Drawer-DzKEmewj.mjs} +2 -2
- package/{Drawer-BkCPfK6P.mjs.map → Drawer-DzKEmewj.mjs.map} +1 -1
- package/{FavoriteButton-CC3qL0lR.mjs → FavoriteButton-7nK77lQP.mjs} +6 -6
- package/FavoriteButton-7nK77lQP.mjs.map +1 -0
- package/{FavoriteButton-BGF-3dze.d.cts → FavoriteButton-B8r_qtlj.d.cts} +2 -2
- package/{FavoriteButton-BGF-3dze.d.cts.map → FavoriteButton-B8r_qtlj.d.cts.map} +1 -1
- package/{FavoriteButton-DliYzkfu.cjs → FavoriteButton-BkIaWfgD.cjs} +6 -6
- package/FavoriteButton-BkIaWfgD.cjs.map +1 -0
- package/{FavoriteButton-BZEGWrRo.d.mts → FavoriteButton-hIkGjcKH.d.mts} +2 -2
- package/{FavoriteButton-BZEGWrRo.d.mts.map → FavoriteButton-hIkGjcKH.d.mts.map} +1 -1
- package/{FileUpload-p_pl9NXr.mjs → FileUpload-BfZOMsLs.mjs} +6 -6
- package/FileUpload-BfZOMsLs.mjs.map +1 -0
- package/{FileUpload--e_UJ_ek.cjs → FileUpload-gjRbkgrL.cjs} +6 -6
- package/FileUpload-gjRbkgrL.cjs.map +1 -0
- package/IconButton.cjs +1 -1
- package/IconButton.mjs +1 -1
- package/{ImageSlider-BidXfnLj.cjs → ImageSlider-CAgxQffP.cjs} +3 -3
- package/ImageSlider-CAgxQffP.cjs.map +1 -0
- package/{ImageSlider-CDrg_TbL.mjs → ImageSlider-fdrJ6lIJ.mjs} +3 -3
- package/ImageSlider-fdrJ6lIJ.mjs.map +1 -0
- package/InfoIconTooltip.cjs +1 -1
- package/InfoIconTooltip.cjs.map +1 -1
- package/InfoIconTooltip.mjs +1 -1
- package/InfoIconTooltip.mjs.map +1 -1
- package/InlineButton-CRLbNJZ3.d.mts.map +1 -1
- package/InlineButton-DoXGLiSE.d.cts.map +1 -1
- package/Input.cjs +1 -1
- package/Input.cjs.map +1 -1
- package/Input.mjs +1 -1
- package/Input.mjs.map +1 -1
- package/JumpMenu-BXYZnPIH.cjs.map +1 -1
- package/JumpMenu-DcZjAiej.mjs.map +1 -1
- package/{Menu-Cxu8CaX1.mjs → Menu-Bn4smlEe.mjs} +2 -2
- package/Menu-Bn4smlEe.mjs.map +1 -0
- package/{Menu-ClUogmwE.cjs → Menu-DuDhtoNP.cjs} +2 -2
- package/Menu-DuDhtoNP.cjs.map +1 -0
- package/Modal-DM0aXJZ5.d.cts.map +1 -1
- package/Modal-DM0aXJZ5.d.mts.map +1 -1
- package/{Modal-C6gatdtT.mjs → Modal-DtxWd7Le.mjs} +3 -2
- package/{Modal-C6gatdtT.mjs.map → Modal-DtxWd7Le.mjs.map} +1 -1
- package/{Modal-CiBqXyiK.cjs → Modal-q4HhBAQU.cjs} +3 -2
- package/Modal-q4HhBAQU.cjs.map +1 -0
- package/{Pagination-bAtbN478.cjs → Pagination-Denb9_zB.cjs} +2 -2
- package/{Pagination-bAtbN478.cjs.map → Pagination-Denb9_zB.cjs.map} +1 -1
- package/{Pagination-DIpGKMLz.mjs → Pagination-Dyfeys4B.mjs} +2 -2
- package/{Pagination-DIpGKMLz.mjs.map → Pagination-Dyfeys4B.mjs.map} +1 -1
- package/PhoneInput-B5pkpkdt.mjs.map +1 -1
- package/PhoneInput-BXnkBME4.d.mts.map +1 -1
- package/PhoneInput-Bkrbrins.d.cts.map +1 -1
- package/PhoneInput-CUMPOSxJ.cjs.map +1 -1
- package/{ProgressCircle-BC81D9sU.cjs → ProgressCircle-B6R4dxoV.cjs} +2 -2
- package/{ProgressCircle-BC81D9sU.cjs.map → ProgressCircle-B6R4dxoV.cjs.map} +1 -1
- package/{ProgressCircle-ae8cvZhe.mjs → ProgressCircle-zSai1HTT.mjs} +2 -2
- package/{ProgressCircle-ae8cvZhe.mjs.map → ProgressCircle-zSai1HTT.mjs.map} +1 -1
- package/SearchInput-DYIPC8Cd.d.cts.map +1 -1
- package/SearchInput-IfEWePDQ.d.mts.map +1 -1
- package/{Select-BkZu8OLs.mjs → Select-CH_ZN88G.mjs} +2 -2
- package/Select-CH_ZN88G.mjs.map +1 -0
- package/{Select-BXDjzyDs.cjs → Select-DCCcyLT4.cjs} +2 -2
- package/Select-DCCcyLT4.cjs.map +1 -0
- package/{SplitButton-DcmmLW8j.cjs → SplitButton-B_Y253RU.cjs} +2 -2
- package/{SplitButton-DcmmLW8j.cjs.map → SplitButton-B_Y253RU.cjs.map} +1 -1
- package/{SplitButton-WE5ymwCQ.mjs → SplitButton-_poP9Ykq.mjs} +2 -2
- package/{SplitButton-WE5ymwCQ.mjs.map → SplitButton-_poP9Ykq.mjs.map} +1 -1
- package/{Table-M-rANdMt.mjs → Table-CQGtDpvH.mjs} +3 -3
- package/{Table-M-rANdMt.mjs.map → Table-CQGtDpvH.mjs.map} +1 -1
- package/{Table-CLlDragJ.cjs → Table-D4UYosb1.cjs} +3 -3
- package/{Table-CLlDragJ.cjs.map → Table-D4UYosb1.cjs.map} +1 -1
- package/Typography/InlineButton.cjs +1 -1
- package/Typography/InlineButton.cjs.map +1 -1
- package/Typography/InlineButton.mjs +1 -1
- package/Typography/InlineButton.mjs.map +1 -1
- package/{ViewMore-BBoUvo7p.cjs → ViewMore-BcoSRZSl.cjs} +14 -1
- package/ViewMore-BcoSRZSl.cjs.map +1 -0
- package/{ViewMore-BrZPuE4E.mjs → ViewMore-Be0TQZ_2.mjs} +14 -1
- package/ViewMore-Be0TQZ_2.mjs.map +1 -0
- package/bottomSheet.cjs +1 -1
- package/bottomSheet.mjs +1 -1
- package/{buttonColorClasses-C3hg1at8.cjs → buttonColorClasses-CQQmLYfk.cjs} +4 -4
- package/buttonColorClasses-CQQmLYfk.cjs.map +1 -0
- package/{buttonColorClasses-B7OU4aQA.mjs → buttonColorClasses-CQnqAJXl.mjs} +4 -4
- package/buttonColorClasses-CQnqAJXl.mjs.map +1 -0
- package/card/components/createFavoriteButton.cjs +1 -1
- package/card/components/createFavoriteButton.mjs +1 -1
- package/cookieConsent.cjs +1 -1
- package/cookieConsent.mjs +1 -1
- package/drawer.cjs +1 -1
- package/drawer.mjs +1 -1
- package/evolve-ui.entries.json +556 -0
- package/favoriteButton.cjs +1 -1
- package/favoriteButton.d.cts +1 -1
- package/favoriteButton.d.mts +1 -1
- package/favoriteButton.mjs +1 -1
- package/featureFlags/hooks.d.cts +1 -1
- package/featureFlags/hooks.d.mts +1 -1
- package/fileUpload.cjs +1 -1
- package/fileUpload.mjs +1 -1
- package/imageSlider.cjs +1 -1
- package/imageSlider.mjs +1 -1
- package/index.cjs +14 -14
- package/index.d.cts +1 -1
- package/index.d.mts +1 -1
- package/index.mjs +14 -14
- package/menu.cjs +1 -1
- package/menu.mjs +1 -1
- package/modal/useCloseModal.cjs +2 -1
- package/modal/useCloseModal.cjs.map +1 -1
- package/modal/useCloseModal.mjs +2 -1
- package/modal/useCloseModal.mjs.map +1 -1
- package/modal.cjs +1 -1
- package/modal.mjs +1 -1
- package/package.json +2 -4
- package/pagination.cjs +1 -1
- package/pagination.mjs +1 -1
- package/progressCircle.cjs +1 -1
- package/progressCircle.mjs +1 -1
- package/searchInput.cjs +4 -4
- package/searchInput.cjs.map +1 -1
- package/searchInput.mjs +4 -4
- package/searchInput.mjs.map +1 -1
- package/select.cjs +1 -1
- package/select.mjs +1 -1
- package/selectAsync.cjs +1 -1
- package/selectAsync.mjs +1 -1
- package/selectAsyncCreatable.cjs +1 -1
- package/selectAsyncCreatable.mjs +1 -1
- package/selectCreatable.cjs +1 -1
- package/selectCreatable.mjs +1 -1
- package/splitButton.cjs +1 -1
- package/splitButton.mjs +1 -1
- package/src/Accordion/Accordion.tsx +233 -0
- package/src/AddressDisplay/AddressDisplay.tsx +43 -0
- package/src/AddressDisplay/components/addressComponents.tsx +111 -0
- package/src/AddressDisplay/components/addressField.tsx +25 -0
- package/src/AddressDisplay/components/addressSection.tsx +8 -0
- package/src/AddressDisplay/components/getCountryValue.tsx +31 -0
- package/src/AddressDisplay/types.ts +26 -0
- package/src/AutomatedCarousel/AutomatedCarousel.tsx +163 -0
- package/src/AutomatedCarousel/automatedCarousel.types.ts +7 -0
- package/src/AutomatedCarousel/components/CarouselProgressBar/CarouselProgressBar.tsx +139 -0
- package/src/AutomatedCarousel/components/CarouselProgressBar/components/CarouselProgressBarUnit/CarouselProgressBarUnit.tsx +165 -0
- package/src/Badge/Badge.tsx +104 -0
- package/src/Badge/Badge.types.ts +58 -0
- package/src/Badge/ItemBadge.tsx +97 -0
- package/src/Badge/LiveStatusBadge.tsx +93 -0
- package/src/BannerNotification/BannerNotification.tsx +157 -0
- package/src/BannerNotification/components/BannerNotificationSkeleton.tsx +39 -0
- package/src/BannerNotification/components/CalloutIcon/BannerIcon.tsx +48 -0
- package/src/BannerNotification/utils/getRandomTooltipId.ts +3 -0
- package/src/BottomSheet/BottomSheet.tsx +476 -0
- package/src/BottomSheet/components/BottomSheetBackdrop/BottomSheetBackdrop.tsx +47 -0
- package/src/BottomSheet/components/BottomSheetContentArea/BottomSheetContentArea.tsx +93 -0
- package/src/BottomSheet/components/BottomSheetOverlay/BottomSheetOverlayTranslate3d.tsx +199 -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 +58 -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 +443 -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 +83 -0
- package/src/FavoriteButton/components/LabeledAnimatedFavoriteButton/LabeledAnimatedFavoriteButton.tsx +186 -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 +584 -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 +65 -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 +321 -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 +140 -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 +515 -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 +237 -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 +305 -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 +159 -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 +167 -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 +65 -0
- package/src/utils/utilityTypes.ts +13 -0
- package/table.cjs +1 -1
- package/table.mjs +1 -1
- package/tabs.cjs +1 -1
- package/tabs.cjs.map +1 -1
- package/tabs.mjs +1 -1
- package/tabs.mjs.map +1 -1
- package/textArea.cjs.map +1 -1
- package/textArea.mjs.map +1 -1
- package/viewMore.cjs +1 -1
- package/viewMore.mjs +1 -1
- package/BottomSheet-ZV_eq3xt.mjs.map +0 -1
- package/BottomSheet-emWP9Fct.cjs.map +0 -1
- package/FavoriteButton-CC3qL0lR.mjs.map +0 -1
- package/FavoriteButton-DliYzkfu.cjs.map +0 -1
- package/FileUpload--e_UJ_ek.cjs.map +0 -1
- package/FileUpload-p_pl9NXr.mjs.map +0 -1
- package/ImageSlider-BidXfnLj.cjs.map +0 -1
- package/ImageSlider-CDrg_TbL.mjs.map +0 -1
- package/Menu-ClUogmwE.cjs.map +0 -1
- package/Menu-Cxu8CaX1.mjs.map +0 -1
- package/Modal-CiBqXyiK.cjs.map +0 -1
- package/Select-BXDjzyDs.cjs.map +0 -1
- package/Select-BkZu8OLs.mjs.map +0 -1
- package/ViewMore-BBoUvo7p.cjs.map +0 -1
- package/ViewMore-BrZPuE4E.mjs.map +0 -1
- package/buttonColorClasses-B7OU4aQA.mjs.map +0 -1
- package/buttonColorClasses-C3hg1at8.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProgressCircle-BC81D9sU.cjs","names":["getColor","colorIconSecondary","colorIconDisabled","colorIconSuccess","CheckCircle"],"sources":["../src/ProgressCircle/hooks/useProgressStatusTransitions.ts","../src/ProgressCircle/utils/progressCircle.constants.ts","../src/ProgressCircle/ProgressCircle.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\ntype ProgressCircleStatus = 'pending' | 'progressing' | 'complete' | 'indeterminate';\n\n/**\n * Manages the animation state for the ProgressCircle component.\n *\n * Handles two animation concerns:\n * 1. `animateToSolidCircle` - Controls the transition from dashed to solid circle\n * 2. `isShowingCompletion` - Controls whether to show the completion checkmark\n *\n * @param status - The current status of the progress circle\n * @returns Animation state flags for the component\n */\nexport const useProgressStatusTransitions = (status: ProgressCircleStatus) => {\n const isComplete = status === 'complete';\n const isProgressing = status === 'progressing';\n const isIndeterminate = status === 'indeterminate';\n\n // State to control animation trigger\n const [animateToSolidCircle, setAnimateToSolidCircle] = useState(false);\n // State to track completion animation\n const [isShowingCompletion, setIsShowingCompletion] = useState(false);\n\n // Trigger completion animation when status changes to/from 'complete'\n useEffect(() => {\n setIsShowingCompletion(isComplete);\n }, [isComplete]);\n\n // Trigger animation when status changes to progressing, complete, or indeterminate\n useEffect(() => {\n if (isProgressing || isComplete || isIndeterminate) {\n // Small delay to ensure element is mounted before animating\n const timer = setTimeout(() => {\n setAnimateToSolidCircle(true);\n }, 10);\n\n return () => {\n clearTimeout(timer);\n };\n }\n\n setAnimateToSolidCircle(false);\n\n return undefined;\n }, [isComplete, isIndeterminate, isProgressing]);\n\n return { animateToSolidCircle, isShowingCompletion };\n};\n","// SVG dimensions and styling constants\nexport const VIEWBOX_SIZE = 34;\nexport const CIRCLE_RADIUS = 11.25;\nexport const CIRCLE_CENTER = 17;\nexport const STROKE_WIDTH = 1.5;\nexport const ICON_CONTAINER_SIZE = 34;\nexport const DASHED_PATTERN = '4 4';\n\n// Outer circle sizes matching IconButton\nexport const progressCircleOuterSizes = {\n lg: 54,\n md: 42,\n sm: 34,\n} as const;\n\n// Animation calculation constants\nexport const WAVE_ARC_SIZE = 0.75;\nexport const WAVE_OFFSET = 0.125;\nexport const SPINNER_ARC_SIZE = 0.25;\n\n// Base props for all circle SVG elements (derived from constants above)\nexport const circleBaseProps = {\n cx: CIRCLE_CENTER,\n cy: CIRCLE_CENTER,\n r: CIRCLE_RADIUS,\n strokeWidth: STROKE_WIDTH,\n} as const;\n","import { colorIconDisabled, colorIconSecondary, colorIconSuccess } from '@evolve.ui/theme-system';\nimport { ReactNode } from 'react';\n\nimport { CheckCircle } from '../Icons/generatedIcons/CheckCircle';\nimport { getColor, IconProps } from '../Icons/IconBase';\nimport { useProgressStatusTransitions } from './hooks/useProgressStatusTransitions';\nimport {\n CIRCLE_RADIUS,\n circleBaseProps,\n DASHED_PATTERN,\n ICON_CONTAINER_SIZE,\n progressCircleOuterSizes,\n SPINNER_ARC_SIZE,\n VIEWBOX_SIZE,\n WAVE_ARC_SIZE,\n WAVE_OFFSET,\n} from './utils/progressCircle.constants';\n\ntype ProgressCircleProps = {\n 'aria-label'?: string;\n centerIcon?: ReactNode;\n className?: string;\n color?: Exclude<IconProps['color'], 'disabled' | 'inherit'>;\n 'data-testid'?: string;\n indeterminateAnimation?: 'spinner' | 'wave';\n /**\n * Progress value from 0-100. Only used when status is 'progressing'.\n * If not provided while status is 'progressing', an indeterminate animation will be shown instead.\n */\n progress?: number;\n size?: keyof typeof progressCircleOuterSizes;\n /**\n * Current status of the operation:\n * - 'pending': Shows dashed circle with gray arrow (not yet started)\n * - 'progressing': Shows progress animation. If `progress` is not provided, automatically shows indeterminate animation\n * - 'complete': Shows full circle with success checkmark animation\n * - 'indeterminate': Always shows indeterminate animation, even if progress value is provided (use for explicit indeterminate state)\n */\n status?: 'pending' | 'progressing' | 'complete' | 'indeterminate';\n};\n\nexport const ProgressCircle = ({\n 'aria-label': ariaLabel = 'Progress Circle',\n centerIcon,\n className,\n color = 'secondary',\n 'data-testid': dataTestId,\n indeterminateAnimation = 'spinner',\n progress,\n size = 'md',\n status = 'pending',\n}: ProgressCircleProps) => {\n const outerSize = progressCircleOuterSizes[size];\n\n const strokeColor = getColor(color) ?? `rgb(var(${colorIconSecondary}))`;\n const grayColor = `rgb(var(${colorIconDisabled}))`;\n const successColor = `rgb(var(${colorIconSuccess}))`;\n\n // Status flags for cleaner conditionals\n const isPending = status === 'pending';\n const isProgressing = status === 'progressing';\n const isComplete = status === 'complete';\n const isIndeterminate = status === 'indeterminate';\n\n // When status is complete, always use success color for the progress circle\n const progressCircleColor = isComplete ? successColor : strokeColor;\n\n // Arrow color changes based on status: gray when pending, colored otherwise\n const arrowColor = isPending ? grayColor : strokeColor;\n\n // Calculate circle circumference for progress animation\n const circumference = 2 * Math.PI * CIRCLE_RADIUS;\n\n // Calculate foreignObject dimensions - centered in viewBox\n const iconViewBoxOffset = (VIEWBOX_SIZE - ICON_CONTAINER_SIZE) / 2;\n\n // Transition state from custom hook\n const { animateToSolidCircle, isShowingCompletion } = useProgressStatusTransitions(status);\n\n // Show fill and progress circles only when progressing or complete\n const showProgressCircles = isProgressing || isComplete;\n\n // Auto-set progress to 100% when status is complete\n // Default to 0 if progress is undefined (though this should only be used when showProgressArc is true)\n const resolvedProgressValue = isComplete ? 100 : (progress ?? 0);\n\n // Gray fill circle: animates from circumference to 0 when animateToSolidCircle is true\n const grayFillOffset = animateToSolidCircle ? 0 : circumference;\n\n // Colored progress circle: tied to effective progress value (100% when complete)\n const progressOffset = circumference - (resolvedProgressValue / 100) * circumference;\n\n // Conditional rendering logic for indeterminate vs progress modes\n // Show indeterminate if explicitly set OR if progressing without progress value\n const hasProgressValue = typeof progress === 'number';\n const isIndeterminateMode = isIndeterminate || (isProgressing && !hasProgressValue);\n const showIndeterminateSpinner = isIndeterminateMode && animateToSolidCircle;\n const showProgressArc = !isIndeterminateMode && showProgressCircles;\n const showGrayFill = isIndeterminateMode || showProgressCircles;\n\n // CSS custom properties for the wave animation keyframes (defined in plugin.ts).\n // These must be inline styles because the values are calculated from the\n // circle's circumference, which is derived from CIRCLE_RADIUS based off chosen size (sm, md, lg) at runtime.\n const waveAnimationStyles = {\n '--progress-wave-end': `1 ${circumference}`,\n '--progress-wave-full': `${-circumference}`,\n '--progress-wave-mid': `${circumference * WAVE_ARC_SIZE} ${circumference}`,\n '--progress-wave-offset': `${-circumference * WAVE_OFFSET}`,\n '--progress-wave-start': `1 ${circumference}`,\n } as React.CSSProperties;\n\n // Determine ARIA attributes based on whether we're showing determinate or indeterminate\n // Show progressbar role only when actively progressing with progress value\n // Complete status should be 'status' role, not 'progressbar'\n const ariaRole = showProgressArc && !isComplete ? 'progressbar' : 'status';\n const ariaBusy = isIndeterminateMode || isProgressing;\n const ariaValueNow = showProgressArc ? resolvedProgressValue : undefined;\n\n return (\n <span\n className={className}\n data-testid={dataTestId}\n style={waveAnimationStyles}\n >\n <svg\n aria-busy={ariaBusy}\n aria-label={ariaLabel}\n aria-live=\"polite\"\n aria-valuemax={showProgressArc ? 100 : undefined}\n aria-valuemin={showProgressArc ? 0 : undefined}\n aria-valuenow={ariaValueNow}\n className={\n isShowingCompletion\n ? `min-h-[${outerSize}px] min-w-[${outerSize}px] animate-progress-completion`\n : `min-h-[${outerSize}px] min-w-[${outerSize}px]`\n }\n fill=\"none\"\n height={outerSize}\n role={ariaRole}\n viewBox={`0 0 ${VIEWBOX_SIZE} ${VIEWBOX_SIZE}`}\n width={outerSize}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {/* Dashed background circle */}\n <circle\n {...circleBaseProps}\n stroke={grayColor}\n strokeDasharray={DASHED_PATTERN}\n />\n\n {/* Gray fill circle - animates 0→100% in 300ms when status is progressing or indeterminate */}\n {showGrayFill && (\n <circle\n {...circleBaseProps}\n className=\"origin-center -rotate-90 transition-[stroke-dashoffset] duration-300\"\n stroke={grayColor}\n strokeDasharray={circumference}\n strokeDashoffset={grayFillOffset}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Indeterminate spinner - 1/4 circle arc that rotates */}\n {showIndeterminateSpinner && indeterminateAnimation === 'spinner' && (\n <circle\n {...circleBaseProps}\n className=\"origin-center animate-spin\"\n stroke={strokeColor}\n strokeDasharray={`${circumference * SPINNER_ARC_SIZE} ${circumference * (1 - SPINNER_ARC_SIZE)}`}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Indeterminate wave - Google Loader style animation */}\n {showIndeterminateSpinner && indeterminateAnimation === 'wave' && (\n <circle\n {...circleBaseProps}\n className=\"origin-center animate-progress-wave\"\n stroke={strokeColor}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Colored progress circle - tied to progress value (determinate mode) */}\n {showProgressArc && (\n <circle\n {...circleBaseProps}\n className=\"origin-center -rotate-90 transition-[stroke-dashoffset_0.5s_ease-in-out_0.3s,stroke_0.3s_ease-in-out]\"\n stroke={progressCircleColor}\n strokeDasharray={circumference}\n strokeDashoffset={progressOffset}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Center icon content */}\n {!isShowingCompletion && (\n <foreignObject\n height={ICON_CONTAINER_SIZE}\n width={ICON_CONTAINER_SIZE}\n x={iconViewBoxOffset}\n y={iconViewBoxOffset}\n >\n <div className=\"flex h-full w-full items-center justify-center\">\n {centerIcon || (\n <svg\n fill=\"none\"\n height={ICON_CONTAINER_SIZE}\n viewBox={`0 0 ${VIEWBOX_SIZE} ${VIEWBOX_SIZE}`}\n width={ICON_CONTAINER_SIZE}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n className=\"transition-[fill_0.3s_ease-in-out]\"\n d=\"M21.4015 16.5893C21.3406 16.6504 21.2681 16.699 21.1883 16.7321C21.1086 16.7652 21.0231 16.7823 20.9367 16.7823C20.8503 16.7823 20.7648 16.7652 20.685 16.7321C20.6053 16.699 20.5328 16.6504 20.4718 16.5893L17.656 13.7734V21.8125C17.656 21.9865 17.5868 22.1534 17.4638 22.2765C17.3407 22.3996 17.1738 22.4687 16.9997 22.4687C16.8257 22.4687 16.6588 22.3996 16.5357 22.2765C16.4126 22.1534 16.3435 21.9865 16.3435 21.8125V13.7734L13.5265 16.5893C13.4032 16.7125 13.236 16.7818 13.0617 16.7818C12.8873 16.7818 12.7201 16.7125 12.5968 16.5893C12.4736 16.466 12.4043 16.2988 12.4043 16.1244C12.4043 15.9501 12.4736 15.7829 12.5968 15.6596L16.5343 11.7221C16.5953 11.6609 16.6678 11.6123 16.7475 11.5792C16.8273 11.5461 16.9128 11.5291 16.9992 11.5291C17.0856 11.5291 17.1711 11.5461 17.2508 11.5792C17.3306 11.6123 17.4031 11.6609 17.464 11.7221L21.4015 15.6596C21.4627 15.7205 21.5113 15.793 21.5444 15.8728C21.5775 15.9525 21.5945 16.038 21.5945 16.1244C21.5945 16.2108 21.5775 16.2963 21.5444 16.3761C21.5113 16.4558 21.4627 16.5283 21.4015 16.5893Z\"\n fill={arrowColor}\n />\n </svg>\n )}\n </div>\n </foreignObject>\n )}\n\n {/* Completion CheckCircle */}\n {isShowingCompletion && (\n <foreignObject\n height={ICON_CONTAINER_SIZE}\n width={ICON_CONTAINER_SIZE}\n x={iconViewBoxOffset}\n y={iconViewBoxOffset}\n >\n <div className=\"flex h-full w-full animate-progress-icon-fade-in items-center justify-center\">\n <CheckCircle\n color=\"success\"\n size=\"md\"\n style=\"fill\"\n />\n </div>\n </foreignObject>\n )}\n </svg>\n </span>\n );\n};\n\nProgressCircle.displayName = 'ProgressCircle';\n"],"mappings":";;;;;;;;;;;;;;;;AAcA,MAAa,gCAAgC,WAAiC;CAC1E,MAAM,aAAa,WAAW;CAC9B,MAAM,gBAAgB,WAAW;CACjC,MAAM,kBAAkB,WAAW;CAGnC,MAAM,CAAC,sBAAsB,4BAAA,GAAA,MAAA,SAAA,CAAoC,KAAK;CAEtE,MAAM,CAAC,qBAAqB,2BAAA,GAAA,MAAA,SAAA,CAAmC,KAAK;CAGpE,CAAA,GAAA,MAAA,UAAA,OAAgB;EACZ,uBAAuB,UAAU;CACrC,GAAG,CAAC,UAAU,CAAC;CAGf,CAAA,GAAA,MAAA,UAAA,OAAgB;EACZ,IAAI,iBAAiB,cAAc,iBAAiB;GAEhD,MAAM,QAAQ,iBAAiB;IAC3B,wBAAwB,IAAI;GAChC,GAAG,EAAE;GAEL,aAAa;IACT,aAAa,KAAK;GACtB;EACJ;EAEA,wBAAwB,KAAK;CAGjC,GAAG;EAAC;EAAY;EAAiB;CAAa,CAAC;CAE/C,OAAO;EAAE;EAAsB;CAAoB;AACvD;;;AC9CA,MAAa,gBAAgB;AAE7B,MAAa,eAAe;AAK5B,MAAa,2BAA2B;CACpC,IAAI;CACJ,IAAI;CACJ,IAAI;AACR;AAGA,MAAa,gBAAgB;AAC7B,MAAa,cAAc;AAI3B,MAAa,kBAAkB;CAC3B,IAAA;CACA,IAAA;CACA,GAAG;CACH,aAAa;AACjB;;;ACeA,MAAa,kBAAkB,EAC3B,cAAc,YAAY,mBAC1B,YACA,WACA,QAAQ,aACR,eAAe,YACf,yBAAyB,WACzB,UACA,OAAO,MACP,SAAS,gBACc;CACvB,MAAM,YAAY,yBAAyB;CAE3C,MAAM,cAAcA,uBAAAA,SAAS,KAAK,KAAK,WAAWC,wBAAAA,mBAAmB;CACrE,MAAM,YAAY,WAAWC,wBAAAA,kBAAkB;CAC/C,MAAM,eAAe,WAAWC,wBAAAA,iBAAiB;CAGjD,MAAM,YAAY,WAAW;CAC7B,MAAM,gBAAgB,WAAW;CACjC,MAAM,aAAa,WAAW;CAC9B,MAAM,kBAAkB,WAAW;CAGnC,MAAM,sBAAsB,aAAa,eAAe;CAGxD,MAAM,aAAa,YAAY,YAAY;CAG3C,MAAM,gBAAgB,IAAI,KAAK,KAAK;CAGpC,MAAM,oBAAA,IAA2D;CAGjE,MAAM,EAAE,sBAAsB,wBAAwB,6BAA6B,MAAM;CAGzF,MAAM,sBAAsB,iBAAiB;CAI7C,MAAM,wBAAwB,aAAa,MAAO,YAAY;CAG9D,MAAM,iBAAiB,uBAAuB,IAAI;CAGlD,MAAM,iBAAiB,gBAAiB,wBAAwB,MAAO;CAKvE,MAAM,sBAAsB,mBAAoB,iBAAiB,EADxC,OAAO,aAAa;CAE7C,MAAM,2BAA2B,uBAAuB;CACxD,MAAM,kBAAkB,CAAC,uBAAuB;CAChD,MAAM,eAAe,uBAAuB;CAK5C,MAAM,sBAAsB;EACxB,uBAAuB,KAAK;EAC5B,wBAAwB,GAAG,CAAC;EAC5B,uBAAuB,GAAG,gBAAgB,cAAc,GAAG;EAC3D,0BAA0B,GAAG,CAAC,gBAAgB;EAC9C,yBAAyB,KAAK;CAClC;CAKA,MAAM,WAAW,mBAAmB,CAAC,aAAa,gBAAgB;CAIlE,OACI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;EACe;EACX,eAAa;EACb,OAAO;YAEP,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;GACI,aAVK,uBAAuB;GAW5B,cAAY;GACZ,aAAU;GACV,iBAAe,kBAAkB,MAAM,KAAA;GACvC,iBAAe,kBAAkB,IAAI,KAAA;GACrC,iBAdS,kBAAkB,wBAAwB,KAAA;GAenD,WACI,sBACM,UAAU,UAAU,aAAa,UAAU,mCAC3C,UAAU,UAAU,aAAa,UAAU;GAErD,MAAK;GACL,QAAQ;GACR,MAAM;GACN,SAAS;GACT,OAAO;GACP,OAAM;aAjBV;IAoBI,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACI,GAAI;KACJ,QAAQ;KACR,iBAAA;IACH,CAAA;IAGA,gBACG,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACI,GAAI;KACJ,WAAU;KACV,QAAQ;KACR,iBAAiB;KACjB,kBAAkB;KAClB,eAAc;IACjB,CAAA;IAIJ,4BAA4B,2BAA2B,aACpD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACI,GAAI;KACJ,WAAU;KACV,QAAQ;KACR,iBAAiB,GAAG,gBAAA,IAAiC,GAAG,gBAAiB;KACzE,eAAc;IACjB,CAAA;IAIJ,4BAA4B,2BAA2B,UACpD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACI,GAAI;KACJ,WAAU;KACV,QAAQ;KACR,eAAc;IACjB,CAAA;IAIJ,mBACG,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACI,GAAI;KACJ,WAAU;KACV,QAAQ;KACR,iBAAiB;KACjB,kBAAkB;KAClB,eAAc;IACjB,CAAA;IAIJ,CAAC,uBACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAD;KACI,QAAA;KACA,OAAA;KACA,GAAG;KACH,GAAG;eAEH,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAU;gBACV,cACG,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OACI,MAAK;OACL,QAAA;OACA,SAAS;OACT,OAAA;OACA,OAAM;iBAEN,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QACI,WAAU;QACV,GAAE;QACF,MAAM;OACT,CAAA;MACA,CAAA;KAER,CAAA;IACM,CAAA;IAIlB,uBACG,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAD;KACI,QAAA;KACA,OAAA;KACA,GAAG;KACH,GAAG;eAEH,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAU;gBACX,iBAAA,GAAA,kBAAA,IAAA,CAACC,oBAAAA,aAAD;OACI,OAAM;OACN,MAAK;OACL,OAAM;MACT,CAAA;KACA,CAAA;IACM,CAAA;GAElB;;CACH,CAAA;AAEd;AAEA,eAAe,cAAc"}
|
|
1
|
+
{"version":3,"file":"ProgressCircle-B6R4dxoV.cjs","names":["getColor","colorIconSecondary","colorIconDisabled","colorIconSuccess","CheckCircle"],"sources":["../src/ProgressCircle/hooks/useProgressStatusTransitions.ts","../src/ProgressCircle/utils/progressCircle.constants.ts","../src/ProgressCircle/ProgressCircle.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\ntype ProgressCircleStatus = 'pending' | 'progressing' | 'complete' | 'indeterminate';\n\n/**\n * Manages the animation state for the ProgressCircle component.\n *\n * Handles two animation concerns:\n * 1. `animateToSolidCircle` - Controls the transition from dashed to solid circle\n * 2. `isShowingCompletion` - Controls whether to show the completion checkmark\n *\n * @param status - The current status of the progress circle\n * @returns Animation state flags for the component\n */\nexport const useProgressStatusTransitions = (status: ProgressCircleStatus) => {\n const isComplete = status === 'complete';\n const isProgressing = status === 'progressing';\n const isIndeterminate = status === 'indeterminate';\n\n // State to control animation trigger\n const [animateToSolidCircle, setAnimateToSolidCircle] = useState(false);\n // State to track completion animation\n const [isShowingCompletion, setIsShowingCompletion] = useState(false);\n\n // Trigger completion animation when status changes to/from 'complete'\n useEffect(() => {\n setIsShowingCompletion(isComplete);\n }, [isComplete]);\n\n // Trigger animation when status changes to progressing, complete, or indeterminate\n useEffect(() => {\n if (isProgressing || isComplete || isIndeterminate) {\n // Small delay to ensure element is mounted before animating\n const timer = setTimeout(() => {\n setAnimateToSolidCircle(true);\n }, 10);\n\n return () => {\n clearTimeout(timer);\n };\n }\n\n setAnimateToSolidCircle(false);\n\n return undefined;\n }, [isComplete, isIndeterminate, isProgressing]);\n\n return { animateToSolidCircle, isShowingCompletion };\n};\n","// SVG dimensions and styling constants\nexport const VIEWBOX_SIZE = 34;\nexport const CIRCLE_RADIUS = 11.25;\nexport const CIRCLE_CENTER = 17;\nexport const STROKE_WIDTH = 1.5;\nexport const ICON_CONTAINER_SIZE = 34;\nexport const DASHED_PATTERN = '4 4';\n\n// Outer circle sizes matching IconButton\nexport const progressCircleOuterSizes = {\n lg: 54,\n md: 42,\n sm: 34,\n} as const;\n\n// Animation calculation constants\nexport const WAVE_ARC_SIZE = 0.75;\nexport const WAVE_OFFSET = 0.125;\nexport const SPINNER_ARC_SIZE = 0.25;\n\n// Base props for all circle SVG elements (derived from constants above)\nexport const circleBaseProps = {\n cx: CIRCLE_CENTER,\n cy: CIRCLE_CENTER,\n r: CIRCLE_RADIUS,\n strokeWidth: STROKE_WIDTH,\n} as const;\n","import { colorIconDisabled, colorIconSecondary, colorIconSuccess } from '@evolve.ui/theme-system';\nimport { ReactNode } from 'react';\n\nimport { CheckCircle } from '../Icons/generatedIcons/CheckCircle';\nimport { getColor, IconProps } from '../Icons/IconBase';\nimport { useProgressStatusTransitions } from './hooks/useProgressStatusTransitions';\nimport {\n CIRCLE_RADIUS,\n circleBaseProps,\n DASHED_PATTERN,\n ICON_CONTAINER_SIZE,\n progressCircleOuterSizes,\n SPINNER_ARC_SIZE,\n VIEWBOX_SIZE,\n WAVE_ARC_SIZE,\n WAVE_OFFSET,\n} from './utils/progressCircle.constants';\n\ntype ProgressCircleProps = {\n 'aria-label'?: string;\n centerIcon?: ReactNode;\n className?: string;\n color?: Exclude<IconProps['color'], 'disabled' | 'inherit'>;\n 'data-testid'?: string;\n indeterminateAnimation?: 'spinner' | 'wave';\n /**\n * Progress value from 0-100. Only used when status is 'progressing'.\n * If not provided while status is 'progressing', an indeterminate animation will be shown instead.\n */\n progress?: number;\n size?: keyof typeof progressCircleOuterSizes;\n /**\n * Current status of the operation:\n * - 'pending': Shows dashed circle with gray arrow (not yet started)\n * - 'progressing': Shows progress animation. If `progress` is not provided, automatically shows indeterminate animation\n * - 'complete': Shows full circle with success checkmark animation\n * - 'indeterminate': Always shows indeterminate animation, even if progress value is provided (use for explicit indeterminate state)\n */\n status?: 'pending' | 'progressing' | 'complete' | 'indeterminate';\n};\n\nexport const ProgressCircle = ({\n 'aria-label': ariaLabel = 'Progress Circle',\n centerIcon,\n className,\n color = 'secondary',\n 'data-testid': dataTestId,\n indeterminateAnimation = 'spinner',\n progress,\n size = 'md',\n status = 'pending',\n}: ProgressCircleProps) => {\n const outerSize = progressCircleOuterSizes[size];\n\n const strokeColor = getColor(color) ?? `rgb(var(${colorIconSecondary}))`;\n const grayColor = `rgb(var(${colorIconDisabled}))`;\n const successColor = `rgb(var(${colorIconSuccess}))`;\n\n // Status flags for cleaner conditionals\n const isPending = status === 'pending';\n const isProgressing = status === 'progressing';\n const isComplete = status === 'complete';\n const isIndeterminate = status === 'indeterminate';\n\n // When status is complete, always use success color for the progress circle\n const progressCircleColor = isComplete ? successColor : strokeColor;\n\n // Arrow color changes based on status: gray when pending, colored otherwise\n const arrowColor = isPending ? grayColor : strokeColor;\n\n // Calculate circle circumference for progress animation\n const circumference = 2 * Math.PI * CIRCLE_RADIUS;\n\n // Calculate foreignObject dimensions - centered in viewBox\n const iconViewBoxOffset = (VIEWBOX_SIZE - ICON_CONTAINER_SIZE) / 2;\n\n // Transition state from custom hook\n const { animateToSolidCircle, isShowingCompletion } = useProgressStatusTransitions(status);\n\n // Show fill and progress circles only when progressing or complete\n const showProgressCircles = isProgressing || isComplete;\n\n // Auto-set progress to 100% when status is complete\n // Default to 0 if progress is undefined (though this should only be used when showProgressArc is true)\n const resolvedProgressValue = isComplete ? 100 : (progress ?? 0);\n\n // Gray fill circle: animates from circumference to 0 when animateToSolidCircle is true\n const grayFillOffset = animateToSolidCircle ? 0 : circumference;\n\n // Colored progress circle: tied to effective progress value (100% when complete)\n const progressOffset = circumference - (resolvedProgressValue / 100) * circumference;\n\n // Conditional rendering logic for indeterminate vs progress modes\n // Show indeterminate if explicitly set OR if progressing without progress value\n const hasProgressValue = typeof progress === 'number';\n const isIndeterminateMode = isIndeterminate || (isProgressing && !hasProgressValue);\n const showIndeterminateSpinner = isIndeterminateMode && animateToSolidCircle;\n const showProgressArc = !isIndeterminateMode && showProgressCircles;\n const showGrayFill = isIndeterminateMode || showProgressCircles;\n\n // CSS custom properties for the wave animation keyframes (defined in plugin.ts).\n // These must be inline styles because the values are calculated from the\n // circle's circumference, which is derived from CIRCLE_RADIUS based off chosen size (sm, md, lg) at runtime.\n const waveAnimationStyles = {\n '--progress-wave-end': `1 ${circumference}`,\n '--progress-wave-full': `${-circumference}`,\n '--progress-wave-mid': `${circumference * WAVE_ARC_SIZE} ${circumference}`,\n '--progress-wave-offset': `${-circumference * WAVE_OFFSET}`,\n '--progress-wave-start': `1 ${circumference}`,\n } as React.CSSProperties;\n\n // Determine ARIA attributes based on whether we're showing determinate or indeterminate\n // Show progressbar role only when actively progressing with progress value\n // Complete status should be 'status' role, not 'progressbar'\n const ariaRole = showProgressArc && !isComplete ? 'progressbar' : 'status';\n const ariaBusy = isIndeterminateMode || isProgressing;\n const ariaValueNow = showProgressArc ? resolvedProgressValue : undefined;\n\n return (\n <span\n className={className}\n data-testid={dataTestId}\n style={waveAnimationStyles}\n >\n <svg\n aria-busy={ariaBusy}\n aria-label={ariaLabel}\n aria-live=\"polite\"\n aria-valuemax={showProgressArc ? 100 : undefined}\n aria-valuemin={showProgressArc ? 0 : undefined}\n aria-valuenow={ariaValueNow}\n className={\n isShowingCompletion\n ? `min-h-[${outerSize}px] min-w-[${outerSize}px] animate-progress-completion`\n : `min-h-[${outerSize}px] min-w-[${outerSize}px]`\n }\n fill=\"none\"\n height={outerSize}\n role={ariaRole}\n viewBox={`0 0 ${VIEWBOX_SIZE} ${VIEWBOX_SIZE}`}\n width={outerSize}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {/* Dashed background circle */}\n <circle\n {...circleBaseProps}\n stroke={grayColor}\n strokeDasharray={DASHED_PATTERN}\n />\n\n {/* Gray fill circle - animates 0→100% in 300ms when status is progressing or indeterminate */}\n {showGrayFill && (\n <circle\n {...circleBaseProps}\n className=\"origin-center -rotate-90 transition-[stroke-dashoffset] duration-300\"\n stroke={grayColor}\n strokeDasharray={circumference}\n strokeDashoffset={grayFillOffset}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Indeterminate spinner - 1/4 circle arc that rotates */}\n {showIndeterminateSpinner && indeterminateAnimation === 'spinner' && (\n <circle\n {...circleBaseProps}\n className=\"origin-center animate-spin\"\n stroke={strokeColor}\n strokeDasharray={`${circumference * SPINNER_ARC_SIZE} ${circumference * (1 - SPINNER_ARC_SIZE)}`}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Indeterminate wave - Google Loader style animation */}\n {showIndeterminateSpinner && indeterminateAnimation === 'wave' && (\n <circle\n {...circleBaseProps}\n className=\"origin-center animate-progress-wave\"\n stroke={strokeColor}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Colored progress circle - tied to progress value (determinate mode) */}\n {showProgressArc && (\n <circle\n {...circleBaseProps}\n className=\"origin-center -rotate-90 transition-[stroke-dashoffset_0.5s_ease-in-out_0.3s,stroke_0.3s_ease-in-out]\"\n stroke={progressCircleColor}\n strokeDasharray={circumference}\n strokeDashoffset={progressOffset}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Center icon content */}\n {!isShowingCompletion && (\n <foreignObject\n height={ICON_CONTAINER_SIZE}\n width={ICON_CONTAINER_SIZE}\n x={iconViewBoxOffset}\n y={iconViewBoxOffset}\n >\n <div className=\"flex h-full w-full items-center justify-center\">\n {centerIcon || (\n <svg\n fill=\"none\"\n height={ICON_CONTAINER_SIZE}\n viewBox={`0 0 ${VIEWBOX_SIZE} ${VIEWBOX_SIZE}`}\n width={ICON_CONTAINER_SIZE}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n className=\"transition-[fill_0.3s_ease-in-out]\"\n d=\"M21.4015 16.5893C21.3406 16.6504 21.2681 16.699 21.1883 16.7321C21.1086 16.7652 21.0231 16.7823 20.9367 16.7823C20.8503 16.7823 20.7648 16.7652 20.685 16.7321C20.6053 16.699 20.5328 16.6504 20.4718 16.5893L17.656 13.7734V21.8125C17.656 21.9865 17.5868 22.1534 17.4638 22.2765C17.3407 22.3996 17.1738 22.4687 16.9997 22.4687C16.8257 22.4687 16.6588 22.3996 16.5357 22.2765C16.4126 22.1534 16.3435 21.9865 16.3435 21.8125V13.7734L13.5265 16.5893C13.4032 16.7125 13.236 16.7818 13.0617 16.7818C12.8873 16.7818 12.7201 16.7125 12.5968 16.5893C12.4736 16.466 12.4043 16.2988 12.4043 16.1244C12.4043 15.9501 12.4736 15.7829 12.5968 15.6596L16.5343 11.7221C16.5953 11.6609 16.6678 11.6123 16.7475 11.5792C16.8273 11.5461 16.9128 11.5291 16.9992 11.5291C17.0856 11.5291 17.1711 11.5461 17.2508 11.5792C17.3306 11.6123 17.4031 11.6609 17.464 11.7221L21.4015 15.6596C21.4627 15.7205 21.5113 15.793 21.5444 15.8728C21.5775 15.9525 21.5945 16.038 21.5945 16.1244C21.5945 16.2108 21.5775 16.2963 21.5444 16.3761C21.5113 16.4558 21.4627 16.5283 21.4015 16.5893Z\"\n fill={arrowColor}\n />\n </svg>\n )}\n </div>\n </foreignObject>\n )}\n\n {/* Completion CheckCircle */}\n {isShowingCompletion && (\n <foreignObject\n height={ICON_CONTAINER_SIZE}\n width={ICON_CONTAINER_SIZE}\n x={iconViewBoxOffset}\n y={iconViewBoxOffset}\n >\n <div className=\"animate-progress-icon-fade-in flex h-full w-full items-center justify-center\">\n <CheckCircle\n color=\"success\"\n size=\"md\"\n style=\"fill\"\n />\n </div>\n </foreignObject>\n )}\n </svg>\n </span>\n );\n};\n\nProgressCircle.displayName = 'ProgressCircle';\n"],"mappings":";;;;;;;;;;;;;;;;AAcA,MAAa,gCAAgC,WAAiC;CAC1E,MAAM,aAAa,WAAW;CAC9B,MAAM,gBAAgB,WAAW;CACjC,MAAM,kBAAkB,WAAW;CAGnC,MAAM,CAAC,sBAAsB,4BAAA,GAAA,MAAA,SAAA,CAAoC,KAAK;CAEtE,MAAM,CAAC,qBAAqB,2BAAA,GAAA,MAAA,SAAA,CAAmC,KAAK;CAGpE,CAAA,GAAA,MAAA,UAAA,OAAgB;EACZ,uBAAuB,UAAU;CACrC,GAAG,CAAC,UAAU,CAAC;CAGf,CAAA,GAAA,MAAA,UAAA,OAAgB;EACZ,IAAI,iBAAiB,cAAc,iBAAiB;GAEhD,MAAM,QAAQ,iBAAiB;IAC3B,wBAAwB,IAAI;GAChC,GAAG,EAAE;GAEL,aAAa;IACT,aAAa,KAAK;GACtB;EACJ;EAEA,wBAAwB,KAAK;CAGjC,GAAG;EAAC;EAAY;EAAiB;CAAa,CAAC;CAE/C,OAAO;EAAE;EAAsB;CAAoB;AACvD;;;AC9CA,MAAa,gBAAgB;AAE7B,MAAa,eAAe;AAK5B,MAAa,2BAA2B;CACpC,IAAI;CACJ,IAAI;CACJ,IAAI;AACR;AAGA,MAAa,gBAAgB;AAC7B,MAAa,cAAc;AAI3B,MAAa,kBAAkB;CAC3B,IAAA;CACA,IAAA;CACA,GAAG;CACH,aAAa;AACjB;;;ACeA,MAAa,kBAAkB,EAC3B,cAAc,YAAY,mBAC1B,YACA,WACA,QAAQ,aACR,eAAe,YACf,yBAAyB,WACzB,UACA,OAAO,MACP,SAAS,gBACc;CACvB,MAAM,YAAY,yBAAyB;CAE3C,MAAM,cAAcA,uBAAAA,SAAS,KAAK,KAAK,WAAWC,wBAAAA,mBAAmB;CACrE,MAAM,YAAY,WAAWC,wBAAAA,kBAAkB;CAC/C,MAAM,eAAe,WAAWC,wBAAAA,iBAAiB;CAGjD,MAAM,YAAY,WAAW;CAC7B,MAAM,gBAAgB,WAAW;CACjC,MAAM,aAAa,WAAW;CAC9B,MAAM,kBAAkB,WAAW;CAGnC,MAAM,sBAAsB,aAAa,eAAe;CAGxD,MAAM,aAAa,YAAY,YAAY;CAG3C,MAAM,gBAAgB,IAAI,KAAK,KAAK;CAGpC,MAAM,oBAAA,IAA2D;CAGjE,MAAM,EAAE,sBAAsB,wBAAwB,6BAA6B,MAAM;CAGzF,MAAM,sBAAsB,iBAAiB;CAI7C,MAAM,wBAAwB,aAAa,MAAO,YAAY;CAG9D,MAAM,iBAAiB,uBAAuB,IAAI;CAGlD,MAAM,iBAAiB,gBAAiB,wBAAwB,MAAO;CAKvE,MAAM,sBAAsB,mBAAoB,iBAAiB,EADxC,OAAO,aAAa;CAE7C,MAAM,2BAA2B,uBAAuB;CACxD,MAAM,kBAAkB,CAAC,uBAAuB;CAChD,MAAM,eAAe,uBAAuB;CAK5C,MAAM,sBAAsB;EACxB,uBAAuB,KAAK;EAC5B,wBAAwB,GAAG,CAAC;EAC5B,uBAAuB,GAAG,gBAAgB,cAAc,GAAG;EAC3D,0BAA0B,GAAG,CAAC,gBAAgB;EAC9C,yBAAyB,KAAK;CAClC;CAKA,MAAM,WAAW,mBAAmB,CAAC,aAAa,gBAAgB;CAIlE,OACI,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;EACe;EACX,eAAa;EACb,OAAO;YAEP,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;GACI,aAVK,uBAAuB;GAW5B,cAAY;GACZ,aAAU;GACV,iBAAe,kBAAkB,MAAM,KAAA;GACvC,iBAAe,kBAAkB,IAAI,KAAA;GACrC,iBAdS,kBAAkB,wBAAwB,KAAA;GAenD,WACI,sBACM,UAAU,UAAU,aAAa,UAAU,mCAC3C,UAAU,UAAU,aAAa,UAAU;GAErD,MAAK;GACL,QAAQ;GACR,MAAM;GACN,SAAS;GACT,OAAO;GACP,OAAM;aAjBV;IAoBI,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACI,GAAI;KACJ,QAAQ;KACR,iBAAA;IACH,CAAA;IAGA,gBACG,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACI,GAAI;KACJ,WAAU;KACV,QAAQ;KACR,iBAAiB;KACjB,kBAAkB;KAClB,eAAc;IACjB,CAAA;IAIJ,4BAA4B,2BAA2B,aACpD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACI,GAAI;KACJ,WAAU;KACV,QAAQ;KACR,iBAAiB,GAAG,gBAAA,IAAiC,GAAG,gBAAiB;KACzE,eAAc;IACjB,CAAA;IAIJ,4BAA4B,2BAA2B,UACpD,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACI,GAAI;KACJ,WAAU;KACV,QAAQ;KACR,eAAc;IACjB,CAAA;IAIJ,mBACG,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACI,GAAI;KACJ,WAAU;KACV,QAAQ;KACR,iBAAiB;KACjB,kBAAkB;KAClB,eAAc;IACjB,CAAA;IAIJ,CAAC,uBACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAD;KACI,QAAA;KACA,OAAA;KACA,GAAG;KACH,GAAG;eAEH,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAU;gBACV,cACG,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;OACI,MAAK;OACL,QAAA;OACA,SAAS;OACT,OAAA;OACA,OAAM;iBAEN,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;QACI,WAAU;QACV,GAAE;QACF,MAAM;OACT,CAAA;MACA,CAAA;KAER,CAAA;IACM,CAAA;IAIlB,uBACG,iBAAA,GAAA,kBAAA,IAAA,CAAC,iBAAD;KACI,QAAA;KACA,OAAA;KACA,GAAG;KACH,GAAG;eAEH,iBAAA,GAAA,kBAAA,IAAA,CAAC,OAAD;MAAK,WAAU;gBACX,iBAAA,GAAA,kBAAA,IAAA,CAACC,oBAAAA,aAAD;OACI,OAAM;OACN,MAAK;OACL,OAAM;MACT,CAAA;KACA,CAAA;IACM,CAAA;GAElB;;CACH,CAAA;AAEd;AAEA,eAAe,cAAc"}
|
|
@@ -172,7 +172,7 @@ const ProgressCircle = ({ "aria-label": ariaLabel = "Progress Circle", centerIco
|
|
|
172
172
|
x: iconViewBoxOffset,
|
|
173
173
|
y: iconViewBoxOffset,
|
|
174
174
|
children: /* @__PURE__ */ jsx("div", {
|
|
175
|
-
className: "flex h-full w-full
|
|
175
|
+
className: "animate-progress-icon-fade-in flex h-full w-full items-center justify-center",
|
|
176
176
|
children: /* @__PURE__ */ jsx(CheckCircle, {
|
|
177
177
|
color: "success",
|
|
178
178
|
size: "md",
|
|
@@ -188,4 +188,4 @@ ProgressCircle.displayName = "ProgressCircle";
|
|
|
188
188
|
//#endregion
|
|
189
189
|
export { ProgressCircle as t };
|
|
190
190
|
|
|
191
|
-
//# sourceMappingURL=ProgressCircle-
|
|
191
|
+
//# sourceMappingURL=ProgressCircle-zSai1HTT.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProgressCircle-ae8cvZhe.mjs","names":[],"sources":["../src/ProgressCircle/hooks/useProgressStatusTransitions.ts","../src/ProgressCircle/utils/progressCircle.constants.ts","../src/ProgressCircle/ProgressCircle.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\ntype ProgressCircleStatus = 'pending' | 'progressing' | 'complete' | 'indeterminate';\n\n/**\n * Manages the animation state for the ProgressCircle component.\n *\n * Handles two animation concerns:\n * 1. `animateToSolidCircle` - Controls the transition from dashed to solid circle\n * 2. `isShowingCompletion` - Controls whether to show the completion checkmark\n *\n * @param status - The current status of the progress circle\n * @returns Animation state flags for the component\n */\nexport const useProgressStatusTransitions = (status: ProgressCircleStatus) => {\n const isComplete = status === 'complete';\n const isProgressing = status === 'progressing';\n const isIndeterminate = status === 'indeterminate';\n\n // State to control animation trigger\n const [animateToSolidCircle, setAnimateToSolidCircle] = useState(false);\n // State to track completion animation\n const [isShowingCompletion, setIsShowingCompletion] = useState(false);\n\n // Trigger completion animation when status changes to/from 'complete'\n useEffect(() => {\n setIsShowingCompletion(isComplete);\n }, [isComplete]);\n\n // Trigger animation when status changes to progressing, complete, or indeterminate\n useEffect(() => {\n if (isProgressing || isComplete || isIndeterminate) {\n // Small delay to ensure element is mounted before animating\n const timer = setTimeout(() => {\n setAnimateToSolidCircle(true);\n }, 10);\n\n return () => {\n clearTimeout(timer);\n };\n }\n\n setAnimateToSolidCircle(false);\n\n return undefined;\n }, [isComplete, isIndeterminate, isProgressing]);\n\n return { animateToSolidCircle, isShowingCompletion };\n};\n","// SVG dimensions and styling constants\nexport const VIEWBOX_SIZE = 34;\nexport const CIRCLE_RADIUS = 11.25;\nexport const CIRCLE_CENTER = 17;\nexport const STROKE_WIDTH = 1.5;\nexport const ICON_CONTAINER_SIZE = 34;\nexport const DASHED_PATTERN = '4 4';\n\n// Outer circle sizes matching IconButton\nexport const progressCircleOuterSizes = {\n lg: 54,\n md: 42,\n sm: 34,\n} as const;\n\n// Animation calculation constants\nexport const WAVE_ARC_SIZE = 0.75;\nexport const WAVE_OFFSET = 0.125;\nexport const SPINNER_ARC_SIZE = 0.25;\n\n// Base props for all circle SVG elements (derived from constants above)\nexport const circleBaseProps = {\n cx: CIRCLE_CENTER,\n cy: CIRCLE_CENTER,\n r: CIRCLE_RADIUS,\n strokeWidth: STROKE_WIDTH,\n} as const;\n","import { colorIconDisabled, colorIconSecondary, colorIconSuccess } from '@evolve.ui/theme-system';\nimport { ReactNode } from 'react';\n\nimport { CheckCircle } from '../Icons/generatedIcons/CheckCircle';\nimport { getColor, IconProps } from '../Icons/IconBase';\nimport { useProgressStatusTransitions } from './hooks/useProgressStatusTransitions';\nimport {\n CIRCLE_RADIUS,\n circleBaseProps,\n DASHED_PATTERN,\n ICON_CONTAINER_SIZE,\n progressCircleOuterSizes,\n SPINNER_ARC_SIZE,\n VIEWBOX_SIZE,\n WAVE_ARC_SIZE,\n WAVE_OFFSET,\n} from './utils/progressCircle.constants';\n\ntype ProgressCircleProps = {\n 'aria-label'?: string;\n centerIcon?: ReactNode;\n className?: string;\n color?: Exclude<IconProps['color'], 'disabled' | 'inherit'>;\n 'data-testid'?: string;\n indeterminateAnimation?: 'spinner' | 'wave';\n /**\n * Progress value from 0-100. Only used when status is 'progressing'.\n * If not provided while status is 'progressing', an indeterminate animation will be shown instead.\n */\n progress?: number;\n size?: keyof typeof progressCircleOuterSizes;\n /**\n * Current status of the operation:\n * - 'pending': Shows dashed circle with gray arrow (not yet started)\n * - 'progressing': Shows progress animation. If `progress` is not provided, automatically shows indeterminate animation\n * - 'complete': Shows full circle with success checkmark animation\n * - 'indeterminate': Always shows indeterminate animation, even if progress value is provided (use for explicit indeterminate state)\n */\n status?: 'pending' | 'progressing' | 'complete' | 'indeterminate';\n};\n\nexport const ProgressCircle = ({\n 'aria-label': ariaLabel = 'Progress Circle',\n centerIcon,\n className,\n color = 'secondary',\n 'data-testid': dataTestId,\n indeterminateAnimation = 'spinner',\n progress,\n size = 'md',\n status = 'pending',\n}: ProgressCircleProps) => {\n const outerSize = progressCircleOuterSizes[size];\n\n const strokeColor = getColor(color) ?? `rgb(var(${colorIconSecondary}))`;\n const grayColor = `rgb(var(${colorIconDisabled}))`;\n const successColor = `rgb(var(${colorIconSuccess}))`;\n\n // Status flags for cleaner conditionals\n const isPending = status === 'pending';\n const isProgressing = status === 'progressing';\n const isComplete = status === 'complete';\n const isIndeterminate = status === 'indeterminate';\n\n // When status is complete, always use success color for the progress circle\n const progressCircleColor = isComplete ? successColor : strokeColor;\n\n // Arrow color changes based on status: gray when pending, colored otherwise\n const arrowColor = isPending ? grayColor : strokeColor;\n\n // Calculate circle circumference for progress animation\n const circumference = 2 * Math.PI * CIRCLE_RADIUS;\n\n // Calculate foreignObject dimensions - centered in viewBox\n const iconViewBoxOffset = (VIEWBOX_SIZE - ICON_CONTAINER_SIZE) / 2;\n\n // Transition state from custom hook\n const { animateToSolidCircle, isShowingCompletion } = useProgressStatusTransitions(status);\n\n // Show fill and progress circles only when progressing or complete\n const showProgressCircles = isProgressing || isComplete;\n\n // Auto-set progress to 100% when status is complete\n // Default to 0 if progress is undefined (though this should only be used when showProgressArc is true)\n const resolvedProgressValue = isComplete ? 100 : (progress ?? 0);\n\n // Gray fill circle: animates from circumference to 0 when animateToSolidCircle is true\n const grayFillOffset = animateToSolidCircle ? 0 : circumference;\n\n // Colored progress circle: tied to effective progress value (100% when complete)\n const progressOffset = circumference - (resolvedProgressValue / 100) * circumference;\n\n // Conditional rendering logic for indeterminate vs progress modes\n // Show indeterminate if explicitly set OR if progressing without progress value\n const hasProgressValue = typeof progress === 'number';\n const isIndeterminateMode = isIndeterminate || (isProgressing && !hasProgressValue);\n const showIndeterminateSpinner = isIndeterminateMode && animateToSolidCircle;\n const showProgressArc = !isIndeterminateMode && showProgressCircles;\n const showGrayFill = isIndeterminateMode || showProgressCircles;\n\n // CSS custom properties for the wave animation keyframes (defined in plugin.ts).\n // These must be inline styles because the values are calculated from the\n // circle's circumference, which is derived from CIRCLE_RADIUS based off chosen size (sm, md, lg) at runtime.\n const waveAnimationStyles = {\n '--progress-wave-end': `1 ${circumference}`,\n '--progress-wave-full': `${-circumference}`,\n '--progress-wave-mid': `${circumference * WAVE_ARC_SIZE} ${circumference}`,\n '--progress-wave-offset': `${-circumference * WAVE_OFFSET}`,\n '--progress-wave-start': `1 ${circumference}`,\n } as React.CSSProperties;\n\n // Determine ARIA attributes based on whether we're showing determinate or indeterminate\n // Show progressbar role only when actively progressing with progress value\n // Complete status should be 'status' role, not 'progressbar'\n const ariaRole = showProgressArc && !isComplete ? 'progressbar' : 'status';\n const ariaBusy = isIndeterminateMode || isProgressing;\n const ariaValueNow = showProgressArc ? resolvedProgressValue : undefined;\n\n return (\n <span\n className={className}\n data-testid={dataTestId}\n style={waveAnimationStyles}\n >\n <svg\n aria-busy={ariaBusy}\n aria-label={ariaLabel}\n aria-live=\"polite\"\n aria-valuemax={showProgressArc ? 100 : undefined}\n aria-valuemin={showProgressArc ? 0 : undefined}\n aria-valuenow={ariaValueNow}\n className={\n isShowingCompletion\n ? `min-h-[${outerSize}px] min-w-[${outerSize}px] animate-progress-completion`\n : `min-h-[${outerSize}px] min-w-[${outerSize}px]`\n }\n fill=\"none\"\n height={outerSize}\n role={ariaRole}\n viewBox={`0 0 ${VIEWBOX_SIZE} ${VIEWBOX_SIZE}`}\n width={outerSize}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {/* Dashed background circle */}\n <circle\n {...circleBaseProps}\n stroke={grayColor}\n strokeDasharray={DASHED_PATTERN}\n />\n\n {/* Gray fill circle - animates 0→100% in 300ms when status is progressing or indeterminate */}\n {showGrayFill && (\n <circle\n {...circleBaseProps}\n className=\"origin-center -rotate-90 transition-[stroke-dashoffset] duration-300\"\n stroke={grayColor}\n strokeDasharray={circumference}\n strokeDashoffset={grayFillOffset}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Indeterminate spinner - 1/4 circle arc that rotates */}\n {showIndeterminateSpinner && indeterminateAnimation === 'spinner' && (\n <circle\n {...circleBaseProps}\n className=\"origin-center animate-spin\"\n stroke={strokeColor}\n strokeDasharray={`${circumference * SPINNER_ARC_SIZE} ${circumference * (1 - SPINNER_ARC_SIZE)}`}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Indeterminate wave - Google Loader style animation */}\n {showIndeterminateSpinner && indeterminateAnimation === 'wave' && (\n <circle\n {...circleBaseProps}\n className=\"origin-center animate-progress-wave\"\n stroke={strokeColor}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Colored progress circle - tied to progress value (determinate mode) */}\n {showProgressArc && (\n <circle\n {...circleBaseProps}\n className=\"origin-center -rotate-90 transition-[stroke-dashoffset_0.5s_ease-in-out_0.3s,stroke_0.3s_ease-in-out]\"\n stroke={progressCircleColor}\n strokeDasharray={circumference}\n strokeDashoffset={progressOffset}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Center icon content */}\n {!isShowingCompletion && (\n <foreignObject\n height={ICON_CONTAINER_SIZE}\n width={ICON_CONTAINER_SIZE}\n x={iconViewBoxOffset}\n y={iconViewBoxOffset}\n >\n <div className=\"flex h-full w-full items-center justify-center\">\n {centerIcon || (\n <svg\n fill=\"none\"\n height={ICON_CONTAINER_SIZE}\n viewBox={`0 0 ${VIEWBOX_SIZE} ${VIEWBOX_SIZE}`}\n width={ICON_CONTAINER_SIZE}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n className=\"transition-[fill_0.3s_ease-in-out]\"\n d=\"M21.4015 16.5893C21.3406 16.6504 21.2681 16.699 21.1883 16.7321C21.1086 16.7652 21.0231 16.7823 20.9367 16.7823C20.8503 16.7823 20.7648 16.7652 20.685 16.7321C20.6053 16.699 20.5328 16.6504 20.4718 16.5893L17.656 13.7734V21.8125C17.656 21.9865 17.5868 22.1534 17.4638 22.2765C17.3407 22.3996 17.1738 22.4687 16.9997 22.4687C16.8257 22.4687 16.6588 22.3996 16.5357 22.2765C16.4126 22.1534 16.3435 21.9865 16.3435 21.8125V13.7734L13.5265 16.5893C13.4032 16.7125 13.236 16.7818 13.0617 16.7818C12.8873 16.7818 12.7201 16.7125 12.5968 16.5893C12.4736 16.466 12.4043 16.2988 12.4043 16.1244C12.4043 15.9501 12.4736 15.7829 12.5968 15.6596L16.5343 11.7221C16.5953 11.6609 16.6678 11.6123 16.7475 11.5792C16.8273 11.5461 16.9128 11.5291 16.9992 11.5291C17.0856 11.5291 17.1711 11.5461 17.2508 11.5792C17.3306 11.6123 17.4031 11.6609 17.464 11.7221L21.4015 15.6596C21.4627 15.7205 21.5113 15.793 21.5444 15.8728C21.5775 15.9525 21.5945 16.038 21.5945 16.1244C21.5945 16.2108 21.5775 16.2963 21.5444 16.3761C21.5113 16.4558 21.4627 16.5283 21.4015 16.5893Z\"\n fill={arrowColor}\n />\n </svg>\n )}\n </div>\n </foreignObject>\n )}\n\n {/* Completion CheckCircle */}\n {isShowingCompletion && (\n <foreignObject\n height={ICON_CONTAINER_SIZE}\n width={ICON_CONTAINER_SIZE}\n x={iconViewBoxOffset}\n y={iconViewBoxOffset}\n >\n <div className=\"flex h-full w-full animate-progress-icon-fade-in items-center justify-center\">\n <CheckCircle\n color=\"success\"\n size=\"md\"\n style=\"fill\"\n />\n </div>\n </foreignObject>\n )}\n </svg>\n </span>\n );\n};\n\nProgressCircle.displayName = 'ProgressCircle';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ProgressCircle-zSai1HTT.mjs","names":[],"sources":["../src/ProgressCircle/hooks/useProgressStatusTransitions.ts","../src/ProgressCircle/utils/progressCircle.constants.ts","../src/ProgressCircle/ProgressCircle.tsx"],"sourcesContent":["import { useEffect, useState } from 'react';\n\ntype ProgressCircleStatus = 'pending' | 'progressing' | 'complete' | 'indeterminate';\n\n/**\n * Manages the animation state for the ProgressCircle component.\n *\n * Handles two animation concerns:\n * 1. `animateToSolidCircle` - Controls the transition from dashed to solid circle\n * 2. `isShowingCompletion` - Controls whether to show the completion checkmark\n *\n * @param status - The current status of the progress circle\n * @returns Animation state flags for the component\n */\nexport const useProgressStatusTransitions = (status: ProgressCircleStatus) => {\n const isComplete = status === 'complete';\n const isProgressing = status === 'progressing';\n const isIndeterminate = status === 'indeterminate';\n\n // State to control animation trigger\n const [animateToSolidCircle, setAnimateToSolidCircle] = useState(false);\n // State to track completion animation\n const [isShowingCompletion, setIsShowingCompletion] = useState(false);\n\n // Trigger completion animation when status changes to/from 'complete'\n useEffect(() => {\n setIsShowingCompletion(isComplete);\n }, [isComplete]);\n\n // Trigger animation when status changes to progressing, complete, or indeterminate\n useEffect(() => {\n if (isProgressing || isComplete || isIndeterminate) {\n // Small delay to ensure element is mounted before animating\n const timer = setTimeout(() => {\n setAnimateToSolidCircle(true);\n }, 10);\n\n return () => {\n clearTimeout(timer);\n };\n }\n\n setAnimateToSolidCircle(false);\n\n return undefined;\n }, [isComplete, isIndeterminate, isProgressing]);\n\n return { animateToSolidCircle, isShowingCompletion };\n};\n","// SVG dimensions and styling constants\nexport const VIEWBOX_SIZE = 34;\nexport const CIRCLE_RADIUS = 11.25;\nexport const CIRCLE_CENTER = 17;\nexport const STROKE_WIDTH = 1.5;\nexport const ICON_CONTAINER_SIZE = 34;\nexport const DASHED_PATTERN = '4 4';\n\n// Outer circle sizes matching IconButton\nexport const progressCircleOuterSizes = {\n lg: 54,\n md: 42,\n sm: 34,\n} as const;\n\n// Animation calculation constants\nexport const WAVE_ARC_SIZE = 0.75;\nexport const WAVE_OFFSET = 0.125;\nexport const SPINNER_ARC_SIZE = 0.25;\n\n// Base props for all circle SVG elements (derived from constants above)\nexport const circleBaseProps = {\n cx: CIRCLE_CENTER,\n cy: CIRCLE_CENTER,\n r: CIRCLE_RADIUS,\n strokeWidth: STROKE_WIDTH,\n} as const;\n","import { colorIconDisabled, colorIconSecondary, colorIconSuccess } from '@evolve.ui/theme-system';\nimport { ReactNode } from 'react';\n\nimport { CheckCircle } from '../Icons/generatedIcons/CheckCircle';\nimport { getColor, IconProps } from '../Icons/IconBase';\nimport { useProgressStatusTransitions } from './hooks/useProgressStatusTransitions';\nimport {\n CIRCLE_RADIUS,\n circleBaseProps,\n DASHED_PATTERN,\n ICON_CONTAINER_SIZE,\n progressCircleOuterSizes,\n SPINNER_ARC_SIZE,\n VIEWBOX_SIZE,\n WAVE_ARC_SIZE,\n WAVE_OFFSET,\n} from './utils/progressCircle.constants';\n\ntype ProgressCircleProps = {\n 'aria-label'?: string;\n centerIcon?: ReactNode;\n className?: string;\n color?: Exclude<IconProps['color'], 'disabled' | 'inherit'>;\n 'data-testid'?: string;\n indeterminateAnimation?: 'spinner' | 'wave';\n /**\n * Progress value from 0-100. Only used when status is 'progressing'.\n * If not provided while status is 'progressing', an indeterminate animation will be shown instead.\n */\n progress?: number;\n size?: keyof typeof progressCircleOuterSizes;\n /**\n * Current status of the operation:\n * - 'pending': Shows dashed circle with gray arrow (not yet started)\n * - 'progressing': Shows progress animation. If `progress` is not provided, automatically shows indeterminate animation\n * - 'complete': Shows full circle with success checkmark animation\n * - 'indeterminate': Always shows indeterminate animation, even if progress value is provided (use for explicit indeterminate state)\n */\n status?: 'pending' | 'progressing' | 'complete' | 'indeterminate';\n};\n\nexport const ProgressCircle = ({\n 'aria-label': ariaLabel = 'Progress Circle',\n centerIcon,\n className,\n color = 'secondary',\n 'data-testid': dataTestId,\n indeterminateAnimation = 'spinner',\n progress,\n size = 'md',\n status = 'pending',\n}: ProgressCircleProps) => {\n const outerSize = progressCircleOuterSizes[size];\n\n const strokeColor = getColor(color) ?? `rgb(var(${colorIconSecondary}))`;\n const grayColor = `rgb(var(${colorIconDisabled}))`;\n const successColor = `rgb(var(${colorIconSuccess}))`;\n\n // Status flags for cleaner conditionals\n const isPending = status === 'pending';\n const isProgressing = status === 'progressing';\n const isComplete = status === 'complete';\n const isIndeterminate = status === 'indeterminate';\n\n // When status is complete, always use success color for the progress circle\n const progressCircleColor = isComplete ? successColor : strokeColor;\n\n // Arrow color changes based on status: gray when pending, colored otherwise\n const arrowColor = isPending ? grayColor : strokeColor;\n\n // Calculate circle circumference for progress animation\n const circumference = 2 * Math.PI * CIRCLE_RADIUS;\n\n // Calculate foreignObject dimensions - centered in viewBox\n const iconViewBoxOffset = (VIEWBOX_SIZE - ICON_CONTAINER_SIZE) / 2;\n\n // Transition state from custom hook\n const { animateToSolidCircle, isShowingCompletion } = useProgressStatusTransitions(status);\n\n // Show fill and progress circles only when progressing or complete\n const showProgressCircles = isProgressing || isComplete;\n\n // Auto-set progress to 100% when status is complete\n // Default to 0 if progress is undefined (though this should only be used when showProgressArc is true)\n const resolvedProgressValue = isComplete ? 100 : (progress ?? 0);\n\n // Gray fill circle: animates from circumference to 0 when animateToSolidCircle is true\n const grayFillOffset = animateToSolidCircle ? 0 : circumference;\n\n // Colored progress circle: tied to effective progress value (100% when complete)\n const progressOffset = circumference - (resolvedProgressValue / 100) * circumference;\n\n // Conditional rendering logic for indeterminate vs progress modes\n // Show indeterminate if explicitly set OR if progressing without progress value\n const hasProgressValue = typeof progress === 'number';\n const isIndeterminateMode = isIndeterminate || (isProgressing && !hasProgressValue);\n const showIndeterminateSpinner = isIndeterminateMode && animateToSolidCircle;\n const showProgressArc = !isIndeterminateMode && showProgressCircles;\n const showGrayFill = isIndeterminateMode || showProgressCircles;\n\n // CSS custom properties for the wave animation keyframes (defined in plugin.ts).\n // These must be inline styles because the values are calculated from the\n // circle's circumference, which is derived from CIRCLE_RADIUS based off chosen size (sm, md, lg) at runtime.\n const waveAnimationStyles = {\n '--progress-wave-end': `1 ${circumference}`,\n '--progress-wave-full': `${-circumference}`,\n '--progress-wave-mid': `${circumference * WAVE_ARC_SIZE} ${circumference}`,\n '--progress-wave-offset': `${-circumference * WAVE_OFFSET}`,\n '--progress-wave-start': `1 ${circumference}`,\n } as React.CSSProperties;\n\n // Determine ARIA attributes based on whether we're showing determinate or indeterminate\n // Show progressbar role only when actively progressing with progress value\n // Complete status should be 'status' role, not 'progressbar'\n const ariaRole = showProgressArc && !isComplete ? 'progressbar' : 'status';\n const ariaBusy = isIndeterminateMode || isProgressing;\n const ariaValueNow = showProgressArc ? resolvedProgressValue : undefined;\n\n return (\n <span\n className={className}\n data-testid={dataTestId}\n style={waveAnimationStyles}\n >\n <svg\n aria-busy={ariaBusy}\n aria-label={ariaLabel}\n aria-live=\"polite\"\n aria-valuemax={showProgressArc ? 100 : undefined}\n aria-valuemin={showProgressArc ? 0 : undefined}\n aria-valuenow={ariaValueNow}\n className={\n isShowingCompletion\n ? `min-h-[${outerSize}px] min-w-[${outerSize}px] animate-progress-completion`\n : `min-h-[${outerSize}px] min-w-[${outerSize}px]`\n }\n fill=\"none\"\n height={outerSize}\n role={ariaRole}\n viewBox={`0 0 ${VIEWBOX_SIZE} ${VIEWBOX_SIZE}`}\n width={outerSize}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n {/* Dashed background circle */}\n <circle\n {...circleBaseProps}\n stroke={grayColor}\n strokeDasharray={DASHED_PATTERN}\n />\n\n {/* Gray fill circle - animates 0→100% in 300ms when status is progressing or indeterminate */}\n {showGrayFill && (\n <circle\n {...circleBaseProps}\n className=\"origin-center -rotate-90 transition-[stroke-dashoffset] duration-300\"\n stroke={grayColor}\n strokeDasharray={circumference}\n strokeDashoffset={grayFillOffset}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Indeterminate spinner - 1/4 circle arc that rotates */}\n {showIndeterminateSpinner && indeterminateAnimation === 'spinner' && (\n <circle\n {...circleBaseProps}\n className=\"origin-center animate-spin\"\n stroke={strokeColor}\n strokeDasharray={`${circumference * SPINNER_ARC_SIZE} ${circumference * (1 - SPINNER_ARC_SIZE)}`}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Indeterminate wave - Google Loader style animation */}\n {showIndeterminateSpinner && indeterminateAnimation === 'wave' && (\n <circle\n {...circleBaseProps}\n className=\"origin-center animate-progress-wave\"\n stroke={strokeColor}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Colored progress circle - tied to progress value (determinate mode) */}\n {showProgressArc && (\n <circle\n {...circleBaseProps}\n className=\"origin-center -rotate-90 transition-[stroke-dashoffset_0.5s_ease-in-out_0.3s,stroke_0.3s_ease-in-out]\"\n stroke={progressCircleColor}\n strokeDasharray={circumference}\n strokeDashoffset={progressOffset}\n strokeLinecap=\"round\"\n />\n )}\n\n {/* Center icon content */}\n {!isShowingCompletion && (\n <foreignObject\n height={ICON_CONTAINER_SIZE}\n width={ICON_CONTAINER_SIZE}\n x={iconViewBoxOffset}\n y={iconViewBoxOffset}\n >\n <div className=\"flex h-full w-full items-center justify-center\">\n {centerIcon || (\n <svg\n fill=\"none\"\n height={ICON_CONTAINER_SIZE}\n viewBox={`0 0 ${VIEWBOX_SIZE} ${VIEWBOX_SIZE}`}\n width={ICON_CONTAINER_SIZE}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n className=\"transition-[fill_0.3s_ease-in-out]\"\n d=\"M21.4015 16.5893C21.3406 16.6504 21.2681 16.699 21.1883 16.7321C21.1086 16.7652 21.0231 16.7823 20.9367 16.7823C20.8503 16.7823 20.7648 16.7652 20.685 16.7321C20.6053 16.699 20.5328 16.6504 20.4718 16.5893L17.656 13.7734V21.8125C17.656 21.9865 17.5868 22.1534 17.4638 22.2765C17.3407 22.3996 17.1738 22.4687 16.9997 22.4687C16.8257 22.4687 16.6588 22.3996 16.5357 22.2765C16.4126 22.1534 16.3435 21.9865 16.3435 21.8125V13.7734L13.5265 16.5893C13.4032 16.7125 13.236 16.7818 13.0617 16.7818C12.8873 16.7818 12.7201 16.7125 12.5968 16.5893C12.4736 16.466 12.4043 16.2988 12.4043 16.1244C12.4043 15.9501 12.4736 15.7829 12.5968 15.6596L16.5343 11.7221C16.5953 11.6609 16.6678 11.6123 16.7475 11.5792C16.8273 11.5461 16.9128 11.5291 16.9992 11.5291C17.0856 11.5291 17.1711 11.5461 17.2508 11.5792C17.3306 11.6123 17.4031 11.6609 17.464 11.7221L21.4015 15.6596C21.4627 15.7205 21.5113 15.793 21.5444 15.8728C21.5775 15.9525 21.5945 16.038 21.5945 16.1244C21.5945 16.2108 21.5775 16.2963 21.5444 16.3761C21.5113 16.4558 21.4627 16.5283 21.4015 16.5893Z\"\n fill={arrowColor}\n />\n </svg>\n )}\n </div>\n </foreignObject>\n )}\n\n {/* Completion CheckCircle */}\n {isShowingCompletion && (\n <foreignObject\n height={ICON_CONTAINER_SIZE}\n width={ICON_CONTAINER_SIZE}\n x={iconViewBoxOffset}\n y={iconViewBoxOffset}\n >\n <div className=\"animate-progress-icon-fade-in flex h-full w-full items-center justify-center\">\n <CheckCircle\n color=\"success\"\n size=\"md\"\n style=\"fill\"\n />\n </div>\n </foreignObject>\n )}\n </svg>\n </span>\n );\n};\n\nProgressCircle.displayName = 'ProgressCircle';\n"],"mappings":";;;;;;;;;;;;;;;;AAcA,MAAa,gCAAgC,WAAiC;CAC1E,MAAM,aAAa,WAAW;CAC9B,MAAM,gBAAgB,WAAW;CACjC,MAAM,kBAAkB,WAAW;CAGnC,MAAM,CAAC,sBAAsB,2BAA2B,SAAS,KAAK;CAEtE,MAAM,CAAC,qBAAqB,0BAA0B,SAAS,KAAK;CAGpE,gBAAgB;EACZ,uBAAuB,UAAU;CACrC,GAAG,CAAC,UAAU,CAAC;CAGf,gBAAgB;EACZ,IAAI,iBAAiB,cAAc,iBAAiB;GAEhD,MAAM,QAAQ,iBAAiB;IAC3B,wBAAwB,IAAI;GAChC,GAAG,EAAE;GAEL,aAAa;IACT,aAAa,KAAK;GACtB;EACJ;EAEA,wBAAwB,KAAK;CAGjC,GAAG;EAAC;EAAY;EAAiB;CAAa,CAAC;CAE/C,OAAO;EAAE;EAAsB;CAAoB;AACvD;;;AC9CA,MAAa,gBAAgB;AAE7B,MAAa,eAAe;AAK5B,MAAa,2BAA2B;CACpC,IAAI;CACJ,IAAI;CACJ,IAAI;AACR;AAGA,MAAa,gBAAgB;AAC7B,MAAa,cAAc;AAI3B,MAAa,kBAAkB;CAC3B,IAAA;CACA,IAAA;CACA,GAAG;CACH,aAAa;AACjB;;;ACeA,MAAa,kBAAkB,EAC3B,cAAc,YAAY,mBAC1B,YACA,WACA,QAAQ,aACR,eAAe,YACf,yBAAyB,WACzB,UACA,OAAO,MACP,SAAS,gBACc;CACvB,MAAM,YAAY,yBAAyB;CAE3C,MAAM,cAAc,SAAS,KAAK,KAAK,WAAW,mBAAmB;CACrE,MAAM,YAAY,WAAW,kBAAkB;CAC/C,MAAM,eAAe,WAAW,iBAAiB;CAGjD,MAAM,YAAY,WAAW;CAC7B,MAAM,gBAAgB,WAAW;CACjC,MAAM,aAAa,WAAW;CAC9B,MAAM,kBAAkB,WAAW;CAGnC,MAAM,sBAAsB,aAAa,eAAe;CAGxD,MAAM,aAAa,YAAY,YAAY;CAG3C,MAAM,gBAAgB,IAAI,KAAK,KAAK;CAGpC,MAAM,oBAAA,IAA2D;CAGjE,MAAM,EAAE,sBAAsB,wBAAwB,6BAA6B,MAAM;CAGzF,MAAM,sBAAsB,iBAAiB;CAI7C,MAAM,wBAAwB,aAAa,MAAO,YAAY;CAG9D,MAAM,iBAAiB,uBAAuB,IAAI;CAGlD,MAAM,iBAAiB,gBAAiB,wBAAwB,MAAO;CAKvE,MAAM,sBAAsB,mBAAoB,iBAAiB,EADxC,OAAO,aAAa;CAE7C,MAAM,2BAA2B,uBAAuB;CACxD,MAAM,kBAAkB,CAAC,uBAAuB;CAChD,MAAM,eAAe,uBAAuB;CAK5C,MAAM,sBAAsB;EACxB,uBAAuB,KAAK;EAC5B,wBAAwB,GAAG,CAAC;EAC5B,uBAAuB,GAAG,gBAAgB,cAAc,GAAG;EAC3D,0BAA0B,GAAG,CAAC,gBAAgB;EAC9C,yBAAyB,KAAK;CAClC;CAKA,MAAM,WAAW,mBAAmB,CAAC,aAAa,gBAAgB;CAIlE,OACI,oBAAC,QAAD;EACe;EACX,eAAa;EACb,OAAO;YAEP,qBAAC,OAAD;GACI,aAVK,uBAAuB;GAW5B,cAAY;GACZ,aAAU;GACV,iBAAe,kBAAkB,MAAM,KAAA;GACvC,iBAAe,kBAAkB,IAAI,KAAA;GACrC,iBAdS,kBAAkB,wBAAwB,KAAA;GAenD,WACI,sBACM,UAAU,UAAU,aAAa,UAAU,mCAC3C,UAAU,UAAU,aAAa,UAAU;GAErD,MAAK;GACL,QAAQ;GACR,MAAM;GACN,SAAS;GACT,OAAO;GACP,OAAM;aAjBV;IAoBI,oBAAC,UAAD;KACI,GAAI;KACJ,QAAQ;KACR,iBAAA;IACH,CAAA;IAGA,gBACG,oBAAC,UAAD;KACI,GAAI;KACJ,WAAU;KACV,QAAQ;KACR,iBAAiB;KACjB,kBAAkB;KAClB,eAAc;IACjB,CAAA;IAIJ,4BAA4B,2BAA2B,aACpD,oBAAC,UAAD;KACI,GAAI;KACJ,WAAU;KACV,QAAQ;KACR,iBAAiB,GAAG,gBAAA,IAAiC,GAAG,gBAAiB;KACzE,eAAc;IACjB,CAAA;IAIJ,4BAA4B,2BAA2B,UACpD,oBAAC,UAAD;KACI,GAAI;KACJ,WAAU;KACV,QAAQ;KACR,eAAc;IACjB,CAAA;IAIJ,mBACG,oBAAC,UAAD;KACI,GAAI;KACJ,WAAU;KACV,QAAQ;KACR,iBAAiB;KACjB,kBAAkB;KAClB,eAAc;IACjB,CAAA;IAIJ,CAAC,uBACE,oBAAC,iBAAD;KACI,QAAA;KACA,OAAA;KACA,GAAG;KACH,GAAG;eAEH,oBAAC,OAAD;MAAK,WAAU;gBACV,cACG,oBAAC,OAAD;OACI,MAAK;OACL,QAAA;OACA,SAAS;OACT,OAAA;OACA,OAAM;iBAEN,oBAAC,QAAD;QACI,WAAU;QACV,GAAE;QACF,MAAM;OACT,CAAA;MACA,CAAA;KAER,CAAA;IACM,CAAA;IAIlB,uBACG,oBAAC,iBAAD;KACI,QAAA;KACA,OAAA;KACA,GAAG;KACH,GAAG;eAEH,oBAAC,OAAD;MAAK,WAAU;gBACX,oBAAC,aAAD;OACI,OAAM;OACN,MAAK;OACL,OAAM;MACT,CAAA;KACA,CAAA;IACM,CAAA;GAElB;;CACH,CAAA;AAEd;AAEA,eAAe,cAAc"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchInput-DYIPC8Cd.d.cts","names":[],"sources":["../src/SearchInput/SearchInput.tsx"],"mappings":";;;;KAQK,KAAA;;AAH0C;;;;EAS3C,mBAAA;EACA,SAAA;EA2CW;;;EAAA,CAvCV,aAAA;EAJD;;;EAQA,QAAA;EASA;;;EALA,QAAA;EAeA;;;;EAVA,YAAA,GAAe,SAAA;EA0BM;;;EAtBrB,SAAA,GAAY,UAAA;EAuCZ;;;;;EAjCA,EAAA;EAmDA;;;;AAUK;EAvDL,YAAA;
|
|
1
|
+
{"version":3,"file":"SearchInput-DYIPC8Cd.d.cts","names":[],"sources":["../src/SearchInput/SearchInput.tsx"],"mappings":";;;;KAQK,KAAA;;AAH0C;;;;EAS3C,mBAAA;EACA,SAAA;EA2CW;;;EAAA,CAvCV,aAAA;EAJD;;;EAQA,QAAA;EASA;;;EALA,QAAA;EAeA;;;;EAVA,YAAA,GAAe,SAAA;EA0BM;;;EAtBrB,SAAA,GAAY,UAAA;EAuCZ;;;;;EAjCA,EAAA;EAmDA;;;;AAUK;EAvDL,YAAA;EA4LH;;;;;EAtLG,kBAAA;EAoDwB;;;EAhDxB,QAAA,GAAW,SAAA,CAAU,gBAAA;EAgDG;;;;EA3CxB,SAAA;EA2CwB;;;EAvCxB,MAAA;EAuCwB;;;EAnCxB,OAAA;EAyDD;;;EArDC,OAAA;EA+BwB;;;EA3BxB,QAAA,IAAY,YAAA;EA2BY;;;EAvBxB,YAAA,IAAgB,YAAA;EAuBQ;;;;;EAjBxB,WAAA;EAiBwB;;;EAbxB,KAAA;EAawB;;;EATxB,KAAA;EASwB;;;;EAHxB,KAAA;AAAA;AAAA,cAGS,WAAA;EAAA,qBAAe,eAAA;EAAA,SAAA;EAAA,eAAA,MAAA;EAAA,QAAA;EAAA,QAAA;EAAA,YAAA;EAAA,SAAA;EAAA,EAAA;EAAA,YAAA;EAAA,oBAAA,cAAA;EAAA,QAAA;EAAA,SAAA;EAAA,MAAA;EAAA,OAAA,EAAA,WAAA;EAAA,OAAA;EAAA,QAAA,EAAA,YAAA;EAAA,YAAA;EAAA,WAAA;EAAA,KAAA;EAAA,KAAA;EAAA;AAAA,GAsBzB,KAAA,iCAAK,GAAA,CAAA,OAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchInput-IfEWePDQ.d.mts","names":[],"sources":["../src/SearchInput/SearchInput.tsx"],"mappings":";;;;KAQK,KAAA;;AAH0C;;;;EAS3C,mBAAA;EACA,SAAA;EA2CW;;;EAAA,CAvCV,aAAA;EAJD;;;EAQA,QAAA;EASA;;;EALA,QAAA;EAeA;;;;EAVA,YAAA,GAAe,SAAA;EA0BM;;;EAtBrB,SAAA,GAAY,UAAA;EAuCZ;;;;;EAjCA,EAAA;EAmDA;;;;AAUK;EAvDL,YAAA;
|
|
1
|
+
{"version":3,"file":"SearchInput-IfEWePDQ.d.mts","names":[],"sources":["../src/SearchInput/SearchInput.tsx"],"mappings":";;;;KAQK,KAAA;;AAH0C;;;;EAS3C,mBAAA;EACA,SAAA;EA2CW;;;EAAA,CAvCV,aAAA;EAJD;;;EAQA,QAAA;EASA;;;EALA,QAAA;EAeA;;;;EAVA,YAAA,GAAe,SAAA;EA0BM;;;EAtBrB,SAAA,GAAY,UAAA;EAuCZ;;;;;EAjCA,EAAA;EAmDA;;;;AAUK;EAvDL,YAAA;EA4LH;;;;;EAtLG,kBAAA;EAoDwB;;;EAhDxB,QAAA,GAAW,SAAA,CAAU,gBAAA;EAgDG;;;;EA3CxB,SAAA;EA2CwB;;;EAvCxB,MAAA;EAuCwB;;;EAnCxB,OAAA;EAyDD;;;EArDC,OAAA;EA+BwB;;;EA3BxB,QAAA,IAAY,YAAA;EA2BY;;;EAvBxB,YAAA,IAAgB,YAAA;EAuBQ;;;;;EAjBxB,WAAA;EAiBwB;;;EAbxB,KAAA;EAawB;;;EATxB,KAAA;EASwB;;;;EAHxB,KAAA;AAAA;AAAA,cAGS,WAAA;EAAA,qBAAe,eAAA;EAAA,SAAA;EAAA,eAAA,MAAA;EAAA,QAAA;EAAA,QAAA;EAAA,YAAA;EAAA,SAAA;EAAA,EAAA;EAAA,YAAA;EAAA,oBAAA,cAAA;EAAA,QAAA;EAAA,SAAA;EAAA,MAAA;EAAA,OAAA,EAAA,WAAA;EAAA,OAAA;EAAA,QAAA,EAAA,YAAA;EAAA,YAAA;EAAA,WAAA;EAAA,KAAA;EAAA,KAAA;EAAA;AAAA,GAsBzB,KAAA,iCAAK,GAAA,CAAA,OAAA"}
|
|
@@ -77,7 +77,7 @@ const Option = ({ children, isDisabled, isFocused, isSelected, ...rest }) => {
|
|
|
77
77
|
"!bg-background-inverse !text-text-inverse hover:!bg-background-inverse": !isDisabled && isSelected,
|
|
78
78
|
"!bg-background-primary": isDisabled && isFocused && !isSelected,
|
|
79
79
|
"!cursor-not-allowed !bg-background-inverse !text-text-disabled hover:!bg-background-inverse": isSelectedAndDisabled,
|
|
80
|
-
"!cursor-not-allowed !text-text-disabled hover:!bg-background-primary
|
|
80
|
+
"!cursor-not-allowed !text-text-disabled hover:!bg-background-primary": isDisabled && !isSelected
|
|
81
81
|
}),
|
|
82
82
|
innerProps: {
|
|
83
83
|
...rest.innerProps,
|
|
@@ -238,4 +238,4 @@ Select.displayName = "Select";
|
|
|
238
238
|
//#endregion
|
|
239
239
|
export { selectBuiltins as n, Select as t };
|
|
240
240
|
|
|
241
|
-
//# sourceMappingURL=Select-
|
|
241
|
+
//# sourceMappingURL=Select-CH_ZN88G.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select-CH_ZN88G.mjs","names":["selectBuiltins"],"sources":["../src/Select/selectComponents.tsx","../src/Select/Select.tsx"],"sourcesContent":["import { cn } from '@evolve.ui/theme-system';\nimport { ComponentProps, ReactNode } from 'react';\nimport { components as selectBuiltins } from 'react-select';\n\nimport { CaretDown, Check } from '../Icons';\nimport { BodyPrimary } from '../Typography/Text/Text';\n\nexport const InsideLabelControl = ({\n children,\n ...props\n}: ComponentProps<typeof selectBuiltins.Control> & {\n selectProps: {\n hasError?: boolean;\n isInsideLabel?: boolean;\n labelText?: ReactNode;\n small?: boolean;\n };\n}) => {\n const { hasError, isInsideLabel, labelText, small } = props.selectProps;\n return (\n <selectBuiltins.Control\n {...props}\n className={cn(\n // GENERAL\n '!m-0 !min-h-[42px] !flex-nowrap !rounded-input !border !border-solid !border-border-secondary !bg-background-primary !p-0 ![box-shadow:none]',\n // HOVER\n {\n 'hover:!border-border-hover': !props.menuIsOpen,\n 'hover:!border-border-selected': props.menuIsOpen,\n },\n {\n '!border-border-critical': props.selectProps['aria-invalid'] === 'true',\n '!border-border-selected': props.menuIsOpen || props.isFocused,\n '!min-h-[34px]': small,\n },\n // ERROR\n {\n '!border-border-critical': hasError && !props.menuIsOpen && !props.isDisabled,\n }\n )}\n >\n {isInsideLabel && Boolean(labelText) && (\n <BodyPrimary\n className=\"ml-xs mr--2xs\"\n color=\"secondary\"\n >\n {labelText}\n </BodyPrimary>\n )}\n {children}\n </selectBuiltins.Control>\n );\n};\n\n/**\n * Add custom icon for dropdown indicator\n * @see https://react-select.com/components#components\n */\nexport const DropdownIndicator = (props: ComponentProps<typeof selectBuiltins.DropdownIndicator>) => {\n return (\n <selectBuiltins.DropdownIndicator\n {...props}\n className=\"flex h-full w-full items-center justify-center !py-0 px-xs\"\n >\n <CaretDown\n aria-label={props.selectProps.menuIsOpen ? 'Caret Up' : 'Caret Down'}\n className={cn({\n 'rotate-180': props.selectProps.menuIsOpen,\n })}\n color={props.selectProps.isDisabled ? 'disabled' : 'primary'}\n size=\"sm\"\n />\n </selectBuiltins.DropdownIndicator>\n );\n};\n\n/**\n * Add data-testid prop to the select component container\n * @see https://react-select.com/components#components\n */\nexport const SelectContainer = ({ className, ...props }: ComponentProps<typeof selectBuiltins.SelectContainer>) => (\n <selectBuiltins.SelectContainer\n {...props}\n className={cn(className, 'hui-text-body-primary !rounded-input text-text-primary ![box-shadow:none]')}\n innerProps={{\n ...props.innerProps,\n // @ts-expect-error all attributes are passed and we have the custom \"data-testid\", so this is ok.\n ...(Boolean(props.selectProps['data-testid']) && {\n // @ts-expect-error all attributes are passed and we have the custom \"data-testid\", so this is ok.\n 'data-testid': props.selectProps['data-testid'],\n }),\n }}\n />\n);\n\nexport const NoOptionsMessage = (props: ComponentProps<typeof selectBuiltins.NoOptionsMessage>) => (\n <selectBuiltins.NoOptionsMessage\n {...props}\n className=\"p-0\"\n >\n <BodyPrimary\n className=\"normal-case\"\n color=\"secondary\"\n >\n No results\n </BodyPrimary>\n </selectBuiltins.NoOptionsMessage>\n);\n\nexport const Input = (props: ComponentProps<typeof selectBuiltins.Input>) => (\n <selectBuiltins.Input\n {...props}\n aria-activedescendant={props['aria-activedescendant'] || undefined}\n // @ts-expect-error prop type does exist on parent, just not here.\n autoComplete={props.selectProps.autoComplete}\n className=\"!m-0 !p-0\"\n />\n);\n\nexport const Option = ({\n children,\n isDisabled,\n isFocused,\n isSelected,\n ...rest\n}: ComponentProps<typeof selectBuiltins.Option>) => {\n const isSelectedAndDisabled = isSelected && isDisabled;\n\n return (\n <selectBuiltins.Option\n {...rest}\n className={cn(\n // BASE\n 'hui-text-body-primary !px-[8px] !py-[4px] text-[16px] text-text-primary',\n // HOVER\n 'hover:cursor-pointer hover:bg-background-hover',\n // SELECTED\n {\n '!bg-background-hover': !isDisabled && isFocused,\n '!bg-background-inverse !text-text-inverse hover:!bg-background-inverse': !isDisabled && isSelected,\n '!bg-background-primary': isDisabled && isFocused && !isSelected,\n // Selected AND disabled - show as selected but with disabled text color\n '!cursor-not-allowed !bg-background-inverse !text-text-disabled hover:!bg-background-inverse':\n isSelectedAndDisabled,\n '!cursor-not-allowed !text-text-disabled hover:!bg-background-primary': isDisabled && !isSelected,\n }\n )}\n innerProps={{\n ...rest.innerProps,\n // @ts-expect-error all attributes are passed and we have the custom \"data-testid\", so this is ok.\n ...(Boolean(rest.selectProps['data-testid']) && {\n // @ts-expect-error all attributes are passed and we have the custom \"data-testid\", so this is ok.\n 'data-testid': rest.selectProps['data-testid'],\n }),\n }}\n isDisabled={Boolean(isDisabled)}\n isFocused={isFocused}\n isSelected={isSelected}\n >\n <div\n // adds data-testid attribute to dropdown option\n {...(rest.data && typeof rest.data === 'object' && 'data-testid' in rest.data\n ? { 'data-testid': rest.data['data-testid'] }\n : {})}\n className={cn('flex h-full w-full items-center', {\n 'bg-background-inverse text-text-disabled': isSelectedAndDisabled,\n 'bg-background-inverse text-text-inverse': isSelected && !isDisabled,\n 'pl-sm': !isSelected,\n })}\n >\n {isSelected && (\n <Check\n className=\"mr-[2px]\"\n color={isDisabled ? 'disabled' : 'inverse'}\n size=\"xs\"\n />\n )}\n {children}\n </div>\n </selectBuiltins.Option>\n );\n};\n\nexport const ClearIndicator = (props: ComponentProps<typeof selectBuiltins.ClearIndicator>) => (\n <selectBuiltins.ClearIndicator\n {...props}\n className=\"!py-0\"\n >\n {props.children}\n </selectBuiltins.ClearIndicator>\n);\n\n/**\n * Reads the scroll offset that `PreventModalScroll` parks on `document.body.style.top`.\n *\n * When a modal is open, `PreventModalScroll` sets `body.style.top = \"-${scrollPosition}px\"`\n * and `body.style.position = \"fixed\"`. React-select uses `window.pageYOffset` for the\n * portal offset, but that returns 0 when the body is fixed, so we read the stored scroll\n * position directly from `body.style.top` to compensate. Zoom-agnostic because it's a\n * stored value, not a layout measurement.\n */\nconst getBodyScrollOffset = () => {\n const bodyTop = typeof document !== 'undefined' ? document.body.style.top : '';\n return bodyTop ? Math.abs(parseFloat(bodyTop)) : 0;\n};\n\n/**\n * Adds the stored body-scroll offset to react-select's computed `top` style.\n *\n * react-select only sets `top` when placement === 'bottom'. When it flips to 'top'\n * it sets `bottom` instead and leaves `top` undefined, so we must guard before adding\n * the scroll offset — otherwise `Number(undefined)` NaN-stomps the style and breaks\n * the flipped portal menu.\n *\n * @internal exported for unit testing only.\n */\nexport const applyBodyScrollOffsetToTop = <T extends Record<string, unknown>>(\n baseStyles: T,\n scrollOffset: number\n): T => ({\n ...baseStyles,\n ...(typeof baseStyles.top === 'number' ? { top: baseStyles.top + scrollOffset } : {}),\n});\n\nexport const Menu = ({ getStyles, ...props }: ComponentProps<typeof selectBuiltins.Menu>) => {\n if (props.selectProps.menuPortalTarget) {\n const customGetStyles: typeof getStyles = (name, styleProps) =>\n applyBodyScrollOffsetToTop(getStyles(name, styleProps), getBodyScrollOffset());\n\n return (\n <selectBuiltins.Menu\n {...props}\n getStyles={customGetStyles}\n className={cn(\n props.className,\n '!z-[11111] !mt-2xs !rounded-input !border !border-border-secondary !bg-background-primary'\n )}\n >\n {props.children}\n </selectBuiltins.Menu>\n );\n }\n\n return (\n <selectBuiltins.Menu\n {...props}\n getStyles={getStyles}\n className={cn(\n props.className,\n '!z-[11111] !mt-2xs !rounded-input !border !border-border-secondary !bg-background-primary'\n )}\n >\n {props.children}\n </selectBuiltins.Menu>\n );\n};\n\nexport const MenuList = (props: ComponentProps<typeof selectBuiltins.MenuList>) => (\n <selectBuiltins.MenuList\n {...props}\n className=\"!px-0 !py-xs\"\n >\n {props.children}\n </selectBuiltins.MenuList>\n);\n\nexport const MenuPortal = (props: ComponentProps<typeof selectBuiltins.MenuPortal>) => (\n <selectBuiltins.MenuPortal\n {...props}\n className=\"!z-[11111]\"\n >\n {props.children}\n </selectBuiltins.MenuPortal>\n);\n\nexport const Placeholder = (props: ComponentProps<typeof selectBuiltins.Placeholder>) => (\n <selectBuiltins.Placeholder\n {...props}\n className=\"!hui-text-body-primary overflow-hidden text-nowrap\"\n >\n {props.children}\n </selectBuiltins.Placeholder>\n);\n\nexport const SingleValue = ({ isDisabled, ...rest }: ComponentProps<typeof selectBuiltins.SingleValue>) => (\n <selectBuiltins.SingleValue\n {...rest}\n className={cn('!hui-text-body-primary m-0', {\n '!cursor-not-allowed !text-text-disabled': isDisabled,\n '!text-text-primary': !isDisabled,\n })}\n isDisabled={isDisabled}\n >\n {rest.children}\n </selectBuiltins.SingleValue>\n);\n\nexport const ValueContainer = (props: ComponentProps<typeof selectBuiltins.ValueContainer>) => (\n <selectBuiltins.ValueContainer\n {...props}\n className=\"!m-0 flex h-full items-center !py-0\"\n >\n {props.children}\n </selectBuiltins.ValueContainer>\n);\n","import type ReactSelectAsync from 'react-select/async';\nimport type ReactSelectAsyncCreatable from 'react-select/async-creatable';\nimport type ReactSelectCreatable from 'react-select/creatable';\n\nimport {\n type ForwardRefExoticComponent,\n type RefAttributes,\n ComponentProps,\n forwardRef,\n useCallback,\n useId,\n} from 'react';\nimport ReactSelect, { ActionMeta, components as selectBuiltins } from 'react-select';\n\nimport { extractFormLabelProps, FormLabel, FormLabelProps } from '../FormLabel/FormLabel';\nimport {\n ClearIndicator,\n DropdownIndicator,\n Input,\n InsideLabelControl,\n Menu,\n MenuList,\n MenuPortal,\n NoOptionsMessage,\n Option,\n Placeholder,\n SelectContainer,\n SingleValue,\n ValueContainer,\n} from './selectComponents';\n\n// Props are unwieldy, so, put them at the bottom.\n\n/**\n * A customized + styled react-select\n *\n * @see https://react-select.com\n */\nexport const Select = forwardRef(\n <SelectType extends AllSelects>(unfilteredProps: Props<SelectType>, ref: ComponentProps<SelectType>['ref']) => {\n const defaultInstanceId = useId();\n const [\n formLabelProps,\n {\n components,\n disabled,\n isInsideLabel,\n menuPlacement = 'auto',\n menuPosition,\n name,\n onChange: propOnChange,\n selectType: SelectComponent = ReactSelect,\n small = false,\n usePortalMenu,\n ...selectProps\n },\n ] = extractFormLabelProps(unfilteredProps);\n\n const onChange = useCallback<SelectOnChange>(\n (event, action) => {\n if (event) {\n event.name = name;\n propOnChange?.(event, action);\n }\n },\n [name, propOnChange]\n );\n\n return (\n <FormLabel\n {...formLabelProps}\n labelText={isInsideLabel ? undefined : formLabelProps.labelText}\n >\n <SelectComponent\n data-hui-id=\"Select\"\n instanceId={defaultInstanceId}\n placeholder=\"Select\"\n {...selectProps}\n components={{\n ClearIndicator,\n Control: InsideLabelControl,\n DropdownIndicator,\n IndicatorSeparator: null,\n Input,\n Menu,\n MenuList,\n MenuPortal,\n NoOptionsMessage,\n Option,\n Placeholder,\n SelectContainer,\n SingleValue,\n ValueContainer,\n ...components,\n }}\n hasError={formLabelProps.hasError}\n isDisabled={disabled}\n isInsideLabel={isInsideLabel}\n labelText={formLabelProps.labelText}\n menuPlacement={menuPlacement}\n menuPosition={menuPosition ?? (usePortalMenu ? 'fixed' : 'absolute')}\n menuPortalTarget={\n usePortalMenu && typeof document !== 'undefined'\n ? document.getElementById('hui-modal-target')\n : undefined\n }\n name={name}\n // This typing should be correct, but react-select is a bit of a mess\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onChange={onChange as any}\n ref={ref}\n small={small}\n />\n </FormLabel>\n );\n }\n) as ForwardRefExoticComponent<Props<typeof ReactSelect> & RefAttributes<unknown>>;\n\nSelect.displayName = 'Select';\n\n/**\n * Re-export react-select built-ins\n * @see https://react-select.com/components\n */\nexport { selectBuiltins as reactSelectBuiltins };\n\ntype ExtendedProps = {\n /** Adds autocomplete attribute to the dom element, used for accessibility and password managers. */\n autoComplete?: string;\n /** If true, the label will be inside the select. */\n isInsideLabel?: boolean;\n /** Set the size of the select to small (`34px` height, small=false is `42px`) */\n small?: boolean;\n /** Position the select dropdown menu absolutely, relative to <body />. Useful in places like modals where the menu may get cut off */\n usePortalMenu?: boolean;\n} & FormLabelProps;\n\ntype AllSelects =\n | typeof ReactSelect\n | typeof ReactSelectAsync\n | typeof ReactSelectAsyncCreatable\n | typeof ReactSelectCreatable;\n\ntype OverridenOnChangeProps<SelectType extends AllSelects> = Omit<ComponentProps<SelectType>, 'onChange'> & {\n onChange?: SelectOnChange;\n};\n\ntype Props<SelectType extends AllSelects> = { selectType?: SelectType } & ExtendedProps &\n OverridenOnChangeProps<SelectType>;\n\n// Hammer-parity public type — `value: any` is the published contract consumers rely on.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type OptionType = { label: string; name?: string; value: any };\nexport type SelectOnChange = (event?: OptionType, action?: ActionMeta<OptionType>) => void;\n"],"mappings":"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"}
|
|
@@ -79,7 +79,7 @@ const Option = ({ children, isDisabled, isFocused, isSelected, ...rest }) => {
|
|
|
79
79
|
"!bg-background-inverse !text-text-inverse hover:!bg-background-inverse": !isDisabled && isSelected,
|
|
80
80
|
"!bg-background-primary": isDisabled && isFocused && !isSelected,
|
|
81
81
|
"!cursor-not-allowed !bg-background-inverse !text-text-disabled hover:!bg-background-inverse": isSelectedAndDisabled,
|
|
82
|
-
"!cursor-not-allowed !text-text-disabled hover:!bg-background-primary
|
|
82
|
+
"!cursor-not-allowed !text-text-disabled hover:!bg-background-primary": isDisabled && !isSelected
|
|
83
83
|
}),
|
|
84
84
|
innerProps: {
|
|
85
85
|
...rest.innerProps,
|
|
@@ -245,4 +245,4 @@ Object.defineProperty(exports, "Select", {
|
|
|
245
245
|
}
|
|
246
246
|
});
|
|
247
247
|
|
|
248
|
-
//# sourceMappingURL=Select-
|
|
248
|
+
//# sourceMappingURL=Select-DCCcyLT4.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select-DCCcyLT4.cjs","names":["selectBuiltins","BodyPrimary","CaretDown","Check","ReactSelect","extractFormLabelProps","FormLabel"],"sources":["../src/Select/selectComponents.tsx","../src/Select/Select.tsx"],"sourcesContent":["import { cn } from '@evolve.ui/theme-system';\nimport { ComponentProps, ReactNode } from 'react';\nimport { components as selectBuiltins } from 'react-select';\n\nimport { CaretDown, Check } from '../Icons';\nimport { BodyPrimary } from '../Typography/Text/Text';\n\nexport const InsideLabelControl = ({\n children,\n ...props\n}: ComponentProps<typeof selectBuiltins.Control> & {\n selectProps: {\n hasError?: boolean;\n isInsideLabel?: boolean;\n labelText?: ReactNode;\n small?: boolean;\n };\n}) => {\n const { hasError, isInsideLabel, labelText, small } = props.selectProps;\n return (\n <selectBuiltins.Control\n {...props}\n className={cn(\n // GENERAL\n '!m-0 !min-h-[42px] !flex-nowrap !rounded-input !border !border-solid !border-border-secondary !bg-background-primary !p-0 ![box-shadow:none]',\n // HOVER\n {\n 'hover:!border-border-hover': !props.menuIsOpen,\n 'hover:!border-border-selected': props.menuIsOpen,\n },\n {\n '!border-border-critical': props.selectProps['aria-invalid'] === 'true',\n '!border-border-selected': props.menuIsOpen || props.isFocused,\n '!min-h-[34px]': small,\n },\n // ERROR\n {\n '!border-border-critical': hasError && !props.menuIsOpen && !props.isDisabled,\n }\n )}\n >\n {isInsideLabel && Boolean(labelText) && (\n <BodyPrimary\n className=\"ml-xs mr--2xs\"\n color=\"secondary\"\n >\n {labelText}\n </BodyPrimary>\n )}\n {children}\n </selectBuiltins.Control>\n );\n};\n\n/**\n * Add custom icon for dropdown indicator\n * @see https://react-select.com/components#components\n */\nexport const DropdownIndicator = (props: ComponentProps<typeof selectBuiltins.DropdownIndicator>) => {\n return (\n <selectBuiltins.DropdownIndicator\n {...props}\n className=\"flex h-full w-full items-center justify-center !py-0 px-xs\"\n >\n <CaretDown\n aria-label={props.selectProps.menuIsOpen ? 'Caret Up' : 'Caret Down'}\n className={cn({\n 'rotate-180': props.selectProps.menuIsOpen,\n })}\n color={props.selectProps.isDisabled ? 'disabled' : 'primary'}\n size=\"sm\"\n />\n </selectBuiltins.DropdownIndicator>\n );\n};\n\n/**\n * Add data-testid prop to the select component container\n * @see https://react-select.com/components#components\n */\nexport const SelectContainer = ({ className, ...props }: ComponentProps<typeof selectBuiltins.SelectContainer>) => (\n <selectBuiltins.SelectContainer\n {...props}\n className={cn(className, 'hui-text-body-primary !rounded-input text-text-primary ![box-shadow:none]')}\n innerProps={{\n ...props.innerProps,\n // @ts-expect-error all attributes are passed and we have the custom \"data-testid\", so this is ok.\n ...(Boolean(props.selectProps['data-testid']) && {\n // @ts-expect-error all attributes are passed and we have the custom \"data-testid\", so this is ok.\n 'data-testid': props.selectProps['data-testid'],\n }),\n }}\n />\n);\n\nexport const NoOptionsMessage = (props: ComponentProps<typeof selectBuiltins.NoOptionsMessage>) => (\n <selectBuiltins.NoOptionsMessage\n {...props}\n className=\"p-0\"\n >\n <BodyPrimary\n className=\"normal-case\"\n color=\"secondary\"\n >\n No results\n </BodyPrimary>\n </selectBuiltins.NoOptionsMessage>\n);\n\nexport const Input = (props: ComponentProps<typeof selectBuiltins.Input>) => (\n <selectBuiltins.Input\n {...props}\n aria-activedescendant={props['aria-activedescendant'] || undefined}\n // @ts-expect-error prop type does exist on parent, just not here.\n autoComplete={props.selectProps.autoComplete}\n className=\"!m-0 !p-0\"\n />\n);\n\nexport const Option = ({\n children,\n isDisabled,\n isFocused,\n isSelected,\n ...rest\n}: ComponentProps<typeof selectBuiltins.Option>) => {\n const isSelectedAndDisabled = isSelected && isDisabled;\n\n return (\n <selectBuiltins.Option\n {...rest}\n className={cn(\n // BASE\n 'hui-text-body-primary !px-[8px] !py-[4px] text-[16px] text-text-primary',\n // HOVER\n 'hover:cursor-pointer hover:bg-background-hover',\n // SELECTED\n {\n '!bg-background-hover': !isDisabled && isFocused,\n '!bg-background-inverse !text-text-inverse hover:!bg-background-inverse': !isDisabled && isSelected,\n '!bg-background-primary': isDisabled && isFocused && !isSelected,\n // Selected AND disabled - show as selected but with disabled text color\n '!cursor-not-allowed !bg-background-inverse !text-text-disabled hover:!bg-background-inverse':\n isSelectedAndDisabled,\n '!cursor-not-allowed !text-text-disabled hover:!bg-background-primary': isDisabled && !isSelected,\n }\n )}\n innerProps={{\n ...rest.innerProps,\n // @ts-expect-error all attributes are passed and we have the custom \"data-testid\", so this is ok.\n ...(Boolean(rest.selectProps['data-testid']) && {\n // @ts-expect-error all attributes are passed and we have the custom \"data-testid\", so this is ok.\n 'data-testid': rest.selectProps['data-testid'],\n }),\n }}\n isDisabled={Boolean(isDisabled)}\n isFocused={isFocused}\n isSelected={isSelected}\n >\n <div\n // adds data-testid attribute to dropdown option\n {...(rest.data && typeof rest.data === 'object' && 'data-testid' in rest.data\n ? { 'data-testid': rest.data['data-testid'] }\n : {})}\n className={cn('flex h-full w-full items-center', {\n 'bg-background-inverse text-text-disabled': isSelectedAndDisabled,\n 'bg-background-inverse text-text-inverse': isSelected && !isDisabled,\n 'pl-sm': !isSelected,\n })}\n >\n {isSelected && (\n <Check\n className=\"mr-[2px]\"\n color={isDisabled ? 'disabled' : 'inverse'}\n size=\"xs\"\n />\n )}\n {children}\n </div>\n </selectBuiltins.Option>\n );\n};\n\nexport const ClearIndicator = (props: ComponentProps<typeof selectBuiltins.ClearIndicator>) => (\n <selectBuiltins.ClearIndicator\n {...props}\n className=\"!py-0\"\n >\n {props.children}\n </selectBuiltins.ClearIndicator>\n);\n\n/**\n * Reads the scroll offset that `PreventModalScroll` parks on `document.body.style.top`.\n *\n * When a modal is open, `PreventModalScroll` sets `body.style.top = \"-${scrollPosition}px\"`\n * and `body.style.position = \"fixed\"`. React-select uses `window.pageYOffset` for the\n * portal offset, but that returns 0 when the body is fixed, so we read the stored scroll\n * position directly from `body.style.top` to compensate. Zoom-agnostic because it's a\n * stored value, not a layout measurement.\n */\nconst getBodyScrollOffset = () => {\n const bodyTop = typeof document !== 'undefined' ? document.body.style.top : '';\n return bodyTop ? Math.abs(parseFloat(bodyTop)) : 0;\n};\n\n/**\n * Adds the stored body-scroll offset to react-select's computed `top` style.\n *\n * react-select only sets `top` when placement === 'bottom'. When it flips to 'top'\n * it sets `bottom` instead and leaves `top` undefined, so we must guard before adding\n * the scroll offset — otherwise `Number(undefined)` NaN-stomps the style and breaks\n * the flipped portal menu.\n *\n * @internal exported for unit testing only.\n */\nexport const applyBodyScrollOffsetToTop = <T extends Record<string, unknown>>(\n baseStyles: T,\n scrollOffset: number\n): T => ({\n ...baseStyles,\n ...(typeof baseStyles.top === 'number' ? { top: baseStyles.top + scrollOffset } : {}),\n});\n\nexport const Menu = ({ getStyles, ...props }: ComponentProps<typeof selectBuiltins.Menu>) => {\n if (props.selectProps.menuPortalTarget) {\n const customGetStyles: typeof getStyles = (name, styleProps) =>\n applyBodyScrollOffsetToTop(getStyles(name, styleProps), getBodyScrollOffset());\n\n return (\n <selectBuiltins.Menu\n {...props}\n getStyles={customGetStyles}\n className={cn(\n props.className,\n '!z-[11111] !mt-2xs !rounded-input !border !border-border-secondary !bg-background-primary'\n )}\n >\n {props.children}\n </selectBuiltins.Menu>\n );\n }\n\n return (\n <selectBuiltins.Menu\n {...props}\n getStyles={getStyles}\n className={cn(\n props.className,\n '!z-[11111] !mt-2xs !rounded-input !border !border-border-secondary !bg-background-primary'\n )}\n >\n {props.children}\n </selectBuiltins.Menu>\n );\n};\n\nexport const MenuList = (props: ComponentProps<typeof selectBuiltins.MenuList>) => (\n <selectBuiltins.MenuList\n {...props}\n className=\"!px-0 !py-xs\"\n >\n {props.children}\n </selectBuiltins.MenuList>\n);\n\nexport const MenuPortal = (props: ComponentProps<typeof selectBuiltins.MenuPortal>) => (\n <selectBuiltins.MenuPortal\n {...props}\n className=\"!z-[11111]\"\n >\n {props.children}\n </selectBuiltins.MenuPortal>\n);\n\nexport const Placeholder = (props: ComponentProps<typeof selectBuiltins.Placeholder>) => (\n <selectBuiltins.Placeholder\n {...props}\n className=\"!hui-text-body-primary overflow-hidden text-nowrap\"\n >\n {props.children}\n </selectBuiltins.Placeholder>\n);\n\nexport const SingleValue = ({ isDisabled, ...rest }: ComponentProps<typeof selectBuiltins.SingleValue>) => (\n <selectBuiltins.SingleValue\n {...rest}\n className={cn('!hui-text-body-primary m-0', {\n '!cursor-not-allowed !text-text-disabled': isDisabled,\n '!text-text-primary': !isDisabled,\n })}\n isDisabled={isDisabled}\n >\n {rest.children}\n </selectBuiltins.SingleValue>\n);\n\nexport const ValueContainer = (props: ComponentProps<typeof selectBuiltins.ValueContainer>) => (\n <selectBuiltins.ValueContainer\n {...props}\n className=\"!m-0 flex h-full items-center !py-0\"\n >\n {props.children}\n </selectBuiltins.ValueContainer>\n);\n","import type ReactSelectAsync from 'react-select/async';\nimport type ReactSelectAsyncCreatable from 'react-select/async-creatable';\nimport type ReactSelectCreatable from 'react-select/creatable';\n\nimport {\n type ForwardRefExoticComponent,\n type RefAttributes,\n ComponentProps,\n forwardRef,\n useCallback,\n useId,\n} from 'react';\nimport ReactSelect, { ActionMeta, components as selectBuiltins } from 'react-select';\n\nimport { extractFormLabelProps, FormLabel, FormLabelProps } from '../FormLabel/FormLabel';\nimport {\n ClearIndicator,\n DropdownIndicator,\n Input,\n InsideLabelControl,\n Menu,\n MenuList,\n MenuPortal,\n NoOptionsMessage,\n Option,\n Placeholder,\n SelectContainer,\n SingleValue,\n ValueContainer,\n} from './selectComponents';\n\n// Props are unwieldy, so, put them at the bottom.\n\n/**\n * A customized + styled react-select\n *\n * @see https://react-select.com\n */\nexport const Select = forwardRef(\n <SelectType extends AllSelects>(unfilteredProps: Props<SelectType>, ref: ComponentProps<SelectType>['ref']) => {\n const defaultInstanceId = useId();\n const [\n formLabelProps,\n {\n components,\n disabled,\n isInsideLabel,\n menuPlacement = 'auto',\n menuPosition,\n name,\n onChange: propOnChange,\n selectType: SelectComponent = ReactSelect,\n small = false,\n usePortalMenu,\n ...selectProps\n },\n ] = extractFormLabelProps(unfilteredProps);\n\n const onChange = useCallback<SelectOnChange>(\n (event, action) => {\n if (event) {\n event.name = name;\n propOnChange?.(event, action);\n }\n },\n [name, propOnChange]\n );\n\n return (\n <FormLabel\n {...formLabelProps}\n labelText={isInsideLabel ? undefined : formLabelProps.labelText}\n >\n <SelectComponent\n data-hui-id=\"Select\"\n instanceId={defaultInstanceId}\n placeholder=\"Select\"\n {...selectProps}\n components={{\n ClearIndicator,\n Control: InsideLabelControl,\n DropdownIndicator,\n IndicatorSeparator: null,\n Input,\n Menu,\n MenuList,\n MenuPortal,\n NoOptionsMessage,\n Option,\n Placeholder,\n SelectContainer,\n SingleValue,\n ValueContainer,\n ...components,\n }}\n hasError={formLabelProps.hasError}\n isDisabled={disabled}\n isInsideLabel={isInsideLabel}\n labelText={formLabelProps.labelText}\n menuPlacement={menuPlacement}\n menuPosition={menuPosition ?? (usePortalMenu ? 'fixed' : 'absolute')}\n menuPortalTarget={\n usePortalMenu && typeof document !== 'undefined'\n ? document.getElementById('hui-modal-target')\n : undefined\n }\n name={name}\n // This typing should be correct, but react-select is a bit of a mess\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onChange={onChange as any}\n ref={ref}\n small={small}\n />\n </FormLabel>\n );\n }\n) as ForwardRefExoticComponent<Props<typeof ReactSelect> & RefAttributes<unknown>>;\n\nSelect.displayName = 'Select';\n\n/**\n * Re-export react-select built-ins\n * @see https://react-select.com/components\n */\nexport { selectBuiltins as reactSelectBuiltins };\n\ntype ExtendedProps = {\n /** Adds autocomplete attribute to the dom element, used for accessibility and password managers. */\n autoComplete?: string;\n /** If true, the label will be inside the select. */\n isInsideLabel?: boolean;\n /** Set the size of the select to small (`34px` height, small=false is `42px`) */\n small?: boolean;\n /** Position the select dropdown menu absolutely, relative to <body />. Useful in places like modals where the menu may get cut off */\n usePortalMenu?: boolean;\n} & FormLabelProps;\n\ntype AllSelects =\n | typeof ReactSelect\n | typeof ReactSelectAsync\n | typeof ReactSelectAsyncCreatable\n | typeof ReactSelectCreatable;\n\ntype OverridenOnChangeProps<SelectType extends AllSelects> = Omit<ComponentProps<SelectType>, 'onChange'> & {\n onChange?: SelectOnChange;\n};\n\ntype Props<SelectType extends AllSelects> = { selectType?: SelectType } & ExtendedProps &\n OverridenOnChangeProps<SelectType>;\n\n// Hammer-parity public type — `value: any` is the published contract consumers rely on.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type OptionType = { label: string; name?: string; value: any };\nexport type SelectOnChange = (event?: OptionType, action?: ActionMeta<OptionType>) => void;\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const require_Icons = require("./Icons.cjs");
|
|
2
|
-
const require_buttonColorClasses = require("./buttonColorClasses-
|
|
2
|
+
const require_buttonColorClasses = require("./buttonColorClasses-CQQmLYfk.cjs");
|
|
3
3
|
const require_Button = require("./Button.cjs");
|
|
4
4
|
const require_menuContext = require("./menuContext-B6MhMBDf.cjs");
|
|
5
5
|
let _evolve_ui_theme_system = require("@evolve.ui/theme-system");
|
|
@@ -181,4 +181,4 @@ Object.defineProperty(exports, "SplitButton", {
|
|
|
181
181
|
}
|
|
182
182
|
});
|
|
183
183
|
|
|
184
|
-
//# sourceMappingURL=SplitButton-
|
|
184
|
+
//# sourceMappingURL=SplitButton-B_Y253RU.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SplitButton-DcmmLW8j.cjs","names":["filledPrimaryClasses","outlinedPrimaryClasses","CaretDown","autoUpdate","Button","MenuContext","FloatingList","FloatingPortal","FloatingFocusManager","FloatingTree"],"sources":["../src/SplitButton/SplitButtonTrigger.tsx","../src/SplitButton/SplitButton.tsx"],"sourcesContent":["import { cn } from '@evolve.ui/theme-system';\nimport { forwardRef, HTMLProps } from 'react';\n\nimport { filledPrimaryClasses, outlinedPrimaryClasses } from '../Button/buttonColorClasses';\nimport { CaretDown } from '../Icons/generatedIcons/CaretDown';\n\ntype Props = {\n /** Whether the menu is currently open — applies pressed visual state to the trigger */\n isOpen?: boolean;\n /** Button size, should match the adjacent default action button */\n size?: 'md' | 'sm';\n /** Visual variant */\n variant?: 'filled' | 'outlined';\n} & Omit<HTMLProps<HTMLButtonElement>, 'size' | 'type'>;\n\n/**\n * The caret trigger button used inside `SplitButton`. Renders a square button\n * with a `CaretDown` icon, styled to join seamlessly with the default action button.\n *\n * Not intended for standalone use — use `SplitButton` instead.\n */\nexport const SplitButtonTrigger = forwardRef<HTMLButtonElement, Props>(\n ({ className, disabled = false, isOpen = false, size = 'md', variant = 'filled', ...rest }, ref) => {\n const isFilled = variant === 'filled';\n\n return (\n <button\n className={cn(\n 'hui-focus-visible-outline relative flex items-center justify-center rounded-l-none rounded-r-button outline outline-1 -outline-offset-1 transition-colors',\n isFilled ? filledPrimaryClasses : cn(outlinedPrimaryClasses, 'ml-[-1px]'),\n {\n 'size-[34px]': size === 'sm',\n 'size-[42px]': size === 'md',\n // Force the pressed/active visual while the menu is open\n '!bg-primary-200 !text-primary-900': isOpen && !isFilled,\n '!bg-primary-900': isOpen && isFilled,\n },\n className\n )}\n data-hui-id=\"SplitButtonTrigger\"\n disabled={disabled}\n ref={ref}\n type=\"button\"\n {...rest}\n >\n <CaretDown\n size={size === 'md' ? 'sm' : 'xs'}\n style=\"bold\"\n />\n </button>\n );\n }\n);\n\nSplitButtonTrigger.displayName = 'SplitButtonTrigger';\n","import { cn } from '@evolve.ui/theme-system';\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingList,\n FloatingPortal,\n FloatingTree,\n offset,\n Placement,\n shift,\n size,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingTree,\n useInteractions,\n useListNavigation,\n useRole,\n useTypeahead,\n} from '@floating-ui/react';\nimport { ReactNode, useEffect, useRef, useState } from 'react';\n\nimport { Button } from '../Button/Button';\nimport { MenuContext } from '../Menu/context/menuContext';\nimport { SplitButtonTrigger } from './SplitButtonTrigger';\n\n/** SSR guard — prevents hydration mismatch on FloatingPortal (same pattern as Menu.tsx) */\nconst useHasMounted = () => {\n const [hasMounted, setHasMounted] = useState(false);\n useEffect(() => {\n setHasMounted(true);\n }, []);\n return hasMounted;\n};\n\ntype Props = {\n /**\n * Accessible label for the split button group wrapper.\n * Defaults to the string value of `label` when `label` is a string.\n */\n 'aria-label'?: string;\n /**\n * `MenuItem` components to render inside the dropdown.\n *\n * Usage:\n * ```tsx\n * <SplitButton label=\"Export CSV\" onDefaultAction={handleExport}>\n * <MenuItem primaryLabel=\"Export PDF\" onClick={handlePdf} />\n * <MenuItem primaryLabel=\"Export Excel\" onClick={handleExcel} />\n * </SplitButton>\n * ```\n */\n children: ReactNode;\n /** Additional CSS class applied to the wrapper element */\n className?: string;\n /** Test id applied to the wrapper element for consumer test targeting */\n 'data-testid'?: string;\n /** Disables both the default action button and the menu trigger */\n disabled?: boolean;\n /** Label for the default action button */\n label: ReactNode;\n /**\n * Shows a loading spinner on the default action button and disables the\n * dropdown trigger to prevent new selections while an action is in-flight.\n *\n * @default false\n */\n loading?: boolean;\n /**\n * Preferred placement of the dropdown menu. Flip middleware will\n * automatically move it to the opposite side if there is insufficient\n * viewport space.\n *\n * @default 'bottom-start'\n */\n menuPlacement?: Placement;\n /**\n * Accessible label for the menu trigger (caret) button.\n * Defaults to `\"See more {label} actions\"` when `label` is a string.\n */\n menuTriggerAriaLabel?: string;\n /** Callback fired when the default action button is clicked */\n onDefaultAction: () => void;\n /**\n * Button size.\n *\n * @default 'md'\n */\n size?: 'md' | 'sm';\n /**\n * Visual variant — `'filled'` (primary) or `'outlined'` (secondary).\n *\n * @default 'filled'\n */\n variant?: 'filled' | 'outlined';\n};\n\nconst SplitButtonContent = ({\n 'aria-label': ariaLabel,\n children,\n className,\n 'data-testid': dataTestId,\n disabled = false,\n label,\n loading = false,\n menuPlacement = 'bottom-start',\n menuTriggerAriaLabel,\n onDefaultAction,\n size: sizeProp = 'md',\n variant = 'filled',\n}: Props) => {\n const [isOpen, setIsOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const elementsRef = useRef<Array<HTMLSpanElement | null>>([]);\n const labelsRef = useRef<Array<string | null>>([]);\n const hasMounted = useHasMounted();\n\n const tree = useFloatingTree();\n const nodeId = useFloatingNodeId();\n\n const { context, floatingStyles, refs } = useFloating<HTMLDivElement>({\n middleware: [\n offset(8),\n flip(),\n shift({ padding: 2 }),\n // Match the menu width to the full button width (action + trigger combined)\n size({\n apply({ elements, rects }) {\n elements.floating.style.minWidth = `${rects.reference.width}px`;\n },\n }),\n ],\n nodeId,\n onOpenChange: setIsOpen,\n open: isOpen,\n placement: menuPlacement,\n whileElementsMounted: autoUpdate,\n });\n\n const click = useClick(context, { event: 'click' });\n const dismiss = useDismiss(context, { bubbles: true });\n const role = useRole(context, { role: 'menu' });\n const listNavigation = useListNavigation(context, {\n activeIndex,\n focusItemOnOpen: false,\n listRef: elementsRef,\n onNavigate: setActiveIndex,\n });\n\n const typeahead = useTypeahead(context, {\n activeIndex,\n listRef: labelsRef,\n onMatch: isOpen ? setActiveIndex : undefined,\n });\n\n const { getFloatingProps, getItemProps, getReferenceProps } = useInteractions([\n click,\n dismiss,\n role,\n listNavigation,\n typeahead,\n ]);\n\n // Close the dropdown when any MenuItem fires its click tree event.\n // MenuItem calls tree.events.emit('click') on selection, so we listen here\n // rather than relying on DOM event bubbling (which MenuItem stops).\n useEffect(() => {\n if (!tree) {\n return;\n }\n\n function handleTreeClick() {\n setIsOpen(false);\n }\n\n tree.events.on('click', handleTreeClick);\n return () => {\n tree.events.off('click', handleTreeClick);\n };\n }, [tree]);\n\n const resolvedMenuTriggerAriaLabel =\n menuTriggerAriaLabel ?? (typeof label === 'string' ? `See more ${label} actions` : 'See more actions');\n\n return (\n // The wrapper div is the floating-ui reference so placement and min-width\n // are relative to the full combined button, not just the caret trigger.\n <div\n aria-label={ariaLabel ?? (typeof label === 'string' ? label : undefined)}\n className={cn('relative inline-flex items-stretch', className)}\n data-hui-id=\"SplitButton\"\n data-testid={dataTestId}\n ref={refs.setReference}\n role=\"group\"\n >\n <Button\n className={cn(\n '!rounded-r-none',\n loading && {\n '!outline-border-disabled': variant === 'outlined',\n }\n )}\n disabled={disabled}\n loading={loading}\n onClick={onDefaultAction}\n size={sizeProp}\n style=\"primary\"\n variant={variant}\n >\n {label}\n </Button>\n\n {variant === 'filled' && (\n <div\n aria-hidden\n className=\"w-px shrink-0 self-stretch bg-text-inverse\"\n />\n )}\n\n <SplitButtonTrigger\n aria-label={resolvedMenuTriggerAriaLabel}\n className={cn(\n // When loading (not genuinely disabled), keep active visual styles\n // but let disabled:cursor-not-allowed through for the not-allowed cursor.\n loading && !disabled && variant === 'filled' && 'disabled:!bg-primary-500',\n loading &&\n !disabled &&\n variant === 'outlined' &&\n 'disabled:!bg-background-primary disabled:!outline-primary-500'\n )}\n disabled={disabled || loading}\n isOpen={isOpen}\n size={sizeProp}\n variant={variant}\n {...getReferenceProps()}\n />\n\n <MenuContext.Provider\n value={{\n activeIndex,\n getItemProps,\n isOpen,\n numberOfColumns: 1,\n setActiveIndex,\n }}\n >\n <FloatingList\n elementsRef={elementsRef}\n labelsRef={labelsRef}\n >\n {isOpen && hasMounted && Boolean(refs.domReference) && (\n <FloatingPortal root={refs.domReference}>\n <FloatingFocusManager\n context={context}\n initialFocus={-1}\n modal={false}\n returnFocus\n >\n <div\n className=\"Menu z-50 cursor-default whitespace-nowrap rounded-container bg-background-primary py-xs text-text-primary shadow-03 outline-0\"\n data-testid=\"split-button-menu\"\n ref={refs.setFloating}\n style={floatingStyles}\n {...getFloatingProps()}\n >\n {children}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </FloatingList>\n </MenuContext.Provider>\n </div>\n );\n};\n\n/**\n * A split button pairs a primary default action with a dropdown menu of\n * related secondary actions. The left button triggers the action immediately;\n * the right caret button opens the dropdown.\n *\n * Use `MenuItem` children to populate the dropdown:\n * ```tsx\n * <SplitButton label=\"Export CSV\" onDefaultAction={handleExport}>\n * <MenuItem primaryLabel=\"Export PDF\" onClick={handlePdf} />\n * <MenuItem primaryLabel=\"Export Excel\" onClick={handleExcel} />\n * </SplitButton>\n * ```\n */\nexport const SplitButton = (props: Props) => (\n <FloatingTree>\n <SplitButtonContent {...props} />\n </FloatingTree>\n);\n\nSplitButton.displayName = 'SplitButton';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SplitButton-B_Y253RU.cjs","names":["filledPrimaryClasses","outlinedPrimaryClasses","CaretDown","autoUpdate","Button","MenuContext","FloatingList","FloatingPortal","FloatingFocusManager","FloatingTree"],"sources":["../src/SplitButton/SplitButtonTrigger.tsx","../src/SplitButton/SplitButton.tsx"],"sourcesContent":["import { cn } from '@evolve.ui/theme-system';\nimport { forwardRef, HTMLProps } from 'react';\n\nimport { filledPrimaryClasses, outlinedPrimaryClasses } from '../Button/buttonColorClasses';\nimport { CaretDown } from '../Icons/generatedIcons/CaretDown';\n\ntype Props = {\n /** Whether the menu is currently open — applies pressed visual state to the trigger */\n isOpen?: boolean;\n /** Button size, should match the adjacent default action button */\n size?: 'md' | 'sm';\n /** Visual variant */\n variant?: 'filled' | 'outlined';\n} & Omit<HTMLProps<HTMLButtonElement>, 'size' | 'type'>;\n\n/**\n * The caret trigger button used inside `SplitButton`. Renders a square button\n * with a `CaretDown` icon, styled to join seamlessly with the default action button.\n *\n * Not intended for standalone use — use `SplitButton` instead.\n */\nexport const SplitButtonTrigger = forwardRef<HTMLButtonElement, Props>(\n ({ className, disabled = false, isOpen = false, size = 'md', variant = 'filled', ...rest }, ref) => {\n const isFilled = variant === 'filled';\n\n return (\n <button\n className={cn(\n 'hui-focus-visible-outline relative flex items-center justify-center rounded-l-none rounded-r-button outline outline-1 -outline-offset-1 transition-colors',\n isFilled ? filledPrimaryClasses : cn(outlinedPrimaryClasses, 'ml-[-1px]'),\n {\n 'size-[34px]': size === 'sm',\n 'size-[42px]': size === 'md',\n // Force the pressed/active visual while the menu is open\n '!bg-primary-200 !text-primary-900': isOpen && !isFilled,\n '!bg-primary-900': isOpen && isFilled,\n },\n className\n )}\n data-hui-id=\"SplitButtonTrigger\"\n disabled={disabled}\n ref={ref}\n type=\"button\"\n {...rest}\n >\n <CaretDown\n size={size === 'md' ? 'sm' : 'xs'}\n style=\"bold\"\n />\n </button>\n );\n }\n);\n\nSplitButtonTrigger.displayName = 'SplitButtonTrigger';\n","import { cn } from '@evolve.ui/theme-system';\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingList,\n FloatingPortal,\n FloatingTree,\n offset,\n Placement,\n shift,\n size,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingTree,\n useInteractions,\n useListNavigation,\n useRole,\n useTypeahead,\n} from '@floating-ui/react';\nimport { ReactNode, useEffect, useRef, useState } from 'react';\n\nimport { Button } from '../Button/Button';\nimport { MenuContext } from '../Menu/context/menuContext';\nimport { SplitButtonTrigger } from './SplitButtonTrigger';\n\n/** SSR guard — prevents hydration mismatch on FloatingPortal (same pattern as Menu.tsx) */\nconst useHasMounted = () => {\n const [hasMounted, setHasMounted] = useState(false);\n useEffect(() => {\n setHasMounted(true);\n }, []);\n return hasMounted;\n};\n\ntype Props = {\n /**\n * Accessible label for the split button group wrapper.\n * Defaults to the string value of `label` when `label` is a string.\n */\n 'aria-label'?: string;\n /**\n * `MenuItem` components to render inside the dropdown.\n *\n * Usage:\n * ```tsx\n * <SplitButton label=\"Export CSV\" onDefaultAction={handleExport}>\n * <MenuItem primaryLabel=\"Export PDF\" onClick={handlePdf} />\n * <MenuItem primaryLabel=\"Export Excel\" onClick={handleExcel} />\n * </SplitButton>\n * ```\n */\n children: ReactNode;\n /** Additional CSS class applied to the wrapper element */\n className?: string;\n /** Test id applied to the wrapper element for consumer test targeting */\n 'data-testid'?: string;\n /** Disables both the default action button and the menu trigger */\n disabled?: boolean;\n /** Label for the default action button */\n label: ReactNode;\n /**\n * Shows a loading spinner on the default action button and disables the\n * dropdown trigger to prevent new selections while an action is in-flight.\n *\n * @default false\n */\n loading?: boolean;\n /**\n * Preferred placement of the dropdown menu. Flip middleware will\n * automatically move it to the opposite side if there is insufficient\n * viewport space.\n *\n * @default 'bottom-start'\n */\n menuPlacement?: Placement;\n /**\n * Accessible label for the menu trigger (caret) button.\n * Defaults to `\"See more {label} actions\"` when `label` is a string.\n */\n menuTriggerAriaLabel?: string;\n /** Callback fired when the default action button is clicked */\n onDefaultAction: () => void;\n /**\n * Button size.\n *\n * @default 'md'\n */\n size?: 'md' | 'sm';\n /**\n * Visual variant — `'filled'` (primary) or `'outlined'` (secondary).\n *\n * @default 'filled'\n */\n variant?: 'filled' | 'outlined';\n};\n\nconst SplitButtonContent = ({\n 'aria-label': ariaLabel,\n children,\n className,\n 'data-testid': dataTestId,\n disabled = false,\n label,\n loading = false,\n menuPlacement = 'bottom-start',\n menuTriggerAriaLabel,\n onDefaultAction,\n size: sizeProp = 'md',\n variant = 'filled',\n}: Props) => {\n const [isOpen, setIsOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const elementsRef = useRef<Array<HTMLSpanElement | null>>([]);\n const labelsRef = useRef<Array<string | null>>([]);\n const hasMounted = useHasMounted();\n\n const tree = useFloatingTree();\n const nodeId = useFloatingNodeId();\n\n const { context, floatingStyles, refs } = useFloating<HTMLDivElement>({\n middleware: [\n offset(8),\n flip(),\n shift({ padding: 2 }),\n // Match the menu width to the full button width (action + trigger combined)\n size({\n apply({ elements, rects }) {\n elements.floating.style.minWidth = `${rects.reference.width}px`;\n },\n }),\n ],\n nodeId,\n onOpenChange: setIsOpen,\n open: isOpen,\n placement: menuPlacement,\n whileElementsMounted: autoUpdate,\n });\n\n const click = useClick(context, { event: 'click' });\n const dismiss = useDismiss(context, { bubbles: true });\n const role = useRole(context, { role: 'menu' });\n const listNavigation = useListNavigation(context, {\n activeIndex,\n focusItemOnOpen: false,\n listRef: elementsRef,\n onNavigate: setActiveIndex,\n });\n\n const typeahead = useTypeahead(context, {\n activeIndex,\n listRef: labelsRef,\n onMatch: isOpen ? setActiveIndex : undefined,\n });\n\n const { getFloatingProps, getItemProps, getReferenceProps } = useInteractions([\n click,\n dismiss,\n role,\n listNavigation,\n typeahead,\n ]);\n\n // Close the dropdown when any MenuItem fires its click tree event.\n // MenuItem calls tree.events.emit('click') on selection, so we listen here\n // rather than relying on DOM event bubbling (which MenuItem stops).\n useEffect(() => {\n if (!tree) {\n return;\n }\n\n function handleTreeClick() {\n setIsOpen(false);\n }\n\n tree.events.on('click', handleTreeClick);\n return () => {\n tree.events.off('click', handleTreeClick);\n };\n }, [tree]);\n\n const resolvedMenuTriggerAriaLabel =\n menuTriggerAriaLabel ?? (typeof label === 'string' ? `See more ${label} actions` : 'See more actions');\n\n return (\n // The wrapper div is the floating-ui reference so placement and min-width\n // are relative to the full combined button, not just the caret trigger.\n <div\n aria-label={ariaLabel ?? (typeof label === 'string' ? label : undefined)}\n className={cn('relative inline-flex items-stretch', className)}\n data-hui-id=\"SplitButton\"\n data-testid={dataTestId}\n ref={refs.setReference}\n role=\"group\"\n >\n <Button\n className={cn(\n '!rounded-r-none',\n loading && {\n '!outline-border-disabled': variant === 'outlined',\n }\n )}\n disabled={disabled}\n loading={loading}\n onClick={onDefaultAction}\n size={sizeProp}\n style=\"primary\"\n variant={variant}\n >\n {label}\n </Button>\n\n {variant === 'filled' && (\n <div\n aria-hidden\n className=\"w-px shrink-0 self-stretch bg-text-inverse\"\n />\n )}\n\n <SplitButtonTrigger\n aria-label={resolvedMenuTriggerAriaLabel}\n className={cn(\n // When loading (not genuinely disabled), keep active visual styles\n // but let disabled:cursor-not-allowed through for the not-allowed cursor.\n loading && !disabled && variant === 'filled' && 'disabled:!bg-primary-500',\n loading &&\n !disabled &&\n variant === 'outlined' &&\n 'disabled:!bg-background-primary disabled:!outline-primary-500'\n )}\n disabled={disabled || loading}\n isOpen={isOpen}\n size={sizeProp}\n variant={variant}\n {...getReferenceProps()}\n />\n\n <MenuContext.Provider\n value={{\n activeIndex,\n getItemProps,\n isOpen,\n numberOfColumns: 1,\n setActiveIndex,\n }}\n >\n <FloatingList\n elementsRef={elementsRef}\n labelsRef={labelsRef}\n >\n {isOpen && hasMounted && Boolean(refs.domReference) && (\n <FloatingPortal root={refs.domReference}>\n <FloatingFocusManager\n context={context}\n initialFocus={-1}\n modal={false}\n returnFocus\n >\n <div\n className=\"Menu z-50 cursor-default whitespace-nowrap rounded-container bg-background-primary py-xs text-text-primary shadow-03 outline-0\"\n data-testid=\"split-button-menu\"\n ref={refs.setFloating}\n style={floatingStyles}\n {...getFloatingProps()}\n >\n {children}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </FloatingList>\n </MenuContext.Provider>\n </div>\n );\n};\n\n/**\n * A split button pairs a primary default action with a dropdown menu of\n * related secondary actions. The left button triggers the action immediately;\n * the right caret button opens the dropdown.\n *\n * Use `MenuItem` children to populate the dropdown:\n * ```tsx\n * <SplitButton label=\"Export CSV\" onDefaultAction={handleExport}>\n * <MenuItem primaryLabel=\"Export PDF\" onClick={handlePdf} />\n * <MenuItem primaryLabel=\"Export Excel\" onClick={handleExcel} />\n * </SplitButton>\n * ```\n */\nexport const SplitButton = (props: Props) => (\n <FloatingTree>\n <SplitButtonContent {...props} />\n </FloatingTree>\n);\n\nSplitButton.displayName = 'SplitButton';\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CaretDown } from "./Icons.mjs";
|
|
2
|
-
import { c as outlinedPrimaryClasses, i as filledPrimaryClasses } from "./buttonColorClasses-
|
|
2
|
+
import { c as outlinedPrimaryClasses, i as filledPrimaryClasses } from "./buttonColorClasses-CQnqAJXl.mjs";
|
|
3
3
|
import { Button } from "./Button.mjs";
|
|
4
4
|
import { t as MenuContext } from "./menuContext-4P6eKzkH.mjs";
|
|
5
5
|
import { cn } from "@evolve.ui/theme-system";
|
|
@@ -176,4 +176,4 @@ SplitButton.displayName = "SplitButton";
|
|
|
176
176
|
//#endregion
|
|
177
177
|
export { SplitButton as t };
|
|
178
178
|
|
|
179
|
-
//# sourceMappingURL=SplitButton-
|
|
179
|
+
//# sourceMappingURL=SplitButton-_poP9Ykq.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SplitButton-WE5ymwCQ.mjs","names":[],"sources":["../src/SplitButton/SplitButtonTrigger.tsx","../src/SplitButton/SplitButton.tsx"],"sourcesContent":["import { cn } from '@evolve.ui/theme-system';\nimport { forwardRef, HTMLProps } from 'react';\n\nimport { filledPrimaryClasses, outlinedPrimaryClasses } from '../Button/buttonColorClasses';\nimport { CaretDown } from '../Icons/generatedIcons/CaretDown';\n\ntype Props = {\n /** Whether the menu is currently open — applies pressed visual state to the trigger */\n isOpen?: boolean;\n /** Button size, should match the adjacent default action button */\n size?: 'md' | 'sm';\n /** Visual variant */\n variant?: 'filled' | 'outlined';\n} & Omit<HTMLProps<HTMLButtonElement>, 'size' | 'type'>;\n\n/**\n * The caret trigger button used inside `SplitButton`. Renders a square button\n * with a `CaretDown` icon, styled to join seamlessly with the default action button.\n *\n * Not intended for standalone use — use `SplitButton` instead.\n */\nexport const SplitButtonTrigger = forwardRef<HTMLButtonElement, Props>(\n ({ className, disabled = false, isOpen = false, size = 'md', variant = 'filled', ...rest }, ref) => {\n const isFilled = variant === 'filled';\n\n return (\n <button\n className={cn(\n 'hui-focus-visible-outline relative flex items-center justify-center rounded-l-none rounded-r-button outline outline-1 -outline-offset-1 transition-colors',\n isFilled ? filledPrimaryClasses : cn(outlinedPrimaryClasses, 'ml-[-1px]'),\n {\n 'size-[34px]': size === 'sm',\n 'size-[42px]': size === 'md',\n // Force the pressed/active visual while the menu is open\n '!bg-primary-200 !text-primary-900': isOpen && !isFilled,\n '!bg-primary-900': isOpen && isFilled,\n },\n className\n )}\n data-hui-id=\"SplitButtonTrigger\"\n disabled={disabled}\n ref={ref}\n type=\"button\"\n {...rest}\n >\n <CaretDown\n size={size === 'md' ? 'sm' : 'xs'}\n style=\"bold\"\n />\n </button>\n );\n }\n);\n\nSplitButtonTrigger.displayName = 'SplitButtonTrigger';\n","import { cn } from '@evolve.ui/theme-system';\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingList,\n FloatingPortal,\n FloatingTree,\n offset,\n Placement,\n shift,\n size,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingTree,\n useInteractions,\n useListNavigation,\n useRole,\n useTypeahead,\n} from '@floating-ui/react';\nimport { ReactNode, useEffect, useRef, useState } from 'react';\n\nimport { Button } from '../Button/Button';\nimport { MenuContext } from '../Menu/context/menuContext';\nimport { SplitButtonTrigger } from './SplitButtonTrigger';\n\n/** SSR guard — prevents hydration mismatch on FloatingPortal (same pattern as Menu.tsx) */\nconst useHasMounted = () => {\n const [hasMounted, setHasMounted] = useState(false);\n useEffect(() => {\n setHasMounted(true);\n }, []);\n return hasMounted;\n};\n\ntype Props = {\n /**\n * Accessible label for the split button group wrapper.\n * Defaults to the string value of `label` when `label` is a string.\n */\n 'aria-label'?: string;\n /**\n * `MenuItem` components to render inside the dropdown.\n *\n * Usage:\n * ```tsx\n * <SplitButton label=\"Export CSV\" onDefaultAction={handleExport}>\n * <MenuItem primaryLabel=\"Export PDF\" onClick={handlePdf} />\n * <MenuItem primaryLabel=\"Export Excel\" onClick={handleExcel} />\n * </SplitButton>\n * ```\n */\n children: ReactNode;\n /** Additional CSS class applied to the wrapper element */\n className?: string;\n /** Test id applied to the wrapper element for consumer test targeting */\n 'data-testid'?: string;\n /** Disables both the default action button and the menu trigger */\n disabled?: boolean;\n /** Label for the default action button */\n label: ReactNode;\n /**\n * Shows a loading spinner on the default action button and disables the\n * dropdown trigger to prevent new selections while an action is in-flight.\n *\n * @default false\n */\n loading?: boolean;\n /**\n * Preferred placement of the dropdown menu. Flip middleware will\n * automatically move it to the opposite side if there is insufficient\n * viewport space.\n *\n * @default 'bottom-start'\n */\n menuPlacement?: Placement;\n /**\n * Accessible label for the menu trigger (caret) button.\n * Defaults to `\"See more {label} actions\"` when `label` is a string.\n */\n menuTriggerAriaLabel?: string;\n /** Callback fired when the default action button is clicked */\n onDefaultAction: () => void;\n /**\n * Button size.\n *\n * @default 'md'\n */\n size?: 'md' | 'sm';\n /**\n * Visual variant — `'filled'` (primary) or `'outlined'` (secondary).\n *\n * @default 'filled'\n */\n variant?: 'filled' | 'outlined';\n};\n\nconst SplitButtonContent = ({\n 'aria-label': ariaLabel,\n children,\n className,\n 'data-testid': dataTestId,\n disabled = false,\n label,\n loading = false,\n menuPlacement = 'bottom-start',\n menuTriggerAriaLabel,\n onDefaultAction,\n size: sizeProp = 'md',\n variant = 'filled',\n}: Props) => {\n const [isOpen, setIsOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const elementsRef = useRef<Array<HTMLSpanElement | null>>([]);\n const labelsRef = useRef<Array<string | null>>([]);\n const hasMounted = useHasMounted();\n\n const tree = useFloatingTree();\n const nodeId = useFloatingNodeId();\n\n const { context, floatingStyles, refs } = useFloating<HTMLDivElement>({\n middleware: [\n offset(8),\n flip(),\n shift({ padding: 2 }),\n // Match the menu width to the full button width (action + trigger combined)\n size({\n apply({ elements, rects }) {\n elements.floating.style.minWidth = `${rects.reference.width}px`;\n },\n }),\n ],\n nodeId,\n onOpenChange: setIsOpen,\n open: isOpen,\n placement: menuPlacement,\n whileElementsMounted: autoUpdate,\n });\n\n const click = useClick(context, { event: 'click' });\n const dismiss = useDismiss(context, { bubbles: true });\n const role = useRole(context, { role: 'menu' });\n const listNavigation = useListNavigation(context, {\n activeIndex,\n focusItemOnOpen: false,\n listRef: elementsRef,\n onNavigate: setActiveIndex,\n });\n\n const typeahead = useTypeahead(context, {\n activeIndex,\n listRef: labelsRef,\n onMatch: isOpen ? setActiveIndex : undefined,\n });\n\n const { getFloatingProps, getItemProps, getReferenceProps } = useInteractions([\n click,\n dismiss,\n role,\n listNavigation,\n typeahead,\n ]);\n\n // Close the dropdown when any MenuItem fires its click tree event.\n // MenuItem calls tree.events.emit('click') on selection, so we listen here\n // rather than relying on DOM event bubbling (which MenuItem stops).\n useEffect(() => {\n if (!tree) {\n return;\n }\n\n function handleTreeClick() {\n setIsOpen(false);\n }\n\n tree.events.on('click', handleTreeClick);\n return () => {\n tree.events.off('click', handleTreeClick);\n };\n }, [tree]);\n\n const resolvedMenuTriggerAriaLabel =\n menuTriggerAriaLabel ?? (typeof label === 'string' ? `See more ${label} actions` : 'See more actions');\n\n return (\n // The wrapper div is the floating-ui reference so placement and min-width\n // are relative to the full combined button, not just the caret trigger.\n <div\n aria-label={ariaLabel ?? (typeof label === 'string' ? label : undefined)}\n className={cn('relative inline-flex items-stretch', className)}\n data-hui-id=\"SplitButton\"\n data-testid={dataTestId}\n ref={refs.setReference}\n role=\"group\"\n >\n <Button\n className={cn(\n '!rounded-r-none',\n loading && {\n '!outline-border-disabled': variant === 'outlined',\n }\n )}\n disabled={disabled}\n loading={loading}\n onClick={onDefaultAction}\n size={sizeProp}\n style=\"primary\"\n variant={variant}\n >\n {label}\n </Button>\n\n {variant === 'filled' && (\n <div\n aria-hidden\n className=\"w-px shrink-0 self-stretch bg-text-inverse\"\n />\n )}\n\n <SplitButtonTrigger\n aria-label={resolvedMenuTriggerAriaLabel}\n className={cn(\n // When loading (not genuinely disabled), keep active visual styles\n // but let disabled:cursor-not-allowed through for the not-allowed cursor.\n loading && !disabled && variant === 'filled' && 'disabled:!bg-primary-500',\n loading &&\n !disabled &&\n variant === 'outlined' &&\n 'disabled:!bg-background-primary disabled:!outline-primary-500'\n )}\n disabled={disabled || loading}\n isOpen={isOpen}\n size={sizeProp}\n variant={variant}\n {...getReferenceProps()}\n />\n\n <MenuContext.Provider\n value={{\n activeIndex,\n getItemProps,\n isOpen,\n numberOfColumns: 1,\n setActiveIndex,\n }}\n >\n <FloatingList\n elementsRef={elementsRef}\n labelsRef={labelsRef}\n >\n {isOpen && hasMounted && Boolean(refs.domReference) && (\n <FloatingPortal root={refs.domReference}>\n <FloatingFocusManager\n context={context}\n initialFocus={-1}\n modal={false}\n returnFocus\n >\n <div\n className=\"Menu z-50 cursor-default whitespace-nowrap rounded-container bg-background-primary py-xs text-text-primary shadow-03 outline-0\"\n data-testid=\"split-button-menu\"\n ref={refs.setFloating}\n style={floatingStyles}\n {...getFloatingProps()}\n >\n {children}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </FloatingList>\n </MenuContext.Provider>\n </div>\n );\n};\n\n/**\n * A split button pairs a primary default action with a dropdown menu of\n * related secondary actions. The left button triggers the action immediately;\n * the right caret button opens the dropdown.\n *\n * Use `MenuItem` children to populate the dropdown:\n * ```tsx\n * <SplitButton label=\"Export CSV\" onDefaultAction={handleExport}>\n * <MenuItem primaryLabel=\"Export PDF\" onClick={handlePdf} />\n * <MenuItem primaryLabel=\"Export Excel\" onClick={handleExcel} />\n * </SplitButton>\n * ```\n */\nexport const SplitButton = (props: Props) => (\n <FloatingTree>\n <SplitButtonContent {...props} />\n </FloatingTree>\n);\n\nSplitButton.displayName = 'SplitButton';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"SplitButton-_poP9Ykq.mjs","names":[],"sources":["../src/SplitButton/SplitButtonTrigger.tsx","../src/SplitButton/SplitButton.tsx"],"sourcesContent":["import { cn } from '@evolve.ui/theme-system';\nimport { forwardRef, HTMLProps } from 'react';\n\nimport { filledPrimaryClasses, outlinedPrimaryClasses } from '../Button/buttonColorClasses';\nimport { CaretDown } from '../Icons/generatedIcons/CaretDown';\n\ntype Props = {\n /** Whether the menu is currently open — applies pressed visual state to the trigger */\n isOpen?: boolean;\n /** Button size, should match the adjacent default action button */\n size?: 'md' | 'sm';\n /** Visual variant */\n variant?: 'filled' | 'outlined';\n} & Omit<HTMLProps<HTMLButtonElement>, 'size' | 'type'>;\n\n/**\n * The caret trigger button used inside `SplitButton`. Renders a square button\n * with a `CaretDown` icon, styled to join seamlessly with the default action button.\n *\n * Not intended for standalone use — use `SplitButton` instead.\n */\nexport const SplitButtonTrigger = forwardRef<HTMLButtonElement, Props>(\n ({ className, disabled = false, isOpen = false, size = 'md', variant = 'filled', ...rest }, ref) => {\n const isFilled = variant === 'filled';\n\n return (\n <button\n className={cn(\n 'hui-focus-visible-outline relative flex items-center justify-center rounded-l-none rounded-r-button outline outline-1 -outline-offset-1 transition-colors',\n isFilled ? filledPrimaryClasses : cn(outlinedPrimaryClasses, 'ml-[-1px]'),\n {\n 'size-[34px]': size === 'sm',\n 'size-[42px]': size === 'md',\n // Force the pressed/active visual while the menu is open\n '!bg-primary-200 !text-primary-900': isOpen && !isFilled,\n '!bg-primary-900': isOpen && isFilled,\n },\n className\n )}\n data-hui-id=\"SplitButtonTrigger\"\n disabled={disabled}\n ref={ref}\n type=\"button\"\n {...rest}\n >\n <CaretDown\n size={size === 'md' ? 'sm' : 'xs'}\n style=\"bold\"\n />\n </button>\n );\n }\n);\n\nSplitButtonTrigger.displayName = 'SplitButtonTrigger';\n","import { cn } from '@evolve.ui/theme-system';\nimport {\n autoUpdate,\n flip,\n FloatingFocusManager,\n FloatingList,\n FloatingPortal,\n FloatingTree,\n offset,\n Placement,\n shift,\n size,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingTree,\n useInteractions,\n useListNavigation,\n useRole,\n useTypeahead,\n} from '@floating-ui/react';\nimport { ReactNode, useEffect, useRef, useState } from 'react';\n\nimport { Button } from '../Button/Button';\nimport { MenuContext } from '../Menu/context/menuContext';\nimport { SplitButtonTrigger } from './SplitButtonTrigger';\n\n/** SSR guard — prevents hydration mismatch on FloatingPortal (same pattern as Menu.tsx) */\nconst useHasMounted = () => {\n const [hasMounted, setHasMounted] = useState(false);\n useEffect(() => {\n setHasMounted(true);\n }, []);\n return hasMounted;\n};\n\ntype Props = {\n /**\n * Accessible label for the split button group wrapper.\n * Defaults to the string value of `label` when `label` is a string.\n */\n 'aria-label'?: string;\n /**\n * `MenuItem` components to render inside the dropdown.\n *\n * Usage:\n * ```tsx\n * <SplitButton label=\"Export CSV\" onDefaultAction={handleExport}>\n * <MenuItem primaryLabel=\"Export PDF\" onClick={handlePdf} />\n * <MenuItem primaryLabel=\"Export Excel\" onClick={handleExcel} />\n * </SplitButton>\n * ```\n */\n children: ReactNode;\n /** Additional CSS class applied to the wrapper element */\n className?: string;\n /** Test id applied to the wrapper element for consumer test targeting */\n 'data-testid'?: string;\n /** Disables both the default action button and the menu trigger */\n disabled?: boolean;\n /** Label for the default action button */\n label: ReactNode;\n /**\n * Shows a loading spinner on the default action button and disables the\n * dropdown trigger to prevent new selections while an action is in-flight.\n *\n * @default false\n */\n loading?: boolean;\n /**\n * Preferred placement of the dropdown menu. Flip middleware will\n * automatically move it to the opposite side if there is insufficient\n * viewport space.\n *\n * @default 'bottom-start'\n */\n menuPlacement?: Placement;\n /**\n * Accessible label for the menu trigger (caret) button.\n * Defaults to `\"See more {label} actions\"` when `label` is a string.\n */\n menuTriggerAriaLabel?: string;\n /** Callback fired when the default action button is clicked */\n onDefaultAction: () => void;\n /**\n * Button size.\n *\n * @default 'md'\n */\n size?: 'md' | 'sm';\n /**\n * Visual variant — `'filled'` (primary) or `'outlined'` (secondary).\n *\n * @default 'filled'\n */\n variant?: 'filled' | 'outlined';\n};\n\nconst SplitButtonContent = ({\n 'aria-label': ariaLabel,\n children,\n className,\n 'data-testid': dataTestId,\n disabled = false,\n label,\n loading = false,\n menuPlacement = 'bottom-start',\n menuTriggerAriaLabel,\n onDefaultAction,\n size: sizeProp = 'md',\n variant = 'filled',\n}: Props) => {\n const [isOpen, setIsOpen] = useState(false);\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const elementsRef = useRef<Array<HTMLSpanElement | null>>([]);\n const labelsRef = useRef<Array<string | null>>([]);\n const hasMounted = useHasMounted();\n\n const tree = useFloatingTree();\n const nodeId = useFloatingNodeId();\n\n const { context, floatingStyles, refs } = useFloating<HTMLDivElement>({\n middleware: [\n offset(8),\n flip(),\n shift({ padding: 2 }),\n // Match the menu width to the full button width (action + trigger combined)\n size({\n apply({ elements, rects }) {\n elements.floating.style.minWidth = `${rects.reference.width}px`;\n },\n }),\n ],\n nodeId,\n onOpenChange: setIsOpen,\n open: isOpen,\n placement: menuPlacement,\n whileElementsMounted: autoUpdate,\n });\n\n const click = useClick(context, { event: 'click' });\n const dismiss = useDismiss(context, { bubbles: true });\n const role = useRole(context, { role: 'menu' });\n const listNavigation = useListNavigation(context, {\n activeIndex,\n focusItemOnOpen: false,\n listRef: elementsRef,\n onNavigate: setActiveIndex,\n });\n\n const typeahead = useTypeahead(context, {\n activeIndex,\n listRef: labelsRef,\n onMatch: isOpen ? setActiveIndex : undefined,\n });\n\n const { getFloatingProps, getItemProps, getReferenceProps } = useInteractions([\n click,\n dismiss,\n role,\n listNavigation,\n typeahead,\n ]);\n\n // Close the dropdown when any MenuItem fires its click tree event.\n // MenuItem calls tree.events.emit('click') on selection, so we listen here\n // rather than relying on DOM event bubbling (which MenuItem stops).\n useEffect(() => {\n if (!tree) {\n return;\n }\n\n function handleTreeClick() {\n setIsOpen(false);\n }\n\n tree.events.on('click', handleTreeClick);\n return () => {\n tree.events.off('click', handleTreeClick);\n };\n }, [tree]);\n\n const resolvedMenuTriggerAriaLabel =\n menuTriggerAriaLabel ?? (typeof label === 'string' ? `See more ${label} actions` : 'See more actions');\n\n return (\n // The wrapper div is the floating-ui reference so placement and min-width\n // are relative to the full combined button, not just the caret trigger.\n <div\n aria-label={ariaLabel ?? (typeof label === 'string' ? label : undefined)}\n className={cn('relative inline-flex items-stretch', className)}\n data-hui-id=\"SplitButton\"\n data-testid={dataTestId}\n ref={refs.setReference}\n role=\"group\"\n >\n <Button\n className={cn(\n '!rounded-r-none',\n loading && {\n '!outline-border-disabled': variant === 'outlined',\n }\n )}\n disabled={disabled}\n loading={loading}\n onClick={onDefaultAction}\n size={sizeProp}\n style=\"primary\"\n variant={variant}\n >\n {label}\n </Button>\n\n {variant === 'filled' && (\n <div\n aria-hidden\n className=\"w-px shrink-0 self-stretch bg-text-inverse\"\n />\n )}\n\n <SplitButtonTrigger\n aria-label={resolvedMenuTriggerAriaLabel}\n className={cn(\n // When loading (not genuinely disabled), keep active visual styles\n // but let disabled:cursor-not-allowed through for the not-allowed cursor.\n loading && !disabled && variant === 'filled' && 'disabled:!bg-primary-500',\n loading &&\n !disabled &&\n variant === 'outlined' &&\n 'disabled:!bg-background-primary disabled:!outline-primary-500'\n )}\n disabled={disabled || loading}\n isOpen={isOpen}\n size={sizeProp}\n variant={variant}\n {...getReferenceProps()}\n />\n\n <MenuContext.Provider\n value={{\n activeIndex,\n getItemProps,\n isOpen,\n numberOfColumns: 1,\n setActiveIndex,\n }}\n >\n <FloatingList\n elementsRef={elementsRef}\n labelsRef={labelsRef}\n >\n {isOpen && hasMounted && Boolean(refs.domReference) && (\n <FloatingPortal root={refs.domReference}>\n <FloatingFocusManager\n context={context}\n initialFocus={-1}\n modal={false}\n returnFocus\n >\n <div\n className=\"Menu z-50 cursor-default whitespace-nowrap rounded-container bg-background-primary py-xs text-text-primary shadow-03 outline-0\"\n data-testid=\"split-button-menu\"\n ref={refs.setFloating}\n style={floatingStyles}\n {...getFloatingProps()}\n >\n {children}\n </div>\n </FloatingFocusManager>\n </FloatingPortal>\n )}\n </FloatingList>\n </MenuContext.Provider>\n </div>\n );\n};\n\n/**\n * A split button pairs a primary default action with a dropdown menu of\n * related secondary actions. The left button triggers the action immediately;\n * the right caret button opens the dropdown.\n *\n * Use `MenuItem` children to populate the dropdown:\n * ```tsx\n * <SplitButton label=\"Export CSV\" onDefaultAction={handleExport}>\n * <MenuItem primaryLabel=\"Export PDF\" onClick={handlePdf} />\n * <MenuItem primaryLabel=\"Export Excel\" onClick={handleExcel} />\n * </SplitButton>\n * ```\n */\nexport const SplitButton = (props: Props) => (\n <FloatingTree>\n <SplitButtonContent {...props} />\n </FloatingTree>\n);\n\nSplitButton.displayName = 'SplitButton';\n"],"mappings":"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"}
|
|
@@ -3,8 +3,8 @@ import { BodyPrimary, BodySecondary, H3 } from "./Typography/Text.mjs";
|
|
|
3
3
|
import { IconButton } from "./IconButton.mjs";
|
|
4
4
|
import { t as Checkbox } from "./ChoiceListItem-BqZ3bIj9.mjs";
|
|
5
5
|
import { t as Loading } from "./Loading-BenQpF_w.mjs";
|
|
6
|
-
import { i as usePagination, r as PaginationProvider, t as AdvancedPagination } from "./Pagination-
|
|
7
|
-
import { t as Select } from "./Select-
|
|
6
|
+
import { i as usePagination, r as PaginationProvider, t as AdvancedPagination } from "./Pagination-Dyfeys4B.mjs";
|
|
7
|
+
import { t as Select } from "./Select-CH_ZN88G.mjs";
|
|
8
8
|
import { cn } from "@evolve.ui/theme-system";
|
|
9
9
|
import { createContext, createElement, useCallback, useContext, useMemo, useState } from "react";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -492,4 +492,4 @@ const InnerTable = ({ actionableCheckbox, backgroundColor, className, columns, c
|
|
|
492
492
|
//#endregion
|
|
493
493
|
export { Table as t };
|
|
494
494
|
|
|
495
|
-
//# sourceMappingURL=Table-
|
|
495
|
+
//# sourceMappingURL=Table-CQGtDpvH.mjs.map
|