@evolve.ui/core-components 1.0.0 → 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 (559) hide show
  1. package/Checkbox.d.cts +1 -1
  2. package/Checkbox.d.mts +1 -1
  3. package/{DateInput-B8XQZPTx.d.cts → DateInput-CFxTZu3m.d.mts} +2 -2
  4. package/{DateInput-B8XQZPTx.d.cts.map → DateInput-CFxTZu3m.d.mts.map} +1 -1
  5. package/{DateInput-CfNmywqQ.d.mts → DateInput-DstMICTl.d.cts} +2 -2
  6. package/{DateInput-CfNmywqQ.d.mts.map → DateInput-DstMICTl.d.cts.map} +1 -1
  7. package/{FavoriteButton-CowOPoqo.d.cts → FavoriteButton-BGF-3dze.d.cts} +2 -2
  8. package/{FavoriteButton-BRY8FVpV.d.mts.map → FavoriteButton-BGF-3dze.d.cts.map} +1 -1
  9. package/{FavoriteButton-BRY8FVpV.d.mts → FavoriteButton-BZEGWrRo.d.mts} +2 -2
  10. package/{FavoriteButton-CowOPoqo.d.cts.map → FavoriteButton-BZEGWrRo.d.mts.map} +1 -1
  11. package/Input.d.cts +1 -1
  12. package/Input.d.mts +1 -1
  13. package/Radio.d.cts +1 -1
  14. package/Radio.d.mts +1 -1
  15. package/{TextInput-BhkeQZh4.d.cts → TextInput-B7lqQ1gh.d.cts} +3 -3
  16. package/{TextInput-BhkeQZh4.d.cts.map → TextInput-B7lqQ1gh.d.cts.map} +1 -1
  17. package/{TextInput-CWCeR18b.d.mts → TextInput-CxoT3np_.d.mts} +3 -3
  18. package/{TextInput-CWCeR18b.d.mts.map → TextInput-CxoT3np_.d.mts.map} +1 -1
  19. package/dateInput.d.cts +1 -1
  20. package/dateInput.d.mts +1 -1
  21. package/datePicker.d.cts +1 -1
  22. package/datePicker.d.mts +1 -1
  23. package/evolve-ui.entries.json +556 -0
  24. package/favoriteButton.d.cts +1 -1
  25. package/favoriteButton.d.mts +1 -1
  26. package/featureFlags/hooks.d.cts +1 -1
  27. package/featureFlags/hooks.d.mts +1 -1
  28. package/fileUpload/testUtils/mockFilesAndImages.d.cts +3 -3
  29. package/fileUpload/testUtils/mockFilesAndImages.d.cts.map +1 -1
  30. package/fileUpload/testUtils/mockFilesAndImages.d.mts +3 -3
  31. package/fileUpload/testUtils/mockFilesAndImages.d.mts.map +1 -1
  32. package/fileUpload/testUtils/testUtils.d.cts +1 -1
  33. package/fileUpload/testUtils/testUtils.d.cts.map +1 -1
  34. package/fileUpload/testUtils/testUtils.d.mts +1 -1
  35. package/fileUpload/testUtils/testUtils.d.mts.map +1 -1
  36. package/{index-BVb-FJDo.d.mts → index-BYPklw8m.d.mts} +2 -2
  37. package/{index-BVb-FJDo.d.mts.map → index-BYPklw8m.d.mts.map} +1 -1
  38. package/{index-3V0Y3AU3.d.mts → index-Bvn6svaT.d.cts} +2 -2
  39. package/{index-3V0Y3AU3.d.mts.map → index-Bvn6svaT.d.cts.map} +1 -1
  40. package/{index-Bu7c6X7O.d.mts → index-C2zPeUs9.d.mts} +5 -5
  41. package/{index-Bu7c6X7O.d.mts.map → index-C2zPeUs9.d.mts.map} +1 -1
  42. package/{index-BXz3rMMk.d.cts → index-Cmz2OD6x.d.cts} +2 -2
  43. package/{index-BXz3rMMk.d.cts.map → index-Cmz2OD6x.d.cts.map} +1 -1
  44. package/{index-kchg551L.d.cts → index-DsZAxqnF.d.mts} +2 -2
  45. package/{index-kchg551L.d.cts.map → index-DsZAxqnF.d.mts.map} +1 -1
  46. package/{index-BzN9RaXe.d.cts → index-QtMvgJcp.d.cts} +5 -5
  47. package/{index-BzN9RaXe.d.cts.map → index-QtMvgJcp.d.cts.map} +1 -1
  48. package/{index-dpfLYhgI.d.mts → index-hrztez-b.d.mts} +2 -2
  49. package/{index-DBYqF9Sr.d.cts.map → index-hrztez-b.d.mts.map} +1 -1
  50. package/{index-DBYqF9Sr.d.cts → index-o9dwzLLE.d.cts} +2 -2
  51. package/{index-dpfLYhgI.d.mts.map → index-o9dwzLLE.d.cts.map} +1 -1
  52. package/index.d.cts +7 -7
  53. package/index.d.mts +7 -7
  54. package/package.json +2 -2
  55. package/providers.d.cts +1 -1
  56. package/providers.d.mts +1 -1
  57. package/src/Accordion/Accordion.tsx +233 -0
  58. package/src/AddressDisplay/AddressDisplay.tsx +43 -0
  59. package/src/AddressDisplay/components/addressComponents.tsx +111 -0
  60. package/src/AddressDisplay/components/addressField.tsx +25 -0
  61. package/src/AddressDisplay/components/addressSection.tsx +8 -0
  62. package/src/AddressDisplay/components/getCountryValue.tsx +31 -0
  63. package/src/AddressDisplay/types.ts +26 -0
  64. package/src/AutomatedCarousel/AutomatedCarousel.tsx +163 -0
  65. package/src/AutomatedCarousel/automatedCarousel.types.ts +7 -0
  66. package/src/AutomatedCarousel/components/CarouselProgressBar/CarouselProgressBar.tsx +139 -0
  67. package/src/AutomatedCarousel/components/CarouselProgressBar/components/CarouselProgressBarUnit/CarouselProgressBarUnit.tsx +165 -0
  68. package/src/Badge/Badge.tsx +104 -0
  69. package/src/Badge/Badge.types.ts +58 -0
  70. package/src/Badge/ItemBadge.tsx +97 -0
  71. package/src/Badge/LiveStatusBadge.tsx +93 -0
  72. package/src/BannerNotification/BannerNotification.tsx +157 -0
  73. package/src/BannerNotification/components/BannerNotificationSkeleton.tsx +39 -0
  74. package/src/BannerNotification/components/CalloutIcon/BannerIcon.tsx +48 -0
  75. package/src/BannerNotification/utils/getRandomTooltipId.ts +3 -0
  76. package/src/BottomSheet/BottomSheet.tsx +476 -0
  77. package/src/BottomSheet/components/BottomSheetBackdrop/BottomSheetBackdrop.tsx +47 -0
  78. package/src/BottomSheet/components/BottomSheetContentArea/BottomSheetContentArea.tsx +92 -0
  79. package/src/BottomSheet/components/BottomSheetOverlay/BottomSheetOverlayTranslate3d.tsx +196 -0
  80. package/src/BottomSheet/components/SheetDescription/SheetDescription.tsx +22 -0
  81. package/src/BottomSheet/components/SheetTitle/SheetTitle.tsx +21 -0
  82. package/src/BottomSheet/components/index.tsx +5 -0
  83. package/src/BottomSheet/hooks/index.tsx +13 -0
  84. package/src/BottomSheet/hooks/useAriaHider.tsx +91 -0
  85. package/src/BottomSheet/hooks/useBottomSheetServices.tsx +224 -0
  86. package/src/BottomSheet/hooks/useDragHandler.tsx +282 -0
  87. package/src/BottomSheet/hooks/useFocusTrap.tsx +113 -0
  88. package/src/BottomSheet/hooks/useLayoutEffect.tsx +4 -0
  89. package/src/BottomSheet/hooks/useOptimizedResizeObserver.tsx +94 -0
  90. package/src/BottomSheet/hooks/useOptimizedScrollState.tsx +87 -0
  91. package/src/BottomSheet/hooks/useReady.tsx +34 -0
  92. package/src/BottomSheet/hooks/useReducedMotion.tsx +22 -0
  93. package/src/BottomSheet/hooks/useScrollLock.tsx +143 -0
  94. package/src/BottomSheet/hooks/useSnapPoints.tsx +355 -0
  95. package/src/BottomSheet/hooks/useSpring.tsx +47 -0
  96. package/src/BottomSheet/hooks/useSpringInterpolationsTranslate3d.tsx +101 -0
  97. package/src/BottomSheet/index.tsx +237 -0
  98. package/src/BottomSheet/state/atoms.ts +147 -0
  99. package/src/BottomSheet/state/useBottomSheetStateMachine.ts +246 -0
  100. package/src/BottomSheet/types.ts +172 -0
  101. package/src/BottomSheet/utils.ts +65 -0
  102. package/src/Breadcrumbs/Breadcrumbs.tsx +126 -0
  103. package/src/Button/Button.tsx +164 -0
  104. package/src/Button/Button.types.ts +80 -0
  105. package/src/Button/buttonColorClasses.ts +53 -0
  106. package/src/Callout/Callout.tsx +136 -0
  107. package/src/Callout/Callout.types.ts +29 -0
  108. package/src/Callout/components/CalloutIcon/CalloutIcon.tsx +56 -0
  109. package/src/Card/CardGrid.tsx +263 -0
  110. package/src/Card/SingleCard.tsx +22 -0
  111. package/src/Card/cardFactory.tsx +176 -0
  112. package/src/Card/components/createBadge.tsx +34 -0
  113. package/src/Card/components/createFavoriteButton.tsx +40 -0
  114. package/src/Card/components/createImage.tsx +64 -0
  115. package/src/Card/components/createInfo.tsx +84 -0
  116. package/src/Card/components/createName.tsx +63 -0
  117. package/src/Card/components/createPriceStatus.tsx +100 -0
  118. package/src/Card/components/types.ts +4 -0
  119. package/src/Card/hooks/useCardVisibilityTracking.ts +82 -0
  120. package/src/Card/sharedProps.ts +12 -0
  121. package/src/Card/types.ts +62 -0
  122. package/src/Carousel/Carousel.tsx +513 -0
  123. package/src/Carousel/Carousel.types.ts +43 -0
  124. package/src/Carousel/Carousel.utils.ts +63 -0
  125. package/src/Carousel/components/DotButton/DotButton.tsx +42 -0
  126. package/src/Carousel/components/NavigationButtons/NavigationButtons.tsx +77 -0
  127. package/src/Carousel/components/TitleSection/TitleSection.tsx +61 -0
  128. package/src/Carousel/components/TitleSection/components/SubHeaderLeft/SubHeaderLeft.tsx +53 -0
  129. package/src/Carousel/components/TitleSection/components/Title/Title.tsx +46 -0
  130. package/src/Carousel/index.ts +2 -0
  131. package/src/Carousel/testUtils.ts +10 -0
  132. package/src/Chips/Chip.tsx +153 -0
  133. package/src/Chips/ChipGroup.tsx +173 -0
  134. package/src/Chips/SuggestionChip.tsx +15 -0
  135. package/src/Chips/chipTypes.ts +113 -0
  136. package/src/Chips/index.ts +4 -0
  137. package/src/ChoiceListItem/Checkbox.tsx +69 -0
  138. package/src/ChoiceListItem/Radio.tsx +61 -0
  139. package/src/ChoiceListItem/choiceListItem.tsx +99 -0
  140. package/src/ChoiceListItem/common.tsx +148 -0
  141. package/src/ChoiceListItem/index.ts +3 -0
  142. package/src/Collapsible/Collapsible.tsx +58 -0
  143. package/src/Confetti/Confetti.tsx +270 -0
  144. package/src/Confetti/index.ts +2 -0
  145. package/src/ContentPager/ContentPager.tsx +189 -0
  146. package/src/ContentPager/components/Page.tsx +24 -0
  147. package/src/CookieConsent/components/CookieCategoryRow/CookieCategoryRow.tsx +30 -0
  148. package/src/CookieConsent/components/CookieConsent/CookieConsent.tsx +74 -0
  149. package/src/CookieConsent/components/CookieConsentBanner/CookieConsentBanner.tsx +51 -0
  150. package/src/CookieConsent/components/CookieConsentModal/CookieConsentModal.tsx +64 -0
  151. package/src/CookieConsent/hooks/useCookieConsent.ts +170 -0
  152. package/src/CookieConsent/hooks/useCookieConsentState.ts +142 -0
  153. package/src/CookieConsent/index.ts +16 -0
  154. package/src/CookieConsent/types/cookieConsent.types.ts +79 -0
  155. package/src/CookieConsent/types/index.ts +7 -0
  156. package/src/Countdown/Countdown.tsx +161 -0
  157. package/src/Countdown/Countdown.types.ts +4 -0
  158. package/src/Countdown/hooks/useGetCountdown.ts +103 -0
  159. package/src/DateTimeInput/dateInput/DateInput.tsx +199 -0
  160. package/src/DateTimeInput/datePicker/DatePicker.tsx +138 -0
  161. package/src/DateTimeInput/datePicker/components/calendar/Calendar.tsx +72 -0
  162. package/src/DateTimeInput/datePicker/index.ts +2 -0
  163. package/src/DateTimeInput/timeInput/TimeInput.tsx +128 -0
  164. package/src/DateTimeInput/timePicker/TimePicker.tsx +118 -0
  165. package/src/DateTimeInput/timePicker/components/TimePopover/AmPmSwitch.tsx +103 -0
  166. package/src/DateTimeInput/timePicker/components/TimePopover/TimeFieldInput.tsx +26 -0
  167. package/src/DateTimeInput/timePicker/components/TimePopover/TimePopover.tsx +84 -0
  168. package/src/DateTimeInput/timePicker/components/TimePopover/TimePopover.utils.ts +67 -0
  169. package/src/DateTimeInput/timePicker/components/TimePopover/TimePopoverActions.tsx +26 -0
  170. package/src/DateTimeInput/timePicker/index.ts +2 -0
  171. package/src/DateTimeInput/utils/getDisplayDate.ts +15 -0
  172. package/src/DateTimeInput/utils/getDisplayTime.ts +15 -0
  173. package/src/DateTimeInput/utils/index.ts +2 -0
  174. package/src/DateTimeInput/utils/parseTimeValue.ts +54 -0
  175. package/src/Drawer/Drawer.tsx +446 -0
  176. package/src/Drawer/atoms.ts +4 -0
  177. package/src/Drawer/components/DialogActions/DialogActions.tsx +33 -0
  178. package/src/Drawer/components/DialogContent/DialogContent.tsx +80 -0
  179. package/src/Drawer/components/DialogHeader/DialogHeader.tsx +68 -0
  180. package/src/EducationalPopover/EducationalPopover.tsx +174 -0
  181. package/src/FavoriteButton/FavoriteButton.tsx +64 -0
  182. package/src/FavoriteButton/components/IconOnlyFavoriteButton/IconOnlyFavoriteButton.tsx +80 -0
  183. package/src/FavoriteButton/components/LabeledAnimatedFavoriteButton/LabeledAnimatedFavoriteButton.tsx +179 -0
  184. package/src/FavoriteButton/components/LabeledFavoriteButton/LabeledFavoriteButton.tsx +71 -0
  185. package/src/FavoriteButton/components/SmallHeartStraightIcon/SmallHeartStraightIcon.tsx +14 -0
  186. package/src/FavoriteButton/hooks/useFavoriteButtonState.ts +30 -0
  187. package/src/FavoriteButton/index.ts +2 -0
  188. package/src/FavoriteButton/types/favoriteButton.ts +87 -0
  189. package/src/FeatureFlags/devTools/FeatureFlagDevToolsUI.tsx +226 -0
  190. package/src/FeatureFlags/devTools/getFeatureFlagCookieOverrides.ts +30 -0
  191. package/src/FeatureFlags/devTools/utils/cookies.ts +169 -0
  192. package/src/FeatureFlags/hooks/index.ts +2 -0
  193. package/src/FeatureFlags/hooks/useFeatureFlag.tsx +19 -0
  194. package/src/FeatureFlags/hooks/useFeatureFlags.tsx +15 -0
  195. package/src/FileUpload/components/FileCard/FileCard.tsx +50 -0
  196. package/src/FileUpload/components/FileDropzone/FileDropzone.tsx +221 -0
  197. package/src/FileUpload/components/FileDropzone/components/DropzoneContent/DropzoneContent.tsx +28 -0
  198. package/src/FileUpload/components/FileDropzone/components/DropzoneContent/DropzoneText.tsx +81 -0
  199. package/src/FileUpload/components/FileDropzone/components/FileDropzoneDebugger/FileDropzoneDebugger.tsx +40 -0
  200. package/src/FileUpload/components/FileDropzone/components/FileDropzoneDebugger/FileRejectionsDisplay.tsx +110 -0
  201. package/src/FileUpload/components/FileDropzoneOverlay/FileDropzoneOverlay.tsx +183 -0
  202. package/src/FileUpload/components/FileDropzoneOverlay/components/OverlayDropzoneContent.tsx +146 -0
  203. package/src/FileUpload/components/FileDropzoneOverlay/components/OverlayDropzoneDragText.tsx +42 -0
  204. package/src/FileUpload/components/FileDropzoneOverlay/styles.ts +79 -0
  205. package/src/FileUpload/components/FilePreviewList/FilePreviewList.tsx +251 -0
  206. package/src/FileUpload/components/FilePreviewList/virtualizerComponents/FilePreviewVirtualizedList/FilePreviewVirtualizedList.tsx +88 -0
  207. package/src/FileUpload/components/FileUpload/FileUpload.tsx +63 -0
  208. package/src/FileUpload/components/FileUploadCanvas/FileUploadCanvas.tsx +125 -0
  209. package/src/FileUpload/components/GridFileCard/GridFileCard.tsx +364 -0
  210. package/src/FileUpload/components/GridFileCard/utils/sortable.ts +48 -0
  211. package/src/FileUpload/components/ListFileCard/ListFileCard.tsx +259 -0
  212. package/src/FileUpload/components/types.ts +78 -0
  213. package/src/FileUpload/hooks/filePreview/useImageFilePreviewUrl.ts +62 -0
  214. package/src/FileUpload/hooks/index.ts +11 -0
  215. package/src/FileUpload/hooks/upload/useHandleDragEnter/useHandleDragEnter.ts +154 -0
  216. package/src/FileUpload/hooks/upload/useHandleDrop/createFileRejectionHelpers.ts +273 -0
  217. package/src/FileUpload/hooks/upload/useHandleDrop/useHandleDrop.ts +153 -0
  218. package/src/FileUpload/hooks/upload/useUploadAvailability/useUploadAvailability.ts +44 -0
  219. package/src/FileUpload/hooks/validation/createDropzoneValidator.ts +41 -0
  220. package/src/FileUpload/hooks/validation/useFileValidation.ts +25 -0
  221. package/src/FileUpload/hooks/validation/useFileValidationLogic.ts +107 -0
  222. package/src/FileUpload/hooks/validation/useValidationMessages.ts +92 -0
  223. package/src/FileUpload/hooks/validation/useValidationState.ts +171 -0
  224. package/src/FileUpload/index.ts +57 -0
  225. package/src/FileUpload/providers/FileUploadProvider.tsx +219 -0
  226. package/src/FileUpload/providers/UploadValidationProvider.tsx +159 -0
  227. package/src/FileUpload/testUtils/mockFilesAndImages.ts +64 -0
  228. package/src/FileUpload/testUtils/testUtils.ts +111 -0
  229. package/src/FileUpload/types/commonTypes.ts +267 -0
  230. package/src/FileUpload/types/index.ts +31 -0
  231. package/src/FileUpload/types/sharedTypes.ts +159 -0
  232. package/src/FileUpload/utils/constants.ts +79 -0
  233. package/src/FileUpload/utils/createMessageContext.ts +180 -0
  234. package/src/FileUpload/utils/getFileExtensionsFromAcceptedTypes.ts +73 -0
  235. package/src/FileUpload/utils/getFilePluralizationText.ts +68 -0
  236. package/src/FileUpload/utils/getMimeTypes.ts +26 -0
  237. package/src/FileUpload/utils/messageUtils.ts +41 -0
  238. package/src/FileUpload/utils/styles.ts +68 -0
  239. package/src/FormLabel/FormLabel.tsx +212 -0
  240. package/src/IconButton/IconButton.tsx +154 -0
  241. package/src/Icons/CreditCardIcon/CreditCardIcon.tsx +73 -0
  242. package/src/Icons/CreditCardIcon/cardIcons.tsx +270 -0
  243. package/src/Icons/IconBase.tsx +133 -0
  244. package/src/Icons/anyIcon.ts +3 -0
  245. package/src/Icons/generatedIcons/Archive.tsx +48 -0
  246. package/src/Icons/generatedIcons/ArrowClockwise.tsx +48 -0
  247. package/src/Icons/generatedIcons/ArrowDown.tsx +48 -0
  248. package/src/Icons/generatedIcons/ArrowLeft.tsx +48 -0
  249. package/src/Icons/generatedIcons/ArrowRight.tsx +48 -0
  250. package/src/Icons/generatedIcons/ArrowSquareOut.tsx +51 -0
  251. package/src/Icons/generatedIcons/ArrowSquareRight.tsx +51 -0
  252. package/src/Icons/generatedIcons/ArrowUp.tsx +48 -0
  253. package/src/Icons/generatedIcons/ArrowsCounterClockwise.tsx +48 -0
  254. package/src/Icons/generatedIcons/ArrowsLeftRight.tsx +48 -0
  255. package/src/Icons/generatedIcons/ArrowsOutCardinal.tsx +48 -0
  256. package/src/Icons/generatedIcons/Bank.tsx +48 -0
  257. package/src/Icons/generatedIcons/Bell.tsx +51 -0
  258. package/src/Icons/generatedIcons/BookBookmark.tsx +51 -0
  259. package/src/Icons/generatedIcons/BookmarksSimple.tsx +51 -0
  260. package/src/Icons/generatedIcons/Broadcast.tsx +48 -0
  261. package/src/Icons/generatedIcons/CalendarBlank.tsx +48 -0
  262. package/src/Icons/generatedIcons/CalendarStar.tsx +51 -0
  263. package/src/Icons/generatedIcons/Camera.tsx +51 -0
  264. package/src/Icons/generatedIcons/CaretDown.tsx +48 -0
  265. package/src/Icons/generatedIcons/CaretLeft.tsx +48 -0
  266. package/src/Icons/generatedIcons/CaretRight.tsx +48 -0
  267. package/src/Icons/generatedIcons/CaretUp.tsx +48 -0
  268. package/src/Icons/generatedIcons/Certificate.tsx +51 -0
  269. package/src/Icons/generatedIcons/ChartBar.tsx +48 -0
  270. package/src/Icons/generatedIcons/Check.tsx +51 -0
  271. package/src/Icons/generatedIcons/CheckCircle.tsx +48 -0
  272. package/src/Icons/generatedIcons/CirclesFour.tsx +51 -0
  273. package/src/Icons/generatedIcons/Clock.tsx +48 -0
  274. package/src/Icons/generatedIcons/ClockCountdown.tsx +48 -0
  275. package/src/Icons/generatedIcons/Close.tsx +51 -0
  276. package/src/Icons/generatedIcons/CloudArrowUp.tsx +51 -0
  277. package/src/Icons/generatedIcons/CloudWarning.tsx +51 -0
  278. package/src/Icons/generatedIcons/Code.tsx +48 -0
  279. package/src/Icons/generatedIcons/Compass.tsx +51 -0
  280. package/src/Icons/generatedIcons/Confetti.tsx +51 -0
  281. package/src/Icons/generatedIcons/Copy.tsx +48 -0
  282. package/src/Icons/generatedIcons/CornersOut.tsx +48 -0
  283. package/src/Icons/generatedIcons/CreditCard.tsx +48 -0
  284. package/src/Icons/generatedIcons/Crown.tsx +51 -0
  285. package/src/Icons/generatedIcons/CrownSimple.tsx +51 -0
  286. package/src/Icons/generatedIcons/CurrencyCircleDollar.tsx +48 -0
  287. package/src/Icons/generatedIcons/CurrencyDollarSimple.tsx +51 -0
  288. package/src/Icons/generatedIcons/Desktop.tsx +51 -0
  289. package/src/Icons/generatedIcons/Detective.tsx +51 -0
  290. package/src/Icons/generatedIcons/DotOutline.tsx +46 -0
  291. package/src/Icons/generatedIcons/DotsSixVertical.tsx +51 -0
  292. package/src/Icons/generatedIcons/DotsThreeOutline.tsx +51 -0
  293. package/src/Icons/generatedIcons/DotsThreeOutlineVertical.tsx +51 -0
  294. package/src/Icons/generatedIcons/DownloadSimple.tsx +51 -0
  295. package/src/Icons/generatedIcons/EnvelopeSimple.tsx +48 -0
  296. package/src/Icons/generatedIcons/Eraser.tsx +51 -0
  297. package/src/Icons/generatedIcons/Eye.tsx +51 -0
  298. package/src/Icons/generatedIcons/EyeSlash.tsx +51 -0
  299. package/src/Icons/generatedIcons/FacebookLogo.tsx +48 -0
  300. package/src/Icons/generatedIcons/FileArchive.tsx +48 -0
  301. package/src/Icons/generatedIcons/FileArrowDown.tsx +48 -0
  302. package/src/Icons/generatedIcons/FileCsv.tsx +48 -0
  303. package/src/Icons/generatedIcons/FilePdf.tsx +48 -0
  304. package/src/Icons/generatedIcons/FileText.tsx +48 -0
  305. package/src/Icons/generatedIcons/Files.tsx +51 -0
  306. package/src/Icons/generatedIcons/Fire.tsx +51 -0
  307. package/src/Icons/generatedIcons/Flag.tsx +51 -0
  308. package/src/Icons/generatedIcons/FlagBannerFold.tsx +48 -0
  309. package/src/Icons/generatedIcons/FloppyDisk.tsx +51 -0
  310. package/src/Icons/generatedIcons/Gauge.tsx +51 -0
  311. package/src/Icons/generatedIcons/Gavel.tsx +51 -0
  312. package/src/Icons/generatedIcons/Gear.tsx +51 -0
  313. package/src/Icons/generatedIcons/GlobeHemisphereWest.tsx +51 -0
  314. package/src/Icons/generatedIcons/GoogleLogo.tsx +48 -0
  315. package/src/Icons/generatedIcons/GridNine.tsx +51 -0
  316. package/src/Icons/generatedIcons/HandCoins.tsx +51 -0
  317. package/src/Icons/generatedIcons/HandbagSimple.tsx +51 -0
  318. package/src/Icons/generatedIcons/Headset.tsx +51 -0
  319. package/src/Icons/generatedIcons/HeartStraight.tsx +51 -0
  320. package/src/Icons/generatedIcons/HourglassLow.tsx +48 -0
  321. package/src/Icons/generatedIcons/House.tsx +51 -0
  322. package/src/Icons/generatedIcons/Image.tsx +51 -0
  323. package/src/Icons/generatedIcons/ImageSquare.tsx +51 -0
  324. package/src/Icons/generatedIcons/ImagesSquare.tsx +51 -0
  325. package/src/Icons/generatedIcons/Info.tsx +48 -0
  326. package/src/Icons/generatedIcons/InstagramLogo.tsx +51 -0
  327. package/src/Icons/generatedIcons/Lightning.tsx +48 -0
  328. package/src/Icons/generatedIcons/Link.tsx +51 -0
  329. package/src/Icons/generatedIcons/LinkedinLogo.tsx +51 -0
  330. package/src/Icons/generatedIcons/List.tsx +48 -0
  331. package/src/Icons/generatedIcons/Lock.tsx +51 -0
  332. package/src/Icons/generatedIcons/LockOpen.tsx +51 -0
  333. package/src/Icons/generatedIcons/MagnifyingGlass.tsx +48 -0
  334. package/src/Icons/generatedIcons/MapPin.tsx +51 -0
  335. package/src/Icons/generatedIcons/MapPinSimpleArea.tsx +48 -0
  336. package/src/Icons/generatedIcons/Medal.tsx +48 -0
  337. package/src/Icons/generatedIcons/Megaphone.tsx +48 -0
  338. package/src/Icons/generatedIcons/Minus.tsx +45 -0
  339. package/src/Icons/generatedIcons/Money.tsx +51 -0
  340. package/src/Icons/generatedIcons/Notches.tsx +48 -0
  341. package/src/Icons/generatedIcons/NotePencil.tsx +48 -0
  342. package/src/Icons/generatedIcons/Package.tsx +51 -0
  343. package/src/Icons/generatedIcons/PaintBrush.tsx +51 -0
  344. package/src/Icons/generatedIcons/PaperPlaneTilt.tsx +51 -0
  345. package/src/Icons/generatedIcons/Paperclip.tsx +51 -0
  346. package/src/Icons/generatedIcons/Pause.tsx +51 -0
  347. package/src/Icons/generatedIcons/PencilLine.tsx +51 -0
  348. package/src/Icons/generatedIcons/PencilRuler.tsx +51 -0
  349. package/src/Icons/generatedIcons/PencilSimple.tsx +51 -0
  350. package/src/Icons/generatedIcons/Phone.tsx +51 -0
  351. package/src/Icons/generatedIcons/PinterestLogo.tsx +51 -0
  352. package/src/Icons/generatedIcons/Play.tsx +51 -0
  353. package/src/Icons/generatedIcons/Plus.tsx +51 -0
  354. package/src/Icons/generatedIcons/PlusCircle.tsx +48 -0
  355. package/src/Icons/generatedIcons/Printer.tsx +51 -0
  356. package/src/Icons/generatedIcons/Question.tsx +48 -0
  357. package/src/Icons/generatedIcons/Receipt.tsx +51 -0
  358. package/src/Icons/generatedIcons/Rows.tsx +51 -0
  359. package/src/Icons/generatedIcons/SealCheck.tsx +51 -0
  360. package/src/Icons/generatedIcons/SelectionSlash.tsx +48 -0
  361. package/src/Icons/generatedIcons/ShareNetwork.tsx +51 -0
  362. package/src/Icons/generatedIcons/ShieldCheck.tsx +51 -0
  363. package/src/Icons/generatedIcons/ShieldStar.tsx +51 -0
  364. package/src/Icons/generatedIcons/ShoppingCart.tsx +48 -0
  365. package/src/Icons/generatedIcons/ShuffleAngular.tsx +48 -0
  366. package/src/Icons/generatedIcons/SidebarSimple.tsx +48 -0
  367. package/src/Icons/generatedIcons/SlidersHorizontal.tsx +51 -0
  368. package/src/Icons/generatedIcons/Smiley.tsx +48 -0
  369. package/src/Icons/generatedIcons/Sparkle.tsx +51 -0
  370. package/src/Icons/generatedIcons/SpinnerGap.tsx +48 -0
  371. package/src/Icons/generatedIcons/StackPlus.tsx +48 -0
  372. package/src/Icons/generatedIcons/Star.tsx +51 -0
  373. package/src/Icons/generatedIcons/Storefront.tsx +51 -0
  374. package/src/Icons/generatedIcons/Swap.tsx +51 -0
  375. package/src/Icons/generatedIcons/Tag.tsx +51 -0
  376. package/src/Icons/generatedIcons/ThumbsDown.tsx +48 -0
  377. package/src/Icons/generatedIcons/ThumbsUp.tsx +48 -0
  378. package/src/Icons/generatedIcons/Toolbox.tsx +48 -0
  379. package/src/Icons/generatedIcons/Trash.tsx +48 -0
  380. package/src/Icons/generatedIcons/TrendUp.tsx +48 -0
  381. package/src/Icons/generatedIcons/Trophy.tsx +51 -0
  382. package/src/Icons/generatedIcons/Truck.tsx +51 -0
  383. package/src/Icons/generatedIcons/UploadSimple.tsx +51 -0
  384. package/src/Icons/generatedIcons/User.tsx +48 -0
  385. package/src/Icons/generatedIcons/Users.tsx +48 -0
  386. package/src/Icons/generatedIcons/UsersThree.tsx +51 -0
  387. package/src/Icons/generatedIcons/VideoCamera.tsx +51 -0
  388. package/src/Icons/generatedIcons/Warning.tsx +51 -0
  389. package/src/Icons/generatedIcons/WarningCircle.tsx +48 -0
  390. package/src/Icons/generatedIcons/WifiHigh.tsx +51 -0
  391. package/src/Icons/generatedIcons/XCircle.tsx +48 -0
  392. package/src/Icons/generatedIcons/XLogo.tsx +48 -0
  393. package/src/Icons/generatedIcons/YoutubeLogo.tsx +51 -0
  394. package/src/Icons/importedIcons.ts +152 -0
  395. package/src/Icons/index.ts +149 -0
  396. package/src/Icons/socialIcons/appleSocialIcon.tsx +50 -0
  397. package/src/Icons/socialIcons/facebookSocialIcon.tsx +41 -0
  398. package/src/Icons/socialIcons/googleSocialIcon.tsx +134 -0
  399. package/src/ImageCluster/ImageCluster.tsx +125 -0
  400. package/src/ImageSlider/ImageSlider.tsx +582 -0
  401. package/src/ImageSlider/ImageSlider.types.ts +90 -0
  402. package/src/ImageSlider/components/IndexIndicator/IndexIndicator.tsx +21 -0
  403. package/src/ImageSlider/components/NavigationButtons/NavigationButtons.tsx +113 -0
  404. package/src/ImageSlider/components/ResponsiveImage/ResponsiveImage.tsx +114 -0
  405. package/src/ImageSlider/components/ResponsiveImage/index.ts +1 -0
  406. package/src/ImageSlider/components/Thumbnails/Thumbnails.tsx +184 -0
  407. package/src/ImageSlider/constants.ts +59 -0
  408. package/src/ImageSlider/hooks/index.ts +3 -0
  409. package/src/ImageSlider/hooks/useImageSlider.ts +57 -0
  410. package/src/ImageSlider/hooks/useImageSliderNavigation.ts +133 -0
  411. package/src/ImageSlider/hooks/useImageSliderScrollHandler.ts +171 -0
  412. package/src/ImageSlider/index.ts +3 -0
  413. package/src/ImageSlider/utils/imageOptimization.ts +97 -0
  414. package/src/ImageSlider/utils/index.ts +1 -0
  415. package/src/InlineNotification/InlineNotification.tsx +95 -0
  416. package/src/JumpMenu/JumpMenu.tsx +395 -0
  417. package/src/JumpMenu/components/JumpMenuItem/JumpMenuItem.tsx +62 -0
  418. package/src/JumpMenu/hooks/useContainerTracking.ts +171 -0
  419. package/src/JumpMenu/hooks/useIntersectionObserver.ts +77 -0
  420. package/src/JumpMenu/hooks/useKeyboardNavigation.ts +102 -0
  421. package/src/JumpMenu/hooks/useResizeObserver.ts +53 -0
  422. package/src/JumpMenu/hooks/useSectionObserver.ts +102 -0
  423. package/src/JumpMenu/index.ts +2 -0
  424. package/src/JumpMenu/types/index.ts +19 -0
  425. package/src/Loading/Loading.tsx +39 -0
  426. package/src/Loading/components/LoadingDot/LoadingDot.tsx +16 -0
  427. package/src/LoadingSpinner/LoadingSpinner.tsx +20 -0
  428. package/src/Menu/Menu.tsx +372 -0
  429. package/src/Menu/components/MenuDivider/MenuDivider.tsx +5 -0
  430. package/src/Menu/components/MenuItem/MenuItem.tsx +298 -0
  431. package/src/Menu/context/menuContext.tsx +20 -0
  432. package/src/Menu/hooks/useMenu.tsx +18 -0
  433. package/src/Menu/index.ts +3 -0
  434. package/src/Modal/ComposableModal.tsx +313 -0
  435. package/src/Modal/Modal.tsx +231 -0
  436. package/src/Modal/components/BackButton/BackButton.tsx +43 -0
  437. package/src/Modal/components/Backdrop/Backdrop.tsx +62 -0
  438. package/src/Modal/components/CloseButton/CloseButton.tsx +55 -0
  439. package/src/Modal/components/ModalActions/ModalActions.tsx +135 -0
  440. package/src/Modal/components/ModalContent/ModalContent.tsx +163 -0
  441. package/src/Modal/components/ModalHeader/ModalHeader.tsx +84 -0
  442. package/src/Modal/components/ModalHeader/hooks/useHeaderAnimation.tsx +49 -0
  443. package/src/Modal/components/ModalProgressSteps/ModalProgressSteps.tsx +26 -0
  444. package/src/Modal/components/ModalSubTitle/ModalSubTitle.tsx +29 -0
  445. package/src/Modal/components/ModalTitle/ModalTitle.tsx +22 -0
  446. package/src/Modal/components/PreventModalScroll/PreventModalScroll.tsx +106 -0
  447. package/src/Modal/components/index.ts +12 -0
  448. package/src/Modal/context.ts +33 -0
  449. package/src/Modal/hooks/useCloseModal.ts +133 -0
  450. package/src/NotificationBadge/NotificationBadge.tsx +34 -0
  451. package/src/Pagination/AdvancedPagination.tsx +48 -0
  452. package/src/Pagination/Pagination.tsx +216 -0
  453. package/src/Pagination/components/AdvancedPaginator/AdvancedPaginator.tsx +52 -0
  454. package/src/Pagination/components/AdvancedPaginator/components/PageSelect/PageSelect.tsx +43 -0
  455. package/src/Pagination/components/ItemCountDisplay/ItemCountDisplay.tsx +32 -0
  456. package/src/Pagination/components/ItemCountSelect/ItemCountSelect.tsx +33 -0
  457. package/src/Pagination/index.tsx +3 -0
  458. package/src/Pagination/paginationProvider.tsx +234 -0
  459. package/src/Pagination/utils.tsx +36 -0
  460. package/src/PhoneInput/PhoneInput.tsx +509 -0
  461. package/src/PhoneInput/useDropdownLogic.tsx +163 -0
  462. package/src/ProgressCircle/ProgressCircle.tsx +246 -0
  463. package/src/ProgressCircle/hooks/useProgressStatusTransitions.ts +49 -0
  464. package/src/ProgressCircle/utils/progressCircle.constants.ts +27 -0
  465. package/src/ProgressSteps/ProgressSteps.tsx +160 -0
  466. package/src/SaveConfetti/SaveConfetti.tsx +277 -0
  467. package/src/SaveConfetti/index.ts +2 -0
  468. package/src/SearchInput/SearchInput.tsx +236 -0
  469. package/src/SegmentedControl/SegmentedControl.tsx +111 -0
  470. package/src/SegmentedControl/SegmentedControlGroup.tsx +94 -0
  471. package/src/SegmentedControl/index.ts +4 -0
  472. package/src/Select/Select.tsx +154 -0
  473. package/src/Select/SelectAsync.tsx +13 -0
  474. package/src/Select/SelectAsyncCreatable.tsx +14 -0
  475. package/src/Select/SelectCreatable.tsx +12 -0
  476. package/src/Select/reexportedComponents.tsx +5 -0
  477. package/src/Select/selectComponents.tsx +306 -0
  478. package/src/Skeleton/Skeleton.tsx +13 -0
  479. package/src/SplitButton/SplitButton.tsx +298 -0
  480. package/src/SplitButton/SplitButtonTrigger.tsx +55 -0
  481. package/src/StarRating/StarRating.tsx +165 -0
  482. package/src/StarRating/components/StarComponent/StarComponent.tsx +44 -0
  483. package/src/Table/Table.tsx +474 -0
  484. package/src/Table/components/TableHeader/TableHeader.tsx +166 -0
  485. package/src/Table/components/TablePagination/TablePagination.tsx +18 -0
  486. package/src/Table/components/TablePagination/components/ItemCountDisplay/ItemCountDisplay.tsx +17 -0
  487. package/src/Table/components/TablePagination/components/ItemCountSelect/ItemCountSelect.tsx +31 -0
  488. package/src/Table/components/TablePagination/components/TablePaginator/TablePaginator.tsx +37 -0
  489. package/src/Table/components/TablePagination/components/TablePaginator/components/PageSelect/PageSelect.tsx +32 -0
  490. package/src/Table/components/TableRow/TableRows.tsx +147 -0
  491. package/src/Table/components/TableRow/components/TableRowCell/TableRowCell.tsx +49 -0
  492. package/src/Table/components/TableShadow/TableShadow.tsx +46 -0
  493. package/src/Table/index.ts +2 -0
  494. package/src/Table/sharedState.ts +30 -0
  495. package/src/Table/sharedStyles.ts +1 -0
  496. package/src/Table/types.ts +55 -0
  497. package/src/Tabs/Tabs.tsx +358 -0
  498. package/src/TextArea/TextArea.tsx +157 -0
  499. package/src/TextInput/TextInput.tsx +173 -0
  500. package/src/Toast/Toast.tsx +64 -0
  501. package/src/Toast/components/ToastContainer/ToastContainer.tsx +48 -0
  502. package/src/Toast/index.ts +2 -0
  503. package/src/Toast/types/role.ts +1 -0
  504. package/src/Toast/utils/getIcon.tsx +41 -0
  505. package/src/ToggleSwitch/ToggleSwitch.tsx +188 -0
  506. package/src/Tooltip/InfoIconTooltip.tsx +47 -0
  507. package/src/Tooltip/Tooltip.tsx +41 -0
  508. package/src/Typography/InlineButton/InlineButton.tsx +166 -0
  509. package/src/Typography/Links/Links.tsx +113 -0
  510. package/src/Typography/Text/Text.tsx +239 -0
  511. package/src/ViewMore/ViewMore.tsx +226 -0
  512. package/src/WebRTCPlayer/WebRTCPlayer.tsx +325 -0
  513. package/src/WebRTCPlayer/adaptor/NativeWebRTCAdaptor.ts +588 -0
  514. package/src/WebRTCPlayer/hooks/useWebRTCStream.ts +571 -0
  515. package/src/WebRTCPlayer/index.ts +22 -0
  516. package/src/WebRTCPlayer/types.ts +95 -0
  517. package/src/breakpoints/index.tsx +1 -0
  518. package/src/breakpoints/utils.tsx +50 -0
  519. package/src/declarations.d.ts +7 -0
  520. package/src/grid/gridHighlighter.tsx +83 -0
  521. package/src/grid/index.ts +3 -0
  522. package/src/grid/pageGrid.tsx +37 -0
  523. package/src/grid/useSubGridCSS.tsx +214 -0
  524. package/src/hooks/useHorizontalScrollFade.ts +44 -0
  525. package/src/hooks/usePrevious.ts +14 -0
  526. package/src/index.ts +351 -0
  527. package/src/intl/index.ts +4 -0
  528. package/src/intl/utils.ts +67 -0
  529. package/src/mixins/horizontalScrollFadeMixin.ts +56 -0
  530. package/src/mixins/index.ts +18 -0
  531. package/src/mixins/propMixins.ts +389 -0
  532. package/src/providers/createContextProvider.ts +22 -0
  533. package/src/providers/designSystemProvider.tsx +218 -0
  534. package/src/providers/errorBoundaryProvider.tsx +179 -0
  535. package/src/providers/featureFlagProvider.tsx +18 -0
  536. package/src/providers/gridSizeProvider.tsx +23 -0
  537. package/src/providers/index.ts +12 -0
  538. package/src/providers/linkProvider.tsx +32 -0
  539. package/src/providers/normalize.tsx +93 -0
  540. package/src/providers/targets/DatePickerTarget.tsx +10 -0
  541. package/src/providers/targets/ModalTarget.tsx +14 -0
  542. package/src/providers/targets/TimePickerTarget.tsx +10 -0
  543. package/src/providers/themeContext.tsx +24 -0
  544. package/src/providers/windowSizeProvider.tsx +125 -0
  545. package/src/spacing/index.ts +1 -0
  546. package/src/spacing/spacing.ts +11 -0
  547. package/src/utils/countriesWithISOCodes.ts +1419 -0
  548. package/src/utils/dateTimeFormat.ts +257 -0
  549. package/src/utils/effectEventListener.ts +11 -0
  550. package/src/utils/formatFileSize.ts +18 -0
  551. package/src/utils/isClientSide.ts +1 -0
  552. package/src/utils/keepTransition.ts +15 -0
  553. package/src/utils/nodeEnv.ts +9 -0
  554. package/src/utils/smoothScrollTo.ts +47 -0
  555. package/src/utils/utilityTypes.ts +13 -0
  556. package/textInput.d.cts +1 -1
  557. package/textInput.d.mts +1 -1
  558. package/timePicker.d.cts +1 -1
  559. package/timePicker.d.mts +1 -1
