@evolve.ui/core-components 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (509) hide show
  1. package/evolve-ui.entries.json +556 -0
  2. package/fileUpload/testUtils/mockFilesAndImages.d.cts +3 -3
  3. package/fileUpload/testUtils/mockFilesAndImages.d.cts.map +1 -1
  4. package/fileUpload/testUtils/mockFilesAndImages.d.mts +3 -3
  5. package/fileUpload/testUtils/mockFilesAndImages.d.mts.map +1 -1
  6. package/fileUpload/testUtils/testUtils.d.cts +1 -1
  7. package/fileUpload/testUtils/testUtils.d.cts.map +1 -1
  8. package/fileUpload/testUtils/testUtils.d.mts +1 -1
  9. package/fileUpload/testUtils/testUtils.d.mts.map +1 -1
  10. package/package.json +2 -2
  11. package/src/Accordion/Accordion.tsx +233 -0
  12. package/src/AddressDisplay/AddressDisplay.tsx +43 -0
  13. package/src/AddressDisplay/components/addressComponents.tsx +111 -0
  14. package/src/AddressDisplay/components/addressField.tsx +25 -0
  15. package/src/AddressDisplay/components/addressSection.tsx +8 -0
  16. package/src/AddressDisplay/components/getCountryValue.tsx +31 -0
  17. package/src/AddressDisplay/types.ts +26 -0
  18. package/src/AutomatedCarousel/AutomatedCarousel.tsx +163 -0
  19. package/src/AutomatedCarousel/automatedCarousel.types.ts +7 -0
  20. package/src/AutomatedCarousel/components/CarouselProgressBar/CarouselProgressBar.tsx +139 -0
  21. package/src/AutomatedCarousel/components/CarouselProgressBar/components/CarouselProgressBarUnit/CarouselProgressBarUnit.tsx +165 -0
  22. package/src/Badge/Badge.tsx +104 -0
  23. package/src/Badge/Badge.types.ts +58 -0
  24. package/src/Badge/ItemBadge.tsx +97 -0
  25. package/src/Badge/LiveStatusBadge.tsx +93 -0
  26. package/src/BannerNotification/BannerNotification.tsx +157 -0
  27. package/src/BannerNotification/components/BannerNotificationSkeleton.tsx +39 -0
  28. package/src/BannerNotification/components/CalloutIcon/BannerIcon.tsx +48 -0
  29. package/src/BannerNotification/utils/getRandomTooltipId.ts +3 -0
  30. package/src/BottomSheet/BottomSheet.tsx +476 -0
  31. package/src/BottomSheet/components/BottomSheetBackdrop/BottomSheetBackdrop.tsx +47 -0
  32. package/src/BottomSheet/components/BottomSheetContentArea/BottomSheetContentArea.tsx +92 -0
  33. package/src/BottomSheet/components/BottomSheetOverlay/BottomSheetOverlayTranslate3d.tsx +196 -0
  34. package/src/BottomSheet/components/SheetDescription/SheetDescription.tsx +22 -0
  35. package/src/BottomSheet/components/SheetTitle/SheetTitle.tsx +21 -0
  36. package/src/BottomSheet/components/index.tsx +5 -0
  37. package/src/BottomSheet/hooks/index.tsx +13 -0
  38. package/src/BottomSheet/hooks/useAriaHider.tsx +91 -0
  39. package/src/BottomSheet/hooks/useBottomSheetServices.tsx +224 -0
  40. package/src/BottomSheet/hooks/useDragHandler.tsx +282 -0
  41. package/src/BottomSheet/hooks/useFocusTrap.tsx +113 -0
  42. package/src/BottomSheet/hooks/useLayoutEffect.tsx +4 -0
  43. package/src/BottomSheet/hooks/useOptimizedResizeObserver.tsx +94 -0
  44. package/src/BottomSheet/hooks/useOptimizedScrollState.tsx +87 -0
  45. package/src/BottomSheet/hooks/useReady.tsx +34 -0
  46. package/src/BottomSheet/hooks/useReducedMotion.tsx +22 -0
  47. package/src/BottomSheet/hooks/useScrollLock.tsx +143 -0
  48. package/src/BottomSheet/hooks/useSnapPoints.tsx +355 -0
  49. package/src/BottomSheet/hooks/useSpring.tsx +47 -0
  50. package/src/BottomSheet/hooks/useSpringInterpolationsTranslate3d.tsx +101 -0
  51. package/src/BottomSheet/index.tsx +237 -0
  52. package/src/BottomSheet/state/atoms.ts +147 -0
  53. package/src/BottomSheet/state/useBottomSheetStateMachine.ts +246 -0
  54. package/src/BottomSheet/types.ts +172 -0
  55. package/src/BottomSheet/utils.ts +65 -0
  56. package/src/Breadcrumbs/Breadcrumbs.tsx +126 -0
  57. package/src/Button/Button.tsx +164 -0
  58. package/src/Button/Button.types.ts +80 -0
  59. package/src/Button/buttonColorClasses.ts +53 -0
  60. package/src/Callout/Callout.tsx +136 -0
  61. package/src/Callout/Callout.types.ts +29 -0
  62. package/src/Callout/components/CalloutIcon/CalloutIcon.tsx +56 -0
  63. package/src/Card/CardGrid.tsx +263 -0
  64. package/src/Card/SingleCard.tsx +22 -0
  65. package/src/Card/cardFactory.tsx +176 -0
  66. package/src/Card/components/createBadge.tsx +34 -0
  67. package/src/Card/components/createFavoriteButton.tsx +40 -0
  68. package/src/Card/components/createImage.tsx +64 -0
  69. package/src/Card/components/createInfo.tsx +84 -0
  70. package/src/Card/components/createName.tsx +63 -0
  71. package/src/Card/components/createPriceStatus.tsx +100 -0
  72. package/src/Card/components/types.ts +4 -0
  73. package/src/Card/hooks/useCardVisibilityTracking.ts +82 -0
  74. package/src/Card/sharedProps.ts +12 -0
  75. package/src/Card/types.ts +62 -0
  76. package/src/Carousel/Carousel.tsx +513 -0
  77. package/src/Carousel/Carousel.types.ts +43 -0
  78. package/src/Carousel/Carousel.utils.ts +63 -0
  79. package/src/Carousel/components/DotButton/DotButton.tsx +42 -0
  80. package/src/Carousel/components/NavigationButtons/NavigationButtons.tsx +77 -0
  81. package/src/Carousel/components/TitleSection/TitleSection.tsx +61 -0
  82. package/src/Carousel/components/TitleSection/components/SubHeaderLeft/SubHeaderLeft.tsx +53 -0
  83. package/src/Carousel/components/TitleSection/components/Title/Title.tsx +46 -0
  84. package/src/Carousel/index.ts +2 -0
  85. package/src/Carousel/testUtils.ts +10 -0
  86. package/src/Chips/Chip.tsx +153 -0
  87. package/src/Chips/ChipGroup.tsx +173 -0
  88. package/src/Chips/SuggestionChip.tsx +15 -0
  89. package/src/Chips/chipTypes.ts +113 -0
  90. package/src/Chips/index.ts +4 -0
  91. package/src/ChoiceListItem/Checkbox.tsx +69 -0
  92. package/src/ChoiceListItem/Radio.tsx +61 -0
  93. package/src/ChoiceListItem/choiceListItem.tsx +99 -0
  94. package/src/ChoiceListItem/common.tsx +148 -0
  95. package/src/ChoiceListItem/index.ts +3 -0
  96. package/src/Collapsible/Collapsible.tsx +58 -0
  97. package/src/Confetti/Confetti.tsx +270 -0
  98. package/src/Confetti/index.ts +2 -0
  99. package/src/ContentPager/ContentPager.tsx +189 -0
  100. package/src/ContentPager/components/Page.tsx +24 -0
  101. package/src/CookieConsent/components/CookieCategoryRow/CookieCategoryRow.tsx +30 -0
  102. package/src/CookieConsent/components/CookieConsent/CookieConsent.tsx +74 -0
  103. package/src/CookieConsent/components/CookieConsentBanner/CookieConsentBanner.tsx +51 -0
  104. package/src/CookieConsent/components/CookieConsentModal/CookieConsentModal.tsx +64 -0
  105. package/src/CookieConsent/hooks/useCookieConsent.ts +170 -0
  106. package/src/CookieConsent/hooks/useCookieConsentState.ts +142 -0
  107. package/src/CookieConsent/index.ts +16 -0
  108. package/src/CookieConsent/types/cookieConsent.types.ts +79 -0
  109. package/src/CookieConsent/types/index.ts +7 -0
  110. package/src/Countdown/Countdown.tsx +161 -0
  111. package/src/Countdown/Countdown.types.ts +4 -0
  112. package/src/Countdown/hooks/useGetCountdown.ts +103 -0
  113. package/src/DateTimeInput/dateInput/DateInput.tsx +199 -0
  114. package/src/DateTimeInput/datePicker/DatePicker.tsx +138 -0
  115. package/src/DateTimeInput/datePicker/components/calendar/Calendar.tsx +72 -0
  116. package/src/DateTimeInput/datePicker/index.ts +2 -0
  117. package/src/DateTimeInput/timeInput/TimeInput.tsx +128 -0
  118. package/src/DateTimeInput/timePicker/TimePicker.tsx +118 -0
  119. package/src/DateTimeInput/timePicker/components/TimePopover/AmPmSwitch.tsx +103 -0
  120. package/src/DateTimeInput/timePicker/components/TimePopover/TimeFieldInput.tsx +26 -0
  121. package/src/DateTimeInput/timePicker/components/TimePopover/TimePopover.tsx +84 -0
  122. package/src/DateTimeInput/timePicker/components/TimePopover/TimePopover.utils.ts +67 -0
  123. package/src/DateTimeInput/timePicker/components/TimePopover/TimePopoverActions.tsx +26 -0
  124. package/src/DateTimeInput/timePicker/index.ts +2 -0
  125. package/src/DateTimeInput/utils/getDisplayDate.ts +15 -0
  126. package/src/DateTimeInput/utils/getDisplayTime.ts +15 -0
  127. package/src/DateTimeInput/utils/index.ts +2 -0
  128. package/src/DateTimeInput/utils/parseTimeValue.ts +54 -0
  129. package/src/Drawer/Drawer.tsx +446 -0
  130. package/src/Drawer/atoms.ts +4 -0
  131. package/src/Drawer/components/DialogActions/DialogActions.tsx +33 -0
  132. package/src/Drawer/components/DialogContent/DialogContent.tsx +80 -0
  133. package/src/Drawer/components/DialogHeader/DialogHeader.tsx +68 -0
  134. package/src/EducationalPopover/EducationalPopover.tsx +174 -0
  135. package/src/FavoriteButton/FavoriteButton.tsx +64 -0
  136. package/src/FavoriteButton/components/IconOnlyFavoriteButton/IconOnlyFavoriteButton.tsx +80 -0
  137. package/src/FavoriteButton/components/LabeledAnimatedFavoriteButton/LabeledAnimatedFavoriteButton.tsx +179 -0
  138. package/src/FavoriteButton/components/LabeledFavoriteButton/LabeledFavoriteButton.tsx +71 -0
  139. package/src/FavoriteButton/components/SmallHeartStraightIcon/SmallHeartStraightIcon.tsx +14 -0
  140. package/src/FavoriteButton/hooks/useFavoriteButtonState.ts +30 -0
  141. package/src/FavoriteButton/index.ts +2 -0
  142. package/src/FavoriteButton/types/favoriteButton.ts +87 -0
  143. package/src/FeatureFlags/devTools/FeatureFlagDevToolsUI.tsx +226 -0
  144. package/src/FeatureFlags/devTools/getFeatureFlagCookieOverrides.ts +30 -0
  145. package/src/FeatureFlags/devTools/utils/cookies.ts +169 -0
  146. package/src/FeatureFlags/hooks/index.ts +2 -0
  147. package/src/FeatureFlags/hooks/useFeatureFlag.tsx +19 -0
  148. package/src/FeatureFlags/hooks/useFeatureFlags.tsx +15 -0
  149. package/src/FileUpload/components/FileCard/FileCard.tsx +50 -0
  150. package/src/FileUpload/components/FileDropzone/FileDropzone.tsx +221 -0
  151. package/src/FileUpload/components/FileDropzone/components/DropzoneContent/DropzoneContent.tsx +28 -0
  152. package/src/FileUpload/components/FileDropzone/components/DropzoneContent/DropzoneText.tsx +81 -0
  153. package/src/FileUpload/components/FileDropzone/components/FileDropzoneDebugger/FileDropzoneDebugger.tsx +40 -0
  154. package/src/FileUpload/components/FileDropzone/components/FileDropzoneDebugger/FileRejectionsDisplay.tsx +110 -0
  155. package/src/FileUpload/components/FileDropzoneOverlay/FileDropzoneOverlay.tsx +183 -0
  156. package/src/FileUpload/components/FileDropzoneOverlay/components/OverlayDropzoneContent.tsx +146 -0
  157. package/src/FileUpload/components/FileDropzoneOverlay/components/OverlayDropzoneDragText.tsx +42 -0
  158. package/src/FileUpload/components/FileDropzoneOverlay/styles.ts +79 -0
  159. package/src/FileUpload/components/FilePreviewList/FilePreviewList.tsx +251 -0
  160. package/src/FileUpload/components/FilePreviewList/virtualizerComponents/FilePreviewVirtualizedList/FilePreviewVirtualizedList.tsx +88 -0
  161. package/src/FileUpload/components/FileUpload/FileUpload.tsx +63 -0
  162. package/src/FileUpload/components/FileUploadCanvas/FileUploadCanvas.tsx +125 -0
  163. package/src/FileUpload/components/GridFileCard/GridFileCard.tsx +364 -0
  164. package/src/FileUpload/components/GridFileCard/utils/sortable.ts +48 -0
  165. package/src/FileUpload/components/ListFileCard/ListFileCard.tsx +259 -0
  166. package/src/FileUpload/components/types.ts +78 -0
  167. package/src/FileUpload/hooks/filePreview/useImageFilePreviewUrl.ts +62 -0
  168. package/src/FileUpload/hooks/index.ts +11 -0
  169. package/src/FileUpload/hooks/upload/useHandleDragEnter/useHandleDragEnter.ts +154 -0
  170. package/src/FileUpload/hooks/upload/useHandleDrop/createFileRejectionHelpers.ts +273 -0
  171. package/src/FileUpload/hooks/upload/useHandleDrop/useHandleDrop.ts +153 -0
  172. package/src/FileUpload/hooks/upload/useUploadAvailability/useUploadAvailability.ts +44 -0
  173. package/src/FileUpload/hooks/validation/createDropzoneValidator.ts +41 -0
  174. package/src/FileUpload/hooks/validation/useFileValidation.ts +25 -0
  175. package/src/FileUpload/hooks/validation/useFileValidationLogic.ts +107 -0
  176. package/src/FileUpload/hooks/validation/useValidationMessages.ts +92 -0
  177. package/src/FileUpload/hooks/validation/useValidationState.ts +171 -0
  178. package/src/FileUpload/index.ts +57 -0
  179. package/src/FileUpload/providers/FileUploadProvider.tsx +219 -0
  180. package/src/FileUpload/providers/UploadValidationProvider.tsx +159 -0
  181. package/src/FileUpload/testUtils/mockFilesAndImages.ts +64 -0
  182. package/src/FileUpload/testUtils/testUtils.ts +111 -0
  183. package/src/FileUpload/types/commonTypes.ts +267 -0
  184. package/src/FileUpload/types/index.ts +31 -0
  185. package/src/FileUpload/types/sharedTypes.ts +159 -0
  186. package/src/FileUpload/utils/constants.ts +79 -0
  187. package/src/FileUpload/utils/createMessageContext.ts +180 -0
  188. package/src/FileUpload/utils/getFileExtensionsFromAcceptedTypes.ts +73 -0
  189. package/src/FileUpload/utils/getFilePluralizationText.ts +68 -0
  190. package/src/FileUpload/utils/getMimeTypes.ts +26 -0
  191. package/src/FileUpload/utils/messageUtils.ts +41 -0
  192. package/src/FileUpload/utils/styles.ts +68 -0
  193. package/src/FormLabel/FormLabel.tsx +212 -0
  194. package/src/IconButton/IconButton.tsx +154 -0
  195. package/src/Icons/CreditCardIcon/CreditCardIcon.tsx +73 -0
  196. package/src/Icons/CreditCardIcon/cardIcons.tsx +270 -0
  197. package/src/Icons/IconBase.tsx +133 -0
  198. package/src/Icons/anyIcon.ts +3 -0
  199. package/src/Icons/generatedIcons/Archive.tsx +48 -0
  200. package/src/Icons/generatedIcons/ArrowClockwise.tsx +48 -0
  201. package/src/Icons/generatedIcons/ArrowDown.tsx +48 -0
  202. package/src/Icons/generatedIcons/ArrowLeft.tsx +48 -0
  203. package/src/Icons/generatedIcons/ArrowRight.tsx +48 -0
  204. package/src/Icons/generatedIcons/ArrowSquareOut.tsx +51 -0
  205. package/src/Icons/generatedIcons/ArrowSquareRight.tsx +51 -0
  206. package/src/Icons/generatedIcons/ArrowUp.tsx +48 -0
  207. package/src/Icons/generatedIcons/ArrowsCounterClockwise.tsx +48 -0
  208. package/src/Icons/generatedIcons/ArrowsLeftRight.tsx +48 -0
  209. package/src/Icons/generatedIcons/ArrowsOutCardinal.tsx +48 -0
  210. package/src/Icons/generatedIcons/Bank.tsx +48 -0
  211. package/src/Icons/generatedIcons/Bell.tsx +51 -0
  212. package/src/Icons/generatedIcons/BookBookmark.tsx +51 -0
  213. package/src/Icons/generatedIcons/BookmarksSimple.tsx +51 -0
  214. package/src/Icons/generatedIcons/Broadcast.tsx +48 -0
  215. package/src/Icons/generatedIcons/CalendarBlank.tsx +48 -0
  216. package/src/Icons/generatedIcons/CalendarStar.tsx +51 -0
  217. package/src/Icons/generatedIcons/Camera.tsx +51 -0
  218. package/src/Icons/generatedIcons/CaretDown.tsx +48 -0
  219. package/src/Icons/generatedIcons/CaretLeft.tsx +48 -0
  220. package/src/Icons/generatedIcons/CaretRight.tsx +48 -0
  221. package/src/Icons/generatedIcons/CaretUp.tsx +48 -0
  222. package/src/Icons/generatedIcons/Certificate.tsx +51 -0
  223. package/src/Icons/generatedIcons/ChartBar.tsx +48 -0
  224. package/src/Icons/generatedIcons/Check.tsx +51 -0
  225. package/src/Icons/generatedIcons/CheckCircle.tsx +48 -0
  226. package/src/Icons/generatedIcons/CirclesFour.tsx +51 -0
  227. package/src/Icons/generatedIcons/Clock.tsx +48 -0
  228. package/src/Icons/generatedIcons/ClockCountdown.tsx +48 -0
  229. package/src/Icons/generatedIcons/Close.tsx +51 -0
  230. package/src/Icons/generatedIcons/CloudArrowUp.tsx +51 -0
  231. package/src/Icons/generatedIcons/CloudWarning.tsx +51 -0
  232. package/src/Icons/generatedIcons/Code.tsx +48 -0
  233. package/src/Icons/generatedIcons/Compass.tsx +51 -0
  234. package/src/Icons/generatedIcons/Confetti.tsx +51 -0
  235. package/src/Icons/generatedIcons/Copy.tsx +48 -0
  236. package/src/Icons/generatedIcons/CornersOut.tsx +48 -0
  237. package/src/Icons/generatedIcons/CreditCard.tsx +48 -0
  238. package/src/Icons/generatedIcons/Crown.tsx +51 -0
  239. package/src/Icons/generatedIcons/CrownSimple.tsx +51 -0
  240. package/src/Icons/generatedIcons/CurrencyCircleDollar.tsx +48 -0
  241. package/src/Icons/generatedIcons/CurrencyDollarSimple.tsx +51 -0
  242. package/src/Icons/generatedIcons/Desktop.tsx +51 -0
  243. package/src/Icons/generatedIcons/Detective.tsx +51 -0
  244. package/src/Icons/generatedIcons/DotOutline.tsx +46 -0
  245. package/src/Icons/generatedIcons/DotsSixVertical.tsx +51 -0
  246. package/src/Icons/generatedIcons/DotsThreeOutline.tsx +51 -0
  247. package/src/Icons/generatedIcons/DotsThreeOutlineVertical.tsx +51 -0
  248. package/src/Icons/generatedIcons/DownloadSimple.tsx +51 -0
  249. package/src/Icons/generatedIcons/EnvelopeSimple.tsx +48 -0
  250. package/src/Icons/generatedIcons/Eraser.tsx +51 -0
  251. package/src/Icons/generatedIcons/Eye.tsx +51 -0
  252. package/src/Icons/generatedIcons/EyeSlash.tsx +51 -0
  253. package/src/Icons/generatedIcons/FacebookLogo.tsx +48 -0
  254. package/src/Icons/generatedIcons/FileArchive.tsx +48 -0
  255. package/src/Icons/generatedIcons/FileArrowDown.tsx +48 -0
  256. package/src/Icons/generatedIcons/FileCsv.tsx +48 -0
  257. package/src/Icons/generatedIcons/FilePdf.tsx +48 -0
  258. package/src/Icons/generatedIcons/FileText.tsx +48 -0
  259. package/src/Icons/generatedIcons/Files.tsx +51 -0
  260. package/src/Icons/generatedIcons/Fire.tsx +51 -0
  261. package/src/Icons/generatedIcons/Flag.tsx +51 -0
  262. package/src/Icons/generatedIcons/FlagBannerFold.tsx +48 -0
  263. package/src/Icons/generatedIcons/FloppyDisk.tsx +51 -0
  264. package/src/Icons/generatedIcons/Gauge.tsx +51 -0
  265. package/src/Icons/generatedIcons/Gavel.tsx +51 -0
  266. package/src/Icons/generatedIcons/Gear.tsx +51 -0
  267. package/src/Icons/generatedIcons/GlobeHemisphereWest.tsx +51 -0
  268. package/src/Icons/generatedIcons/GoogleLogo.tsx +48 -0
  269. package/src/Icons/generatedIcons/GridNine.tsx +51 -0
  270. package/src/Icons/generatedIcons/HandCoins.tsx +51 -0
  271. package/src/Icons/generatedIcons/HandbagSimple.tsx +51 -0
  272. package/src/Icons/generatedIcons/Headset.tsx +51 -0
  273. package/src/Icons/generatedIcons/HeartStraight.tsx +51 -0
  274. package/src/Icons/generatedIcons/HourglassLow.tsx +48 -0
  275. package/src/Icons/generatedIcons/House.tsx +51 -0
  276. package/src/Icons/generatedIcons/Image.tsx +51 -0
  277. package/src/Icons/generatedIcons/ImageSquare.tsx +51 -0
  278. package/src/Icons/generatedIcons/ImagesSquare.tsx +51 -0
  279. package/src/Icons/generatedIcons/Info.tsx +48 -0
  280. package/src/Icons/generatedIcons/InstagramLogo.tsx +51 -0
  281. package/src/Icons/generatedIcons/Lightning.tsx +48 -0
  282. package/src/Icons/generatedIcons/Link.tsx +51 -0
  283. package/src/Icons/generatedIcons/LinkedinLogo.tsx +51 -0
  284. package/src/Icons/generatedIcons/List.tsx +48 -0
  285. package/src/Icons/generatedIcons/Lock.tsx +51 -0
  286. package/src/Icons/generatedIcons/LockOpen.tsx +51 -0
  287. package/src/Icons/generatedIcons/MagnifyingGlass.tsx +48 -0
  288. package/src/Icons/generatedIcons/MapPin.tsx +51 -0
  289. package/src/Icons/generatedIcons/MapPinSimpleArea.tsx +48 -0
  290. package/src/Icons/generatedIcons/Medal.tsx +48 -0
  291. package/src/Icons/generatedIcons/Megaphone.tsx +48 -0
  292. package/src/Icons/generatedIcons/Minus.tsx +45 -0
  293. package/src/Icons/generatedIcons/Money.tsx +51 -0
  294. package/src/Icons/generatedIcons/Notches.tsx +48 -0
  295. package/src/Icons/generatedIcons/NotePencil.tsx +48 -0
  296. package/src/Icons/generatedIcons/Package.tsx +51 -0
  297. package/src/Icons/generatedIcons/PaintBrush.tsx +51 -0
  298. package/src/Icons/generatedIcons/PaperPlaneTilt.tsx +51 -0
  299. package/src/Icons/generatedIcons/Paperclip.tsx +51 -0
  300. package/src/Icons/generatedIcons/Pause.tsx +51 -0
  301. package/src/Icons/generatedIcons/PencilLine.tsx +51 -0
  302. package/src/Icons/generatedIcons/PencilRuler.tsx +51 -0
  303. package/src/Icons/generatedIcons/PencilSimple.tsx +51 -0
  304. package/src/Icons/generatedIcons/Phone.tsx +51 -0
  305. package/src/Icons/generatedIcons/PinterestLogo.tsx +51 -0
  306. package/src/Icons/generatedIcons/Play.tsx +51 -0
  307. package/src/Icons/generatedIcons/Plus.tsx +51 -0
  308. package/src/Icons/generatedIcons/PlusCircle.tsx +48 -0
  309. package/src/Icons/generatedIcons/Printer.tsx +51 -0
  310. package/src/Icons/generatedIcons/Question.tsx +48 -0
  311. package/src/Icons/generatedIcons/Receipt.tsx +51 -0
  312. package/src/Icons/generatedIcons/Rows.tsx +51 -0
  313. package/src/Icons/generatedIcons/SealCheck.tsx +51 -0
  314. package/src/Icons/generatedIcons/SelectionSlash.tsx +48 -0
  315. package/src/Icons/generatedIcons/ShareNetwork.tsx +51 -0
  316. package/src/Icons/generatedIcons/ShieldCheck.tsx +51 -0
  317. package/src/Icons/generatedIcons/ShieldStar.tsx +51 -0
  318. package/src/Icons/generatedIcons/ShoppingCart.tsx +48 -0
  319. package/src/Icons/generatedIcons/ShuffleAngular.tsx +48 -0
  320. package/src/Icons/generatedIcons/SidebarSimple.tsx +48 -0
  321. package/src/Icons/generatedIcons/SlidersHorizontal.tsx +51 -0
  322. package/src/Icons/generatedIcons/Smiley.tsx +48 -0
  323. package/src/Icons/generatedIcons/Sparkle.tsx +51 -0
  324. package/src/Icons/generatedIcons/SpinnerGap.tsx +48 -0
  325. package/src/Icons/generatedIcons/StackPlus.tsx +48 -0
  326. package/src/Icons/generatedIcons/Star.tsx +51 -0
  327. package/src/Icons/generatedIcons/Storefront.tsx +51 -0
  328. package/src/Icons/generatedIcons/Swap.tsx +51 -0
  329. package/src/Icons/generatedIcons/Tag.tsx +51 -0
  330. package/src/Icons/generatedIcons/ThumbsDown.tsx +48 -0
  331. package/src/Icons/generatedIcons/ThumbsUp.tsx +48 -0
  332. package/src/Icons/generatedIcons/Toolbox.tsx +48 -0
  333. package/src/Icons/generatedIcons/Trash.tsx +48 -0
  334. package/src/Icons/generatedIcons/TrendUp.tsx +48 -0
  335. package/src/Icons/generatedIcons/Trophy.tsx +51 -0
  336. package/src/Icons/generatedIcons/Truck.tsx +51 -0
  337. package/src/Icons/generatedIcons/UploadSimple.tsx +51 -0
  338. package/src/Icons/generatedIcons/User.tsx +48 -0
  339. package/src/Icons/generatedIcons/Users.tsx +48 -0
  340. package/src/Icons/generatedIcons/UsersThree.tsx +51 -0
  341. package/src/Icons/generatedIcons/VideoCamera.tsx +51 -0
  342. package/src/Icons/generatedIcons/Warning.tsx +51 -0
  343. package/src/Icons/generatedIcons/WarningCircle.tsx +48 -0
  344. package/src/Icons/generatedIcons/WifiHigh.tsx +51 -0
  345. package/src/Icons/generatedIcons/XCircle.tsx +48 -0
  346. package/src/Icons/generatedIcons/XLogo.tsx +48 -0
  347. package/src/Icons/generatedIcons/YoutubeLogo.tsx +51 -0
  348. package/src/Icons/importedIcons.ts +152 -0
  349. package/src/Icons/index.ts +149 -0
  350. package/src/Icons/socialIcons/appleSocialIcon.tsx +50 -0
  351. package/src/Icons/socialIcons/facebookSocialIcon.tsx +41 -0
  352. package/src/Icons/socialIcons/googleSocialIcon.tsx +134 -0
  353. package/src/ImageCluster/ImageCluster.tsx +125 -0
  354. package/src/ImageSlider/ImageSlider.tsx +582 -0
  355. package/src/ImageSlider/ImageSlider.types.ts +90 -0
  356. package/src/ImageSlider/components/IndexIndicator/IndexIndicator.tsx +21 -0
  357. package/src/ImageSlider/components/NavigationButtons/NavigationButtons.tsx +113 -0
  358. package/src/ImageSlider/components/ResponsiveImage/ResponsiveImage.tsx +114 -0
  359. package/src/ImageSlider/components/ResponsiveImage/index.ts +1 -0
  360. package/src/ImageSlider/components/Thumbnails/Thumbnails.tsx +184 -0
  361. package/src/ImageSlider/constants.ts +59 -0
  362. package/src/ImageSlider/hooks/index.ts +3 -0
  363. package/src/ImageSlider/hooks/useImageSlider.ts +57 -0
  364. package/src/ImageSlider/hooks/useImageSliderNavigation.ts +133 -0
  365. package/src/ImageSlider/hooks/useImageSliderScrollHandler.ts +171 -0
  366. package/src/ImageSlider/index.ts +3 -0
  367. package/src/ImageSlider/utils/imageOptimization.ts +97 -0
  368. package/src/ImageSlider/utils/index.ts +1 -0
  369. package/src/InlineNotification/InlineNotification.tsx +95 -0
  370. package/src/JumpMenu/JumpMenu.tsx +395 -0
  371. package/src/JumpMenu/components/JumpMenuItem/JumpMenuItem.tsx +62 -0
  372. package/src/JumpMenu/hooks/useContainerTracking.ts +171 -0
  373. package/src/JumpMenu/hooks/useIntersectionObserver.ts +77 -0
  374. package/src/JumpMenu/hooks/useKeyboardNavigation.ts +102 -0
  375. package/src/JumpMenu/hooks/useResizeObserver.ts +53 -0
  376. package/src/JumpMenu/hooks/useSectionObserver.ts +102 -0
  377. package/src/JumpMenu/index.ts +2 -0
  378. package/src/JumpMenu/types/index.ts +19 -0
  379. package/src/Loading/Loading.tsx +39 -0
  380. package/src/Loading/components/LoadingDot/LoadingDot.tsx +16 -0
  381. package/src/LoadingSpinner/LoadingSpinner.tsx +20 -0
  382. package/src/Menu/Menu.tsx +372 -0
  383. package/src/Menu/components/MenuDivider/MenuDivider.tsx +5 -0
  384. package/src/Menu/components/MenuItem/MenuItem.tsx +298 -0
  385. package/src/Menu/context/menuContext.tsx +20 -0
  386. package/src/Menu/hooks/useMenu.tsx +18 -0
  387. package/src/Menu/index.ts +3 -0
  388. package/src/Modal/ComposableModal.tsx +313 -0
  389. package/src/Modal/Modal.tsx +231 -0
  390. package/src/Modal/components/BackButton/BackButton.tsx +43 -0
  391. package/src/Modal/components/Backdrop/Backdrop.tsx +62 -0
  392. package/src/Modal/components/CloseButton/CloseButton.tsx +55 -0
  393. package/src/Modal/components/ModalActions/ModalActions.tsx +135 -0
  394. package/src/Modal/components/ModalContent/ModalContent.tsx +163 -0
  395. package/src/Modal/components/ModalHeader/ModalHeader.tsx +84 -0
  396. package/src/Modal/components/ModalHeader/hooks/useHeaderAnimation.tsx +49 -0
  397. package/src/Modal/components/ModalProgressSteps/ModalProgressSteps.tsx +26 -0
  398. package/src/Modal/components/ModalSubTitle/ModalSubTitle.tsx +29 -0
  399. package/src/Modal/components/ModalTitle/ModalTitle.tsx +22 -0
  400. package/src/Modal/components/PreventModalScroll/PreventModalScroll.tsx +106 -0
  401. package/src/Modal/components/index.ts +12 -0
  402. package/src/Modal/context.ts +33 -0
  403. package/src/Modal/hooks/useCloseModal.ts +133 -0
  404. package/src/NotificationBadge/NotificationBadge.tsx +34 -0
  405. package/src/Pagination/AdvancedPagination.tsx +48 -0
  406. package/src/Pagination/Pagination.tsx +216 -0
  407. package/src/Pagination/components/AdvancedPaginator/AdvancedPaginator.tsx +52 -0
  408. package/src/Pagination/components/AdvancedPaginator/components/PageSelect/PageSelect.tsx +43 -0
  409. package/src/Pagination/components/ItemCountDisplay/ItemCountDisplay.tsx +32 -0
  410. package/src/Pagination/components/ItemCountSelect/ItemCountSelect.tsx +33 -0
  411. package/src/Pagination/index.tsx +3 -0
  412. package/src/Pagination/paginationProvider.tsx +234 -0
  413. package/src/Pagination/utils.tsx +36 -0
  414. package/src/PhoneInput/PhoneInput.tsx +509 -0
  415. package/src/PhoneInput/useDropdownLogic.tsx +163 -0
  416. package/src/ProgressCircle/ProgressCircle.tsx +246 -0
  417. package/src/ProgressCircle/hooks/useProgressStatusTransitions.ts +49 -0
  418. package/src/ProgressCircle/utils/progressCircle.constants.ts +27 -0
  419. package/src/ProgressSteps/ProgressSteps.tsx +160 -0
  420. package/src/SaveConfetti/SaveConfetti.tsx +277 -0
  421. package/src/SaveConfetti/index.ts +2 -0
  422. package/src/SearchInput/SearchInput.tsx +236 -0
  423. package/src/SegmentedControl/SegmentedControl.tsx +111 -0
  424. package/src/SegmentedControl/SegmentedControlGroup.tsx +94 -0
  425. package/src/SegmentedControl/index.ts +4 -0
  426. package/src/Select/Select.tsx +154 -0
  427. package/src/Select/SelectAsync.tsx +13 -0
  428. package/src/Select/SelectAsyncCreatable.tsx +14 -0
  429. package/src/Select/SelectCreatable.tsx +12 -0
  430. package/src/Select/reexportedComponents.tsx +5 -0
  431. package/src/Select/selectComponents.tsx +306 -0
  432. package/src/Skeleton/Skeleton.tsx +13 -0
  433. package/src/SplitButton/SplitButton.tsx +298 -0
  434. package/src/SplitButton/SplitButtonTrigger.tsx +55 -0
  435. package/src/StarRating/StarRating.tsx +165 -0
  436. package/src/StarRating/components/StarComponent/StarComponent.tsx +44 -0
  437. package/src/Table/Table.tsx +474 -0
  438. package/src/Table/components/TableHeader/TableHeader.tsx +166 -0
  439. package/src/Table/components/TablePagination/TablePagination.tsx +18 -0
  440. package/src/Table/components/TablePagination/components/ItemCountDisplay/ItemCountDisplay.tsx +17 -0
  441. package/src/Table/components/TablePagination/components/ItemCountSelect/ItemCountSelect.tsx +31 -0
  442. package/src/Table/components/TablePagination/components/TablePaginator/TablePaginator.tsx +37 -0
  443. package/src/Table/components/TablePagination/components/TablePaginator/components/PageSelect/PageSelect.tsx +32 -0
  444. package/src/Table/components/TableRow/TableRows.tsx +147 -0
  445. package/src/Table/components/TableRow/components/TableRowCell/TableRowCell.tsx +49 -0
  446. package/src/Table/components/TableShadow/TableShadow.tsx +46 -0
  447. package/src/Table/index.ts +2 -0
  448. package/src/Table/sharedState.ts +30 -0
  449. package/src/Table/sharedStyles.ts +1 -0
  450. package/src/Table/types.ts +55 -0
  451. package/src/Tabs/Tabs.tsx +358 -0
  452. package/src/TextArea/TextArea.tsx +157 -0
  453. package/src/TextInput/TextInput.tsx +173 -0
  454. package/src/Toast/Toast.tsx +64 -0
  455. package/src/Toast/components/ToastContainer/ToastContainer.tsx +48 -0
  456. package/src/Toast/index.ts +2 -0
  457. package/src/Toast/types/role.ts +1 -0
  458. package/src/Toast/utils/getIcon.tsx +41 -0
  459. package/src/ToggleSwitch/ToggleSwitch.tsx +188 -0
  460. package/src/Tooltip/InfoIconTooltip.tsx +47 -0
  461. package/src/Tooltip/Tooltip.tsx +41 -0
  462. package/src/Typography/InlineButton/InlineButton.tsx +166 -0
  463. package/src/Typography/Links/Links.tsx +113 -0
  464. package/src/Typography/Text/Text.tsx +239 -0
  465. package/src/ViewMore/ViewMore.tsx +226 -0
  466. package/src/WebRTCPlayer/WebRTCPlayer.tsx +325 -0
  467. package/src/WebRTCPlayer/adaptor/NativeWebRTCAdaptor.ts +588 -0
  468. package/src/WebRTCPlayer/hooks/useWebRTCStream.ts +571 -0
  469. package/src/WebRTCPlayer/index.ts +22 -0
  470. package/src/WebRTCPlayer/types.ts +95 -0
  471. package/src/breakpoints/index.tsx +1 -0
  472. package/src/breakpoints/utils.tsx +50 -0
  473. package/src/declarations.d.ts +7 -0
  474. package/src/grid/gridHighlighter.tsx +83 -0
  475. package/src/grid/index.ts +3 -0
  476. package/src/grid/pageGrid.tsx +37 -0
  477. package/src/grid/useSubGridCSS.tsx +214 -0
  478. package/src/hooks/useHorizontalScrollFade.ts +44 -0
  479. package/src/hooks/usePrevious.ts +14 -0
  480. package/src/index.ts +351 -0
  481. package/src/intl/index.ts +4 -0
  482. package/src/intl/utils.ts +67 -0
  483. package/src/mixins/horizontalScrollFadeMixin.ts +56 -0
  484. package/src/mixins/index.ts +18 -0
  485. package/src/mixins/propMixins.ts +389 -0
  486. package/src/providers/createContextProvider.ts +22 -0
  487. package/src/providers/designSystemProvider.tsx +218 -0
  488. package/src/providers/errorBoundaryProvider.tsx +179 -0
  489. package/src/providers/featureFlagProvider.tsx +18 -0
  490. package/src/providers/gridSizeProvider.tsx +23 -0
  491. package/src/providers/index.ts +12 -0
  492. package/src/providers/linkProvider.tsx +32 -0
  493. package/src/providers/normalize.tsx +93 -0
  494. package/src/providers/targets/DatePickerTarget.tsx +10 -0
  495. package/src/providers/targets/ModalTarget.tsx +14 -0
  496. package/src/providers/targets/TimePickerTarget.tsx +10 -0
  497. package/src/providers/themeContext.tsx +24 -0
  498. package/src/providers/windowSizeProvider.tsx +125 -0
  499. package/src/spacing/index.ts +1 -0
  500. package/src/spacing/spacing.ts +11 -0
  501. package/src/utils/countriesWithISOCodes.ts +1419 -0
  502. package/src/utils/dateTimeFormat.ts +257 -0
  503. package/src/utils/effectEventListener.ts +11 -0
  504. package/src/utils/formatFileSize.ts +18 -0
  505. package/src/utils/isClientSide.ts +1 -0
  506. package/src/utils/keepTransition.ts +15 -0
  507. package/src/utils/nodeEnv.ts +9 -0
  508. package/src/utils/smoothScrollTo.ts +47 -0
  509. package/src/utils/utilityTypes.ts +13 -0