@@ -0,0 +1,582 @@
1
+ import { cn } from '@evolve.ui/theme-system';
2
+ import { useCallback, useMemo, useState, type CSSProperties } from 'react';
3
+
4
+ import { IndexIndicator } from './components/IndexIndicator/IndexIndicator';
5
+ import { NavigationButtons } from './components/NavigationButtons/NavigationButtons';
6
+ import { ResponsiveImage } from './components/ResponsiveImage';
7
+ import { Thumbnails } from './components/Thumbnails/Thumbnails';
8
+ import { PLACEHOLDER_EMPTY_CARDS } from './constants';
9
+ import { useImageSlider } from './hooks/useImageSlider';
10
+ import { useImageSliderNavigation } from './hooks/useImageSliderNavigation';
11
+ import { useImageSliderScrollHandler } from './hooks/useImageSliderScrollHandler';
12
+ import {
13
+ ImageSliderAnalyticsEvent,
14
+ ImageSliderCard,
15
+ ResponsiveImageConfig,
16
+ ThumbnailDisplay,
17
+ } from './ImageSlider.types';
18
+ import { generateThumbnailSizesAttribute, generateThumbnailSrcSet } from './utils/imageOptimization';
19
+
20
+ type Props = {
21
+ /**
22
+ * The scrollable content of the image slider.
23
+ * Should be individual images.
24
+ *
25
+ * @property {ReactNode} card - The rendered image content
26
+ * @property {string} key - A unique identifier for the image
27
+ */
28
+ cards: ImageSliderCard[];
29
+ /**
30
+ * Class name for the image gallery container.
31
+ */
32
+ className?: string;
33
+ /**
34
+ * Optional key to identify when content has changed (e.g., an item id).
35
+ * When this key changes, the slider will reset to the first image.
36
+ * If not provided, will reset whenever the cards array reference changes.
37
+ */
38
+ contentKey?: string | number;
39
+ /**
40
+ * Shape of the navigation icons.
41
+ * 'circle' creates round buttons, 'square' creates square buttons.
42
+ *
43
+ * @default 'circle'
44
+ */
45
+ iconShape?: 'circle' | 'square';
46
+ /**
47
+ * Size of the navigation icons - sm=34px, md=42px, lg=54px.
48
+ * For horizontal thumbnails, 'lg' (54px) is recommended.
49
+ *
50
+ * @default 'sm'
51
+ */
52
+ iconSize?: 'sm' | 'md' | 'lg';
53
+ /**
54
+ * Type of icons to use for navigation.
55
+ * 'caret' uses CaretLeft/CaretRight, 'arrow' uses ArrowLeft/ArrowRight.
56
+ *
57
+ * @default 'caret'
58
+ */
59
+ iconType?: 'caret' | 'arrow';
60
+ /**
61
+ * Variant of the navigation icons.
62
+ * 'outlined' shows buttons with borders, 'transparent' shows borderless buttons.
63
+ *
64
+ * @default 'outlined'
65
+ */
66
+ iconVariant?: 'outlined' | 'transparent';
67
+ /**
68
+ * When thumbnailDisplay is 'index', position of the numeric indicator relative to the main image.
69
+ *
70
+ * @default 'bottom'
71
+ */
72
+ indexPosition?: 'top' | 'bottom';
73
+ /**
74
+ * Callback fired when an analytics event occurs in the image slider.
75
+ * Receives interaction type, current image position (1-based), and total image count.
76
+ * Does not fire for mobile swipe navigation, only for button/thumbnail clicks and lightbox opens.
77
+ */
78
+ onAnalyticsEventTriggered?: (event: ImageSliderAnalyticsEvent) => void;
79
+ /**
80
+ * Callback fired when an image is clicked (mouse) or activated via keyboard (Enter/Space).
81
+ * Receives the index of the image and the mouse or keyboard event.
82
+ */
83
+ onImageClick?: (
84
+ imageIndex: number,
85
+ event: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>
86
+ ) => void;
87
+ /**
88
+ * Callback fired when an image is hovered (mouse) or focused (keyboard/screen reader).
89
+ * Receives the index of the image and the mouse or focus event.
90
+ */
91
+ onImageMouseOver?: (
92
+ imageIndex: number,
93
+ event: React.MouseEvent<HTMLElement> | React.FocusEvent<HTMLElement>
94
+ ) => void;
95
+ /**
96
+ * Configuration for responsive image loading when using imageData in cards.
97
+ * Defines mobile/desktop sizes and breakpoint for optimal image loading.
98
+ */
99
+ responsiveImageConfig?: ResponsiveImageConfig;
100
+ /**
101
+ * Displays thumbnail previews on the left side of the slider.
102
+ * Clicking a thumbnail will navigate to the corresponding image.
103
+ * The current image thumbnail will have a border highlight.
104
+ *
105
+ * @default true
106
+ */
107
+ showThumbnails?: boolean;
108
+ /**
109
+ * Display mode for image navigation controls.
110
+ * 'thumbnails' shows image previews (vertical or horizontal per thumbnailOrientation).
111
+ * 'index' shows a numeric indicator (e.g., "1 of 11") above or below the main image per indexPosition.
112
+ *
113
+ * @default ThumbnailDisplay.Thumbnails
114
+ */
115
+ thumbnailDisplay?: ThumbnailDisplay;
116
+ /**
117
+ * Orientation of the thumbnail previews when showThumbnails is true.
118
+ * 'vertical' displays thumbnails on the left side, 'horizontal' displays them below the image.
119
+ *
120
+ * @default 'vertical'
121
+ */
122
+ thumbnailOrientation?: 'vertical' | 'horizontal';
123
+ };
124
+
125
+ /**
126
+ * Displays a single image at a time with navigation controls.
127
+ * Allows navigation via buttons, dots (pagination), or touch gestures (on mobile).
128
+ */
129
+ // Default responsive image configuration
130
+ const DEFAULT_RESPONSIVE_CONFIG: ResponsiveImageConfig = {
131
+ breakpoint: 768,
132
+ desktopSize: 651,
133
+ mobileSize: 366,
134
+ };
135
+
136
+ export const ImageSlider = ({
137
+ cards: initialCards,
138
+ className,
139
+ contentKey,
140
+ iconShape = 'circle',
141
+ iconSize = 'sm',
142
+ iconType = 'caret',
143
+ iconVariant = 'outlined',
144
+ indexPosition = 'bottom',
145
+ onAnalyticsEventTriggered,
146
+ onImageClick,
147
+ onImageMouseOver,
148
+ responsiveImageConfig = DEFAULT_RESPONSIVE_CONFIG,
149
+ showThumbnails = true,
150
+ thumbnailDisplay = ThumbnailDisplay.Thumbnails,
151
+ thumbnailOrientation = 'vertical',
152
+ }: Props) => {
153
+ // When an item doesn't have images, the cards array will be empty.
154
+ // We need to show a placeholder empty card in this case.
155
+ const cards = useMemo(() => {
156
+ if (initialCards.length === 0) {
157
+ return PLACEHOLDER_EMPTY_CARDS;
158
+ }
159
+ return initialCards;
160
+ }, [initialCards]);
161
+
162
+ const numberOfPages = cards.length;
163
+
164
+ // Initialize base slider state and refs
165
+ const {
166
+ containerRef,
167
+ contentRef,
168
+ handleMobileInteraction,
169
+ handleMouseOver,
170
+ hasHoveredGallery,
171
+ isMobile,
172
+ setHasHoveredGallery,
173
+ } = useImageSlider({
174
+ numberOfPages,
175
+ responsiveImageConfig,
176
+ });
177
+
178
+ // Manage scrolling state locally to avoid circular dependency
179
+ const [isScrolling, setIsScrolling] = useState(false);
180
+
181
+ // Initialize navigation state and handlers
182
+ const navigation = useImageSliderNavigation({
183
+ cards,
184
+ contentKey,
185
+ contentRef,
186
+ isScrolling,
187
+ numberOfPages,
188
+ setHasHoveredGallery,
189
+ thumbnailDisplay,
190
+ thumbnailOrientation,
191
+ });
192
+
193
+ // Initialize scroll handling with navigation state and local setIsScrolling
194
+ const { onScrollCards } = useImageSliderScrollHandler({
195
+ contentRef,
196
+ currentPage: navigation.currentPage,
197
+ maxMobileCardWidth: responsiveImageConfig.desktopSize,
198
+ numberOfPages,
199
+ setCurrentPage: navigation.setCurrentPage,
200
+ setIsScrolling,
201
+ });
202
+
203
+ // Extract all the values we need
204
+ const {
205
+ currentPage,
206
+ goToNextPage,
207
+ goToPreviousPage,
208
+ handleThumbnailClick,
209
+ isNextPageDisabled,
210
+ isPreviousPageDisabled,
211
+ onKeyNavigation,
212
+ showNextPageButton,
213
+ showPreviousPageButton,
214
+ } = navigation;
215
+
216
+ // Wrap navigation handlers to trigger analytics
217
+ const goToNextPageWithAnalytics = useCallback(() => {
218
+ goToNextPage();
219
+ onAnalyticsEventTriggered?.({
220
+ imagePosition: currentPage < numberOfPages ? currentPage + 1 : 1,
221
+ interactionType: 'Next',
222
+ totalImages: numberOfPages,
223
+ });
224
+ }, [goToNextPage, onAnalyticsEventTriggered, currentPage, numberOfPages]);
225
+
226
+ const goToPreviousPageWithAnalytics = useCallback(() => {
227
+ goToPreviousPage();
228
+ onAnalyticsEventTriggered?.({
229
+ imagePosition: currentPage > 1 ? currentPage - 1 : numberOfPages,
230
+ interactionType: 'Prev',
231
+ totalImages: numberOfPages,
232
+ });
233
+ }, [goToPreviousPage, onAnalyticsEventTriggered, currentPage, numberOfPages]);
234
+
235
+ const handleThumbnailClickWithAnalytics = useCallback(
236
+ (pageNumber: number) => {
237
+ // Only trigger analytics if navigating to a different image
238
+ if (pageNumber !== currentPage && onAnalyticsEventTriggered) {
239
+ onAnalyticsEventTriggered({
240
+ imagePosition: pageNumber,
241
+ interactionType: 'Thumbnail Click',
242
+ totalImages: numberOfPages,
243
+ });
244
+ }
245
+ handleThumbnailClick(pageNumber);
246
+ },
247
+ [currentPage, handleThumbnailClick, onAnalyticsEventTriggered, numberOfPages]
248
+ );
249
+
250
+ /**
251
+ * These images are wrapped in a div and displayed one at a time with proper snap behavior.
252
+ * When showImageOverflow is enabled on mobile, images take partial width to show overflow.
253
+ * Supports both custom ReactNode cards and responsive imageData.
254
+ * Images are re-rendered when currentPage changes to ensure active image gets full quality.
255
+ *
256
+ * On desktop before hover: Only render first image to avoid loading second image unnecessarily.
257
+ * On mobile: Always render all images for swipe functionality.
258
+ * After hover on desktop: Render all images for navigation.
259
+ */
260
+ const carouselCards = useMemo(() => {
261
+ // On desktop before hover, only render the first image to prevent unnecessary loading
262
+ // On mobile or after hover, render all images
263
+ const cardsToRender = !isMobile && !hasHoveredGallery ? cards.slice(0, 1) : cards;
264
+
265
+ return cardsToRender.map(({ card, imageData, key }, index) => {
266
+ // For the sliced scenario, we need to get the actual index from the original cards array
267
+ const actualIndex = !isMobile && !hasHoveredGallery ? 0 : index;
268
+ const isActive = actualIndex + 1 === currentPage;
269
+
270
+ return (
271
+ <div
272
+ aria-current={isActive ? 'true' : 'false'}
273
+ aria-label={`Image ${actualIndex + 1} of ${cards.length}${imageData?.alt ? `: ${imageData.alt}` : ''}`}
274
+ className={cn(
275
+ 'flex w-full flex-none snap-center items-center justify-center bg-background-primary',
276
+ onImageClick ? 'cursor-zoom-in' : 'cursor-default',
277
+ // Desktop: full height
278
+ 'smMin:h-full',
279
+ // Mobile-specific styling (xsMax) — max dimensions follow responsiveImageConfig.desktopSize via --slider-size
280
+ 'xsMax:aspect-square xsMax:max-h-[var(--slider-size)] xsMax:max-w-[var(--slider-size)] xsMax:overflow-hidden xsMax:rounded-lg xsMax:border xsMax:border-border-secondary',
281
+ // Apply width reduction only when there are multiple cards for bleed effect
282
+ numberOfPages > 1
283
+ ? 'xsMax:w-[calc(100%-64px)] xsMax:max-w-[var(--slider-size)]'
284
+ : 'xsMax:w-full xsMax:max-w-[var(--slider-size)]',
285
+ {
286
+ 'ml-sm': actualIndex === 0,
287
+ 'mr-sm': actualIndex === cards.length - 1,
288
+ }
289
+ )}
290
+ key={key} // Use stable key to avoid unnecessary DOM recreations
291
+ onClick={(event) => {
292
+ // Trigger mobile interaction for high-quality loading
293
+ handleMobileInteraction();
294
+ // Trigger analytics for lightbox open
295
+ if (onAnalyticsEventTriggered) {
296
+ onAnalyticsEventTriggered({
297
+ imagePosition: actualIndex + 1,
298
+ interactionType: 'Open Lightbox',
299
+ totalImages: numberOfPages,
300
+ });
301
+ }
302
+ // Call optional user-provided handler
303
+ onImageClick?.(actualIndex, event);
304
+ }}
305
+ onFocus={(event) => {
306
+ // Trigger mobile interaction for high-quality loading
307
+ handleMobileInteraction();
308
+ // Call optional user-provided handler
309
+ onImageMouseOver?.(actualIndex, event);
310
+ }}
311
+ onKeyUp={
312
+ onImageClick
313
+ ? (event) => {
314
+ if (event.key === 'Enter' || event.key === ' ') {
315
+ event.preventDefault();
316
+ // Trigger analytics for lightbox open via keyboard
317
+ if (onAnalyticsEventTriggered) {
318
+ onAnalyticsEventTriggered({
319
+ imagePosition: actualIndex + 1,
320
+ interactionType: 'Open Lightbox',
321
+ totalImages: numberOfPages,
322
+ });
323
+ }
324
+ if (event.key === 'Enter') {
325
+ onImageClick(actualIndex, event);
326
+ }
327
+ }
328
+ }
329
+ : undefined
330
+ }
331
+ onMouseOver={(event) => {
332
+ // Always trigger gallery hover state for high-quality loading
333
+ handleMouseOver();
334
+ // Call optional user-provided handler
335
+ if (onImageMouseOver) {
336
+ onImageMouseOver(actualIndex, event);
337
+ }
338
+ }}
339
+ onTouchStart={() => {
340
+ // Trigger mobile interaction for high-quality loading on touch/drag
341
+ handleMobileInteraction();
342
+ }}
343
+ role={onImageClick ? 'button' : undefined}
344
+ tabIndex={onImageClick ? 0 : undefined}
345
+ >
346
+ {/* Render responsive image if imageData is provided, otherwise use custom card */}
347
+ {imageData ? (
348
+ <ResponsiveImage
349
+ hasHoveredGallery={hasHoveredGallery}
350
+ imageData={imageData}
351
+ isActiveImage={isActive}
352
+ isMainImage
353
+ responsiveImageConfig={responsiveImageConfig}
354
+ />
355
+ ) : (
356
+ card || null
357
+ )}
358
+ </div>
359
+ );
360
+ });
361
+ }, [
362
+ cards,
363
+ currentPage,
364
+ handleMobileInteraction,
365
+ handleMouseOver,
366
+ hasHoveredGallery,
367
+ isMobile,
368
+ numberOfPages,
369
+ onAnalyticsEventTriggered,
370
+ onImageClick,
371
+ onImageMouseOver,
372
+ responsiveImageConfig,
373
+ ]);
374
+
375
+ const isIndexDisplay = thumbnailDisplay === ThumbnailDisplay.Index;
376
+ const isHorizontalThumbnailsDisplay =
377
+ thumbnailDisplay === ThumbnailDisplay.Thumbnails && thumbnailOrientation === 'horizontal';
378
+
379
+ return (
380
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/mouse-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/tabindex-no-positive
381
+ <section
382
+ aria-label="Image gallery"
383
+ aria-roledescription="carousel"
384
+ className={cn(
385
+ 'relative mx-auto w-full pr-lg outline-none smMax:pr-0',
386
+ // Only extend beyond viewport for bleed effect when there are multiple cards
387
+ { 'xsMax:-ml-sm xsMax:w-[calc(100%+32px)]': numberOfPages > 1 },
388
+ className
389
+ )}
390
+ onClick={() => containerRef.current?.focus()}
391
+ onKeyUp={onKeyNavigation}
392
+ onMouseOver={handleMouseOver}
393
+ ref={containerRef}
394
+ role="application"
395
+ style={
396
+ {
397
+ '--slider-size': `${responsiveImageConfig.desktopSize}px`,
398
+ } as CSSProperties
399
+ }
400
+ // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
401
+ tabIndex={0}
402
+ >
403
+ <div
404
+ className={cn(
405
+ 'flex flex-col',
406
+ // Dynamic gap that scales smoothly from ~58px down to smaller sizes
407
+ 'gap-[58px] mdMax:gap-xl smMax:gap-[38px] xsMax:gap-[28px]'
408
+ )}
409
+ >
410
+ {/* Image Gallery Container */}
411
+ <div
412
+ className={cn(
413
+ 'flex w-full',
414
+ thumbnailDisplay === ThumbnailDisplay.Index
415
+ ? 'flex-col items-center justify-center gap-2xs'
416
+ : thumbnailOrientation === 'horizontal'
417
+ ? 'flex-col items-center justify-center gap-xs'
418
+ : 'relative items-center justify-center gap-[28px]'
419
+ )}
420
+ >
421
+ {/* Index indicator - above main image when thumbnailDisplay is 'index' and indexPosition is 'top' */}
422
+ {thumbnailDisplay === ThumbnailDisplay.Index && indexPosition === 'top' && (
423
+ <IndexIndicator
424
+ currentPage={currentPage}
425
+ numberOfPages={numberOfPages}
426
+ />
427
+ )}
428
+
429
+ {/* Vertical Thumbnails Container - Absolutely positioned */}
430
+ {showThumbnails &&
431
+ thumbnailDisplay === ThumbnailDisplay.Thumbnails &&
432
+ thumbnailOrientation === 'vertical' && (
433
+ <div className="absolute bottom-0 left-0 top-0 z-10 xsMax:hidden">
434
+ <Thumbnails
435
+ cards={cards}
436
+ currentPage={currentPage}
437
+ generateThumbnailSizesAttribute={generateThumbnailSizesAttribute}
438
+ generateThumbnailSrcSet={generateThumbnailSrcSet}
439
+ onThumbnailClick={handleThumbnailClickWithAnalytics}
440
+ orientation="vertical"
441
+ />
442
+ </div>
443
+ )}
444
+
445
+ {/* Main Image Area */}
446
+ <div
447
+ className={cn(
448
+ 'flex items-center',
449
+ isIndexDisplay
450
+ ? 'relative w-full justify-center gap-md smMin:max-w-[780px] xsMax:w-full'
451
+ : isHorizontalThumbnailsDisplay
452
+ ? 'max-w-[606px] gap-md xsMax:w-full'
453
+ : cn(
454
+ 'w-full justify-between gap-sm',
455
+ showThumbnails ? 'pl-[146px] mdMax:pl-[139px] xsMax:pl-0' : ''
456
+ )
457
+ )}
458
+ data-testid="image-slider-hero-controls"
459
+ >
460
+ {/* Desktop navigation buttons (left) - hidden on mobile */}
461
+ <div className="hidden smMin:block">
462
+ <NavigationButtons
463
+ goToNextPage={goToNextPageWithAnalytics}
464
+ goToPreviousPage={goToPreviousPageWithAnalytics}
465
+ iconShape={iconShape}
466
+ iconSize={iconSize}
467
+ iconType={iconType}
468
+ iconVariant={iconVariant}
469
+ isNextPageDisabled={isNextPageDisabled}
470
+ isPreviousPageDisabled={isPreviousPageDisabled}
471
+ position="left"
472
+ showNextPageButton={showNextPageButton}
473
+ showPreviousPageButton={showPreviousPageButton}
474
+ />
475
+ </div>
476
+
477
+ {/* Main image container - responsive layout */}
478
+ <div
479
+ className={cn(
480
+ // Shared: relative container with consistent max dimensions
481
+ 'relative',
482
+ isIndexDisplay
483
+ ? 'max-h-[var(--slider-size)] smMin:flex smMin:aspect-square smMin:max-w-[var(--slider-size)] smMin:flex-1 smMin:justify-center smMin:overflow-hidden xsMax:w-full'
484
+ : isHorizontalThumbnailsDisplay
485
+ ? 'max-h-[400px] smMin:flex smMin:aspect-square smMin:max-w-[400px] smMin:flex-1 smMin:justify-center smMin:overflow-hidden xsMax:w-full'
486
+ : 'max-h-[var(--slider-size)] smMin:flex smMin:aspect-square smMin:max-w-[var(--slider-size)] smMin:flex-1 smMin:justify-center smMin:overflow-hidden xsMax:w-full'
487
+ )}
488
+ data-testid="image-slider-media-frame"
489
+ >
490
+ {/* Mobile navigation buttons - hidden on desktop */}
491
+ <div className="smMin:hidden">
492
+ <NavigationButtons
493
+ goToNextPage={goToNextPageWithAnalytics}
494
+ goToPreviousPage={goToPreviousPageWithAnalytics}
495
+ iconShape={iconShape}
496
+ iconSize={iconSize}
497
+ iconType={iconType}
498
+ iconVariant={iconVariant}
499
+ isNextPageDisabled={isNextPageDisabled}
500
+ isPreviousPageDisabled={isPreviousPageDisabled}
501
+ showNextPageButton={showNextPageButton}
502
+ showPreviousPageButton={showPreviousPageButton}
503
+ />
504
+ </div>
505
+
506
+ {/* Responsive scroll container wrapper */}
507
+ <div
508
+ className={cn(
509
+ // Shared: primary background and full width
510
+ 'w-full bg-background-primary',
511
+ // Desktop: full height and hidden overflow
512
+ 'smMin:h-full smMin:overflow-hidden'
513
+ )}
514
+ >
515
+ <div
516
+ aria-atomic="false"
517
+ aria-live="polite"
518
+ className={cn(
519
+ 'flex w-full snap-x snap-mandatory overflow-y-hidden overflow-x-scroll',
520
+ // Desktop: full height and 24px gap
521
+ 'smMin:h-full smMin:gap-md',
522
+ // Mobile: 2xs gap, let aspect-square control height
523
+ 'xsMax:gap-2xs'
524
+ )}
525
+ onScroll={onScrollCards}
526
+ ref={contentRef}
527
+ role="region"
528
+ style={{
529
+ scrollbarWidth: 'none',
530
+ }}
531
+ >
532
+ {carouselCards}
533
+ </div>
534
+ </div>
535
+ </div>
536
+
537
+ {/* Desktop navigation buttons (right) - hidden on mobile */}
538
+ <div className="hidden smMin:block">
539
+ <NavigationButtons
540
+ goToNextPage={goToNextPageWithAnalytics}
541
+ goToPreviousPage={goToPreviousPageWithAnalytics}
542
+ iconShape={iconShape}
543
+ iconSize={iconSize}
544
+ iconType={iconType}
545
+ iconVariant={iconVariant}
546
+ isNextPageDisabled={isNextPageDisabled}
547
+ isPreviousPageDisabled={isPreviousPageDisabled}
548
+ position="right"
549
+ showNextPageButton={showNextPageButton}
550
+ showPreviousPageButton={showPreviousPageButton}
551
+ />
552
+ </div>
553
+ </div>
554
+
555
+ {/* Horizontal Thumbnails Container - Below image */}
556
+ {showThumbnails &&
557
+ thumbnailDisplay === ThumbnailDisplay.Thumbnails &&
558
+ thumbnailOrientation === 'horizontal' && (
559
+ <div className="w-full xsMax:hidden">
560
+ <Thumbnails
561
+ cards={cards}
562
+ currentPage={currentPage}
563
+ generateThumbnailSizesAttribute={generateThumbnailSizesAttribute}
564
+ generateThumbnailSrcSet={generateThumbnailSrcSet}
565
+ onThumbnailClick={handleThumbnailClickWithAnalytics}
566
+ orientation="horizontal"
567
+ />
568
+ </div>
569
+ )}
570
+
571
+ {/* Index indicator - below main image when thumbnailDisplay is 'index' and indexPosition is 'bottom' */}
572
+ {thumbnailDisplay === ThumbnailDisplay.Index && indexPosition === 'bottom' && (
573
+ <IndexIndicator
574
+ currentPage={currentPage}
575
+ numberOfPages={numberOfPages}
576
+ />
577
+ )}
578
+ </div>
579
+ </div>
580
+ </section>
581
+ );
582
+ };
@@ -0,0 +1,90 @@
1
+ import { ReactNode } from 'react';
2
+
3
+ /**
4
+ * Display mode for thumbnail navigation
5
+ */
6
+ export enum ThumbnailDisplay {
7
+ Index = 'index',
8
+ Thumbnails = 'thumbnails',
9
+ }
10
+
11
+ /**
12
+ * Analytics event data for ImageSlider interactions
13
+ */
14
+ export type ImageSliderAnalyticsEvent = {
15
+ /** Current image position (1-based index) */
16
+ imagePosition: number;
17
+ /** Type of interaction that triggered the event */
18
+ interactionType: 'Thumbnail Click' | 'Next' | 'Prev' | 'Open Lightbox';
19
+ /** Total number of images in the slider */
20
+ totalImages: number;
21
+ };
22
+
23
+ /**
24
+ * Responsive image data for optimized loading
25
+ */
26
+ export type ResponsiveImageData = {
27
+ /**
28
+ * Alt text for the image
29
+ */
30
+ alt: string;
31
+ /**
32
+ * Base URL for the image (without width parameters)
33
+ */
34
+ baseUrl: string;
35
+ /**
36
+ * Optional title for the image
37
+ */
38
+ title?: string;
39
+ };
40
+
41
+ /**
42
+ * Configuration for responsive image sizes and breakpoints
43
+ */
44
+ export type ResponsiveImageConfig = {
45
+ /**
46
+ * Breakpoint width in pixels where mobile switches to desktop
47
+ * @default 768
48
+ */
49
+ breakpoint: number;
50
+ /**
51
+ * Desktop image width in pixels
52
+ * @default 651
53
+ */
54
+ desktopSize: number;
55
+ /**
56
+ * Mobile image width in pixels
57
+ * @default 366
58
+ */
59
+ mobileSize: number;
60
+ };
61
+
62
+ /**
63
+ * Card for the ImageSlider - supports both custom ReactNode and responsive images
64
+ */
65
+ export type ImageSliderCard = {
66
+ /**
67
+ * The rendered content of the card or image.
68
+ * Optional when using imageData.
69
+ */
70
+ card?: ReactNode;
71
+ /**
72
+ * Responsive image data for automatic srcset/sizes optimization.
73
+ * When provided, `card` will be ignored and an optimized <img> will be rendered.
74
+ * Optional when using custom card content.
75
+ */
76
+ imageData?: ResponsiveImageData;
77
+ /**
78
+ * The unique identifier for the card
79
+ */
80
+ key: string;
81
+ };
82
+
83
+ export type ImageSliderPageInfo = {
84
+ breakpoints: number[];
85
+ cardsPerPage: number;
86
+ numberOfPages: number;
87
+ };
88
+
89
+ // this is the px size of the MD gap (kept for potential future use)
90
+ export const CAROUSEL_CARD_GAP_NUM = 24;