@@ -0,0 +1,174 @@
1
+ import { cn } from '@evolve.ui/theme-system';
2
+ import { ComponentProps, ReactElement, useCallback, useEffect, useMemo, useState } from 'react';
3
+
4
+ import { Button } from '../Button/Button';
5
+ import { IconButton } from '../IconButton/IconButton';
6
+ import { Close } from '../Icons';
7
+ import { AnyIcon } from '../Icons/anyIcon';
8
+ import { Tooltip } from '../Tooltip/Tooltip';
9
+ import { Caption, H5 } from '../Typography/Text/Text';
10
+
11
+ type Props = Omit<ComponentProps<typeof Tooltip>, 'children'> & {
12
+ /**
13
+ * The icon to show in the top-left corner.
14
+ * - If populated, the title is shown right below it.
15
+ * - If not populated, the title will show there instead.
16
+ * @default undefined
17
+ */
18
+ icon?: AnyIcon;
19
+ /**
20
+ * Array of ReactElements that the user will click through to become educated.
21
+ */
22
+ pages: ReactElement[];
23
+ /**
24
+ * Should the close button be shown in the top-right corner?
25
+ * @default false
26
+ */
27
+ showCloseButton?: boolean;
28
+ /**
29
+ * Should the step counter be shown in the bottom-left corner?
30
+ * If there is only a single page, it will not be shown, even if this prop is true.
31
+ * @default false
32
+ */
33
+ showStepCount?: boolean;
34
+ /**
35
+ * Title of the educational modal.
36
+ * This will be shown over the main content of every page in the education flow.
37
+ * - If `icon` is populated, the title is shown right below it.
38
+ * - If `icon` is not populated, the title will show across from the close button instead.
39
+ */
40
+ title?: string;
41
+ };
42
+
43
+ export const EducationalPopover = ({
44
+ icon: Icon,
45
+ isOpen: isOpenProp = true,
46
+ pages,
47
+ showCloseButton = false,
48
+ showStepCount = false,
49
+ title,
50
+ ...tooltipProps
51
+ }: Props) => {
52
+ const [isOpen, setIsOpen] = useState(isOpenProp);
53
+
54
+ const [currentPage, setCurrentPage] = useState(0);
55
+ const pageCount = pages.length;
56
+ const hasMultiplePages = pageCount > 1;
57
+ const isOnLastPage = currentPage + 1 === pageCount;
58
+
59
+ const showTopRow = Icon || title || showCloseButton;
60
+ const showLowerTitleRow = Icon && title;
61
+ const showBottomRow = hasMultiplePages;
62
+
63
+ const pageContent = useMemo(() => pages[currentPage], [currentPage, pages]);
64
+
65
+ const onClose = useCallback(() => {
66
+ setIsOpen(false);
67
+ }, []);
68
+
69
+ const onClickNextButton: ComponentProps<typeof Button>['onClick'] = useCallback(() => {
70
+ // User pressed "Got It" and will close popover
71
+ if (isOnLastPage) {
72
+ onClose();
73
+ }
74
+ // User pressed "Next" and will go to next page
75
+ else {
76
+ setCurrentPage((currentPage) => currentPage + 1);
77
+ }
78
+ }, [isOnLastPage, onClose]);
79
+
80
+ useEffect(() => {
81
+ setCurrentPage(0);
82
+ }, [isOpen, pages]);
83
+
84
+ useEffect(() => {
85
+ setIsOpen(isOpenProp);
86
+ }, [isOpenProp]);
87
+
88
+ if (pages.length === 0) {
89
+ return null;
90
+ }
91
+
92
+ return (
93
+ <Tooltip
94
+ className="!rounded-none"
95
+ isOpen={isOpen}
96
+ style={{ minWidth: '314px' }}
97
+ {...tooltipProps}
98
+ clickable
99
+ globalCloseEvents={{
100
+ clickOutsideAnchor: true,
101
+ escape: true,
102
+ }}
103
+ setIsOpen={setIsOpen}
104
+ >
105
+ <section className="py-xs">
106
+ {/* icon / close button */}
107
+ {showTopRow && (
108
+ <div className="mb-xs flex items-center justify-between">
109
+ {/* if icon exists, place it across from close button */}
110
+ {Icon && <Icon color={tooltipProps.isInverse ? 'inverse' : 'primary'} />}
111
+ {/* if icon does not exist, title is across from close button*/}
112
+ {!Icon && title && <H5 color={tooltipProps.isInverse ? 'inverse' : 'primary'}>{title}</H5>}
113
+
114
+ {showCloseButton && (
115
+ <IconButton
116
+ icon={Close}
117
+ onClick={onClose}
118
+ style={tooltipProps.isInverse ? 'inverse' : 'neutral'}
119
+ />
120
+ )}
121
+ </div>
122
+ )}
123
+ {/* title is under icon if icon exists */}
124
+ {showLowerTitleRow && (
125
+ <H5
126
+ className="mb-xs"
127
+ color={tooltipProps.isInverse ? 'inverse' : 'primary'}
128
+ >
129
+ {title}
130
+ </H5>
131
+ )}
132
+ {/* main educational info */}
133
+ {pageContent}
134
+ {/* bottom content */}
135
+ {showBottomRow && (
136
+ <div
137
+ className={cn('mt-sm flex items-center', {
138
+ 'justify-between': showStepCount || !isOnLastPage,
139
+ 'justify-end': !(showStepCount || !isOnLastPage),
140
+ })}
141
+ >
142
+ {showStepCount && (
143
+ <Caption
144
+ className="items-start"
145
+ color={tooltipProps.isInverse ? 'inverse' : 'primary'}
146
+ >
147
+ {currentPage + 1} of {pageCount}
148
+ </Caption>
149
+ )}
150
+ <div className="flex items-end gap-sm">
151
+ {!isOnLastPage && (
152
+ <Button
153
+ onClick={onClose}
154
+ size="sm"
155
+ style={tooltipProps.isInverse ? 'inverse' : 'primary'}
156
+ variant="transparent"
157
+ >
158
+ Skip
159
+ </Button>
160
+ )}
161
+ <Button
162
+ onClick={onClickNextButton}
163
+ size="sm"
164
+ style={tooltipProps.isInverse ? 'inverse' : 'primary'}
165
+ >
166
+ {isOnLastPage ? 'Got It' : 'Next'}
167
+ </Button>
168
+ </div>
169
+ </div>
170
+ )}
171
+ </section>
172
+ </Tooltip>
173
+ );
174
+ };
@@ -0,0 +1,64 @@
1
+ import { forwardRef } from 'react';
2
+
3
+ import { Tooltip } from '../Tooltip/Tooltip';
4
+ import { IconOnlyFavoriteButton } from './components/IconOnlyFavoriteButton/IconOnlyFavoriteButton';
5
+ import { LabeledAnimatedFavoriteButton } from './components/LabeledAnimatedFavoriteButton/LabeledAnimatedFavoriteButton';
6
+ import { LabeledFavoriteButton } from './components/LabeledFavoriteButton/LabeledFavoriteButton';
7
+ import { FavoriteButtonProps } from './types/favoriteButton';
8
+
9
+ /**
10
+ * A button that allows users to mark an item as a favorite.
11
+ * The button displays a heart icon that changes appearance when favorited.
12
+ *
13
+ * Be aware that if you're using the tooltip option, make sure to use a unique id
14
+ * and set the `anchorSelect` prop on the tooltip to the id of the button.
15
+ *
16
+ * Available in four variants:
17
+ * - `circle`: Shows only the heart icon in a circular button (default)
18
+ * - `square`: Shows only the heart icon in a square button
19
+ * - `labeled`: Shows a button with text and the heart icon
20
+ * - `labeled-animated`: Shows a labeled button with animation-ready wrappers
21
+ */
22
+ export const FavoriteButton = forwardRef<HTMLButtonElement, FavoriteButtonProps>((props, ref) => {
23
+ const { isActivating, isWiggling, tooltipProps, variant = 'circle', ...restProps } = props;
24
+ const { enabled = false, ...tooltipRestProps } = tooltipProps ?? {};
25
+
26
+ // Use a mapping object to determine which component to render
27
+ const variantComponents = {
28
+ circle: (
29
+ <IconOnlyFavoriteButton
30
+ ref={ref}
31
+ shape="circle"
32
+ {...restProps}
33
+ />
34
+ ),
35
+ labeled: (
36
+ <LabeledFavoriteButton
37
+ ref={ref}
38
+ {...restProps}
39
+ />
40
+ ),
41
+ 'labeled-animated': (
42
+ <LabeledAnimatedFavoriteButton
43
+ ref={ref}
44
+ isActivating={isActivating}
45
+ isWiggling={isWiggling}
46
+ {...restProps}
47
+ />
48
+ ),
49
+ square: (
50
+ <IconOnlyFavoriteButton
51
+ ref={ref}
52
+ shape="square"
53
+ {...restProps}
54
+ />
55
+ ),
56
+ };
57
+
58
+ return (
59
+ <>
60
+ {enabled && <Tooltip {...tooltipRestProps} />}
61
+ {variantComponents[variant]}
62
+ </>
63
+ );
64
+ });
@@ -0,0 +1,80 @@
1
+ import { cn } from '@evolve.ui/theme-system';
2
+ import { forwardRef } from 'react';
3
+
4
+ import { HeartStraight } from '../../../Icons';
5
+ import { useFavoriteButtonState } from '../../hooks/useFavoriteButtonState';
6
+ import { IconOnlyFavoriteButtonProps } from '../../types/favoriteButton';
7
+
8
+ /**
9
+ * Icon-only variant of the FavoriteButton component
10
+ * Displays only a heart icon in either a circle or square shape
11
+ */
12
+ export const IconOnlyFavoriteButton = forwardRef<HTMLButtonElement, IconOnlyFavoriteButtonProps>(
13
+ (
14
+ {
15
+ 'aria-label': ariaLabel = 'Favorite Toggle',
16
+ className,
17
+ disabled,
18
+ favorited,
19
+ onClick,
20
+ shape,
21
+ type,
22
+ ...restProps
23
+ },
24
+ ref
25
+ ) => {
26
+ const { handleMouseDown, handleMouseLeave, handleMouseUp, isActive } = useFavoriteButtonState();
27
+
28
+ return (
29
+ <button
30
+ aria-label={ariaLabel}
31
+ aria-pressed={Boolean(favorited)}
32
+ className={cn(
33
+ // Base styles
34
+ 'group flex h-[30px] w-[30px] cursor-pointer items-center justify-center border border-solid',
35
+ // Shape styles
36
+ {
37
+ 'rounded-container': shape === 'square',
38
+ 'rounded-full': shape === 'circle',
39
+ },
40
+ // Default state
41
+ 'bg-background-primary text-surface-500',
42
+ // Selected state
43
+ {
44
+ 'bg-background-primary text-critical-500': favorited,
45
+ },
46
+ // Focus state
47
+ 'focus-visible:hui-focus-visible-outline focus:outline-none focus-visible:outline-offset-1',
48
+ // Active state - immediately show critical color when clicked
49
+ 'active:text-border-critical-400 active:bg-critical-50',
50
+ // Hover state
51
+ 'hover:bg-critical-50 hover:text-critical-400',
52
+ // Disabled state
53
+ 'disabled:cursor-not-allowed disabled:bg-background-primary disabled:text-border-disabled',
54
+ className
55
+ )}
56
+ data-hui-id="FavoriteButton"
57
+ disabled={disabled}
58
+ onClick={onClick}
59
+ onMouseDown={handleMouseDown}
60
+ onMouseLeave={handleMouseLeave}
61
+ onMouseUp={handleMouseUp}
62
+ ref={ref}
63
+ type={type as 'button' | 'submit' | 'reset' | undefined}
64
+ {...restProps}
65
+ >
66
+ <HeartStraight
67
+ className={cn(
68
+ 'mt-[1px] bg-transparent text-current transition-transform duration-200 ease-in-out',
69
+ {
70
+ 'group-hover:scale-[1.125]': !disabled,
71
+ }
72
+ )}
73
+ color="inherit"
74
+ size="sm"
75
+ style={favorited || isActive ? 'fill' : 'regular'}
76
+ />
77
+ </button>
78
+ );
79
+ }
80
+ );
@@ -0,0 +1,179 @@
1
+ import { cn } from '@evolve.ui/theme-system';
2
+ import { ButtonHTMLAttributes, CSSProperties, forwardRef, useEffect, useImperativeHandle, useRef } from 'react';
3
+
4
+ import { outlinedCriticalClasses, outlinedNeutralClasses } from '../../../Button/buttonColorClasses';
5
+ import { HeartStraight } from '../../../Icons';
6
+ import { SaveConfetti, type SaveConfettiHandle } from '../../../SaveConfetti/SaveConfetti';
7
+ import { useFavoriteButtonState } from '../../hooks/useFavoriteButtonState';
8
+
9
+ /**
10
+ * Labeled-animated variant of the FavoriteButton component.
11
+ *
12
+ * Visually identical to the `labeled` variant but exposes `isWiggling` and
13
+ * `isActivating` props that trigger the enhanced save-button nudge animations:
14
+ *
15
+ * - `isWiggling`: side-to-side wiggle (button), 3D twirl + bloom (heart icon),
16
+ * color flash (critical fill pulse on heart when not favorited), and shimmer (label text).
17
+ * During nudge the heart uses `fill` weight with critical color; at rest unfavorited uses `bold`.
18
+ * Apply for ~1300ms, then reset to false to re-arm.
19
+ *
20
+ * - `isActivating`: pulse (button) and heart pop (icon). Apply for ~500ms.
21
+ *
22
+ * Animation CSS is driven by Tailwind `animate-*` utilities from the theme plugin
23
+ * (`theme.extend.animation`) — no runtime style injection. The shimmer uses the
24
+ * `.hui-fb-shimmer` component class from the plugin for its multi-property CSS.
25
+ * The heart-color flash uses `.hui-fb-color-flash` to animate fill on the nested
26
+ * SVG path via a descendant selector. Icon weight: `bold` when unfavorited at rest,
27
+ * `fill` during nudge, favorited, or active press — matching the static `labeled` variant at rest.
28
+ */
29
+
30
+ type Props = {
31
+ /** Accessible label for screen readers. @default 'Favorite Toggle' */
32
+ 'aria-label'?: string;
33
+ /** Whether the item is currently favorited. */
34
+ favorited?: boolean;
35
+ /** Label text shown when favorited. @default 'Saved' */
36
+ favoritedLabel?: string;
37
+ /**
38
+ * When true, fires the save-click animation (button pulse + heart pop) and
39
+ * a mini confetti burst from the button center.
40
+ * Reset to false after ~500ms to re-arm.
41
+ */
42
+ isActivating?: boolean;
43
+ /**
44
+ * When true, fires the nudge animation (wiggle + twirl + shimmer + color flash).
45
+ * Reset to false after ~1300ms to re-arm.
46
+ */
47
+ isWiggling?: boolean;
48
+ /** Label text shown when not favorited. @default 'Save' */
49
+ label?: string;
50
+ } & Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'style'>;
51
+
52
+ type AnimationPaletteCSSVar =
53
+ | '--hui-save-color-critical-500'
54
+ | '--hui-save-color-critical-300'
55
+ | '--hui-save-color-critical-200'
56
+ | '--hui-save-color-tertiary-400'
57
+ | '--hui-save-color-tertiary-200';
58
+
59
+ const BUTTON_INLINE_STYLES: CSSProperties & Record<AnimationPaletteCSSVar, string> = {
60
+ fontSize: 'var(--font-size-button-200)',
61
+ fontWeight: 'var(--font-weight-button)',
62
+ textTransform: 'var(--text-transform-button)' as CSSProperties['textTransform'],
63
+ // Expose canonical animation palette tokens for downstream orchestration.
64
+ '--hui-save-color-critical-500': 'var(--color-critical-500)',
65
+ '--hui-save-color-critical-300': 'var(--color-critical-300)',
66
+ '--hui-save-color-critical-200': 'var(--color-critical-200)',
67
+ '--hui-save-color-tertiary-400': 'var(--color-tertiary-400)',
68
+ '--hui-save-color-tertiary-200': 'var(--color-tertiary-200)',
69
+ };
70
+
71
+ export const LabeledAnimatedFavoriteButton = forwardRef<HTMLButtonElement, Props>(
72
+ (
73
+ {
74
+ 'aria-label': ariaLabel = 'Favorite Toggle',
75
+ className,
76
+ disabled,
77
+ favorited,
78
+ favoritedLabel = 'Saved',
79
+ isActivating,
80
+ isWiggling,
81
+ label = 'Save',
82
+ onClick,
83
+ ...restProps
84
+ },
85
+ ref
86
+ ) => {
87
+ const { handleMouseDown, handleMouseLeave, handleMouseUp, isActive } = useFavoriteButtonState();
88
+
89
+ const internalButtonRef = useRef<HTMLButtonElement>(null);
90
+ const confettiRef = useRef<SaveConfettiHandle>(null);
91
+
92
+ // Preserve consumer-facing ref contract while keeping internal button access for confetti
93
+ useImperativeHandle(ref, () => internalButtonRef.current!);
94
+
95
+ // Fire confetti burst when the save-click animation triggers
96
+ useEffect(() => {
97
+ if (!isActivating || !internalButtonRef.current) {
98
+ return;
99
+ }
100
+ confettiRef.current?.fire(internalButtonRef.current);
101
+ }, [isActivating]);
102
+
103
+ return (
104
+ <>
105
+ <button
106
+ aria-busy={false}
107
+ aria-label={ariaLabel}
108
+ aria-live="polite"
109
+ aria-pressed={favorited ?? false}
110
+ className={cn(
111
+ // Base — exact match to Button's base class string
112
+ 'hui-focus-visible-outline relative flex max-w-full items-center justify-center whitespace-nowrap rounded-button text-center font-primary tracking-[var(--letter-spacing-button)] outline outline-1 -outline-offset-1 transition-colors disabled:text-text-disabled',
113
+ // Color classes — same conditional used by LabeledFavoriteButton
114
+ favorited ? outlinedCriticalClasses : outlinedNeutralClasses,
115
+ // sm size
116
+ 'gap-[4px] px-sm py-[13px] leading-[8px]',
117
+ // Height override (matches LabeledFavoriteButton)
118
+ 'h-[34px]',
119
+ // Favorited state border
120
+ { 'border-critical-500 text-critical-500': favorited },
121
+ // Hover/active overrides — same className passed by LabeledFavoriteButton to Button
122
+ 'hover:border-critical-700 hover:bg-critical-50 hover:text-critical-700',
123
+ 'active:border-critical-900 active:bg-critical-100 active:text-critical-900',
124
+ // Nudge animation — wiggle on button root + color flash on nested SVG path
125
+ isWiggling && 'animate-saveButtonWiggle motion-reduce:animate-none',
126
+ isWiggling && !favorited && 'hui-fb-color-flash',
127
+ // Save-click animation — pulse on button root
128
+ isActivating && 'animate-saveButtonPulse motion-reduce:animate-none',
129
+ className
130
+ )}
131
+ data-hui-id="FavoriteButton"
132
+ disabled={disabled}
133
+ onClick={onClick}
134
+ onMouseDown={handleMouseDown}
135
+ onMouseLeave={handleMouseLeave}
136
+ onMouseUp={handleMouseUp}
137
+ ref={internalButtonRef}
138
+ style={BUTTON_INLINE_STYLES}
139
+ {...restProps}
140
+ >
141
+ {/*
142
+ * Perspective wrapper — 3D twirl animation targets this element.
143
+ * Width/height matches Button's internal iconLeft container (14px for xs icon).
144
+ */}
145
+ <span
146
+ className={cn(
147
+ 'hui-fb-icon-frame relative flex items-center justify-center',
148
+ // Critical color during nudge so fill weight reads red immediately (not surface-500 grey)
149
+ isWiggling && !favorited && 'text-critical-500',
150
+ // Nudge animation — 3D twirl + bloom on icon frame
151
+ isWiggling && 'animate-saveHeartTwirlBloom motion-reduce:animate-none'
152
+ )}
153
+ style={{ height: '14px', perspective: '200px', width: '14px' }}
154
+ >
155
+ <HeartStraight
156
+ className={cn(
157
+ '[transform-style:preserve-3d]',
158
+ // Save-click animation — heart pop on SVG element
159
+ isActivating && 'animate-saveHeartPop motion-reduce:animate-none'
160
+ )}
161
+ color="inherit"
162
+ size="xs"
163
+ style={favorited || isActive || isWiggling ? 'fill' : 'bold'}
164
+ />
165
+ </span>
166
+ {/* Shimmer wrapper — .hui-fb-shimmer bundles background-clip + gradient + animation */}
167
+ <span
168
+ className={cn('hui-fb-animated-label', isWiggling && 'hui-fb-shimmer animate-saveLabelShimmer')}
169
+ >
170
+ {favorited ? favoritedLabel : label}
171
+ </span>
172
+ </button>
173
+ <SaveConfetti ref={confettiRef} />
174
+ </>
175
+ );
176
+ }
177
+ );
178
+
179
+ LabeledAnimatedFavoriteButton.displayName = 'LabeledAnimatedFavoriteButton';
@@ -0,0 +1,71 @@
1
+ import { cn } from '@evolve.ui/theme-system';
2
+ import { ButtonHTMLAttributes, forwardRef } from 'react';
3
+
4
+ import { Button } from '../../../Button/Button';
5
+ import { useFavoriteButtonState } from '../../hooks/useFavoriteButtonState';
6
+ import { SmallHeartStraightIcon } from '../SmallHeartStraightIcon/SmallHeartStraightIcon';
7
+
8
+ /**
9
+ * Labeled variant of the FavoriteButton component
10
+ * Displays a button with text and a heart icon
11
+ */
12
+
13
+ type Props = {
14
+ 'aria-label'?: string;
15
+ favorited?: boolean;
16
+ favoritedLabel?: string;
17
+ label?: string;
18
+ } & Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'style' | 'children'>;
19
+
20
+ export const LabeledFavoriteButton = forwardRef<HTMLButtonElement, Props>(
21
+ (
22
+ {
23
+ 'aria-label': ariaLabel = 'Favorite Toggle',
24
+ className,
25
+ disabled,
26
+ favorited,
27
+ favoritedLabel = 'Saved',
28
+ label = 'Save',
29
+ onClick,
30
+ ...restProps
31
+ },
32
+ ref
33
+ ) => {
34
+ const { handleMouseDown, handleMouseLeave, handleMouseUp, isActive } = useFavoriteButtonState();
35
+
36
+ return (
37
+ <Button
38
+ aria-label={ariaLabel}
39
+ aria-pressed={favorited ? true : false}
40
+ className={cn(
41
+ // Base styles
42
+ 'h-[34px] text-surface-500',
43
+ // Selected state
44
+ {
45
+ 'border-critical-500 text-critical-500': favorited,
46
+ },
47
+ // Hover state - same for both favorited and non-favorited
48
+ 'hover:border-critical-700 hover:bg-critical-50 hover:text-critical-700',
49
+ // Active states - different for favorited and non-favorited
50
+ 'active:border-critical-900 active:bg-critical-100 active:text-critical-900',
51
+ className
52
+ )}
53
+ data-hui-id="FavoriteButton"
54
+ disabled={disabled}
55
+ iconLeft={SmallHeartStraightIcon}
56
+ iconStyle={favorited || isActive ? 'fill' : 'bold'}
57
+ onClick={onClick}
58
+ onMouseDown={handleMouseDown}
59
+ onMouseLeave={handleMouseLeave}
60
+ onMouseUp={handleMouseUp}
61
+ ref={ref}
62
+ size="sm"
63
+ style={favorited ? 'critical' : 'neutral'}
64
+ variant="outlined"
65
+ {...restProps}
66
+ >
67
+ {favorited ? favoritedLabel : label}
68
+ </Button>
69
+ );
70
+ }
71
+ );
@@ -0,0 +1,14 @@
1
+ import { ComponentProps, forwardRef } from 'react';
2
+
3
+ import { CaretRight, HeartStraight } from '../../../Icons';
4
+
5
+ export const SmallHeartStraightIcon = forwardRef<SVGSVGElement, ComponentProps<typeof CaretRight>>((props, ref) => {
6
+ return (
7
+ <HeartStraight
8
+ style="bold"
9
+ {...props}
10
+ ref={ref}
11
+ size="xs"
12
+ />
13
+ );
14
+ });
@@ -0,0 +1,30 @@
1
+ import { useState } from 'react';
2
+
3
+ /**
4
+ * Custom hook for managing the active state of the FavoriteButton
5
+ * @returns Object containing the active state and event handlers
6
+ */
7
+ export const useFavoriteButtonState = () => {
8
+ const [isActive, setIsActive] = useState(false);
9
+
10
+ const handleMouseDown = () => {
11
+ setIsActive(true);
12
+ };
13
+
14
+ const handleMouseUp = () => {
15
+ setIsActive(false);
16
+ };
17
+
18
+ const handleMouseLeave = () => {
19
+ if (isActive) {
20
+ setIsActive(false);
21
+ }
22
+ };
23
+
24
+ return {
25
+ handleMouseDown,
26
+ handleMouseLeave,
27
+ handleMouseUp,
28
+ isActive,
29
+ };
30
+ };
@@ -0,0 +1,2 @@
1
+ export * from './FavoriteButton';
2
+ export * from './types/favoriteButton';