@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,237 @@
1
+ import { forwardRef, useCallback, useEffect, useRef, useState } from 'react';
2
+ import { createPortal } from 'react-dom';
3
+
4
+ import type { Props, RefHandles, SpringEvent } from './types';
5
+
6
+ /* eslint-disable react/jsx-pascal-case */
7
+ import { BottomSheet as _BottomSheet } from './BottomSheet';
8
+ import { useLayoutEffect } from './hooks';
9
+
10
+ export type { RefHandles as BottomSheetRef, Props as BottomSheetProps } from './types';
11
+
12
+ /**
13
+ * BottomSheet component with SSR support and proper animation lifecycle management
14
+ */
15
+ export const BottomSheet = forwardRef<RefHandles, Props>(function BottomSheet(
16
+ { onCloseEnd, onDismiss, onSpringEnd, onSpringStart, ...props },
17
+ ref
18
+ ) {
19
+ // === Component State ===
20
+ // Mounted state helps with SSR and ensures accessibility (no tabbing/screen reader access when closed)
21
+ const [mounted, setMounted] = useState(false);
22
+ const [modalTarget, setModalTarget] = useState<HTMLElement | null>(null);
23
+
24
+ // === Animation State ===
25
+ // Internal state to manage animation lifecycle separate from the open prop
26
+ const [isAnimating, setIsAnimating] = useState(false);
27
+ // Track if we're in the middle of an opening animation
28
+ const [isOpening, setIsOpening] = useState(false);
29
+ // Internal state to handle initial delay for proper transitions
30
+ const [shouldShow, setShouldShow] = useState(false);
31
+
32
+ // === Refs for State Management ===
33
+ const timerRef = useRef<ReturnType<typeof requestAnimationFrame>>(0);
34
+ // The last snap point for remembering user-defined height
35
+ const lastSnapRef = useRef(0);
36
+ // Track if we should call onDismiss after close animation completes
37
+ const shouldCallOnDismiss = useRef(false);
38
+ // Track last action time to prevent rapid successive calls
39
+ const lastActionTime = useRef(0);
40
+ // Track if we're in a force-closed state to ignore all spring events
41
+ const isForceClosedRef = useRef(false);
42
+
43
+ // Initial state determines animation behavior on mount
44
+ const initialStateRef = useRef<'OPEN' | 'CLOSED'>('CLOSED');
45
+
46
+ // Find the modal target element
47
+ useEffect(() => {
48
+ const target = document.querySelector('.hui-modal-target');
49
+
50
+ if (!target) {
51
+ throw new Error('Modal target not found, add one in the DOM tree.');
52
+ }
53
+
54
+ setModalTarget(target as HTMLElement);
55
+ }, []);
56
+
57
+ // === Helper Functions ===
58
+ // Start the close transition (similar to Drawer pattern)
59
+ const startCloseTransition = useCallback((callOnDismiss: boolean = false) => {
60
+ setIsAnimating(true);
61
+ shouldCallOnDismiss.current = callOnDismiss;
62
+ }, []);
63
+
64
+ // Handle internal onDismiss that calls the original onDismiss immediately
65
+ // Memoized to prevent unnecessary re-renders
66
+ const handleInternalDismiss = useCallback(() => {
67
+ const now = Date.now();
68
+ const DEBOUNCE_MS = 150; // Increased debounce time for stress testing
69
+
70
+ // Prevent dismiss during opening animations or rapid successive calls
71
+ // Allow dismiss during closing animations (drag-to-close scenario)
72
+ if (isOpening || isAnimating || now - lastActionTime.current < DEBOUNCE_MS) {
73
+ return;
74
+ }
75
+
76
+ lastActionTime.current = now;
77
+ isForceClosedRef.current = true;
78
+
79
+ onDismiss?.();
80
+ }, [onDismiss, isOpening, isAnimating]);
81
+
82
+ // === Effects ===
83
+ // Close the sheet when the open prop changes to false
84
+ useEffect(() => {
85
+ if (mounted && !props.open && !isAnimating) {
86
+ startCloseTransition(false);
87
+ }
88
+ }, [mounted, props.open, isAnimating, startCloseTransition]);
89
+
90
+ // Handle mounting and opening state - supports cases where sheet appears already open
91
+ useLayoutEffect(() => {
92
+ if (props.open) {
93
+ // Prevent rapid re-mounting during stress testing
94
+ const now = Date.now();
95
+ if (now - lastActionTime.current < 50) {
96
+ return undefined; // Skip if too rapid
97
+ }
98
+
99
+ cancelAnimationFrame(timerRef.current);
100
+ setMounted(true);
101
+ // Reset all state when opening
102
+ setIsAnimating(false);
103
+ setIsOpening(true);
104
+ shouldCallOnDismiss.current = false;
105
+ lastActionTime.current = now;
106
+ isForceClosedRef.current = false;
107
+
108
+ // Add initial delay for proper transition
109
+ // Use requestAnimationFrame to ensure DOM is ready for transition
110
+ const delayId = requestAnimationFrame(() => {
111
+ // Double-check we're still supposed to be open
112
+ if (props.open) {
113
+ setShouldShow(true);
114
+ }
115
+ });
116
+
117
+ // Cleanup function will clear the delay
118
+ return () => {
119
+ cancelAnimationFrame(delayId);
120
+ initialStateRef.current = 'CLOSED';
121
+ setShouldShow(false);
122
+ };
123
+ }
124
+
125
+ // Reset shouldShow when not open
126
+ setShouldShow(false);
127
+ return undefined;
128
+ }, [props.open]);
129
+
130
+ const handleSpringStart = useCallback(
131
+ async function handleSpringStart(event: SpringEvent) {
132
+ // Only process events for open component or CLOSE events
133
+ if (!props.open && event.type !== 'CLOSE') {
134
+ return;
135
+ }
136
+
137
+ await onSpringStart?.(event);
138
+
139
+ if (event.type === 'OPEN') {
140
+ // Cancel any pending unmount when opening
141
+ cancelAnimationFrame(timerRef.current);
142
+ }
143
+ },
144
+ [onSpringStart, props.open]
145
+ );
146
+
147
+ const handleSpringEnd = useCallback(
148
+ async function handleSpringEnd(event: SpringEvent) {
149
+ // Only process CLOSE events when force-closed, or any event when open
150
+ const shouldIgnore = (isForceClosedRef.current || !props.open) && event.type !== 'CLOSE';
151
+ if (shouldIgnore) {
152
+ return;
153
+ }
154
+
155
+ await onSpringEnd?.(event);
156
+
157
+ if (event.type === 'OPEN') {
158
+ setIsOpening(false);
159
+ } else if (event.type === 'CLOSE') {
160
+ // Reset all animation state and unmount
161
+ setIsAnimating(false);
162
+ setIsOpening(false);
163
+ shouldCallOnDismiss.current = false;
164
+ timerRef.current = requestAnimationFrame(() => setMounted(false));
165
+ }
166
+ },
167
+ [onSpringEnd, props.open]
168
+ );
169
+
170
+ // Fallback unmounting - ensures component unmounts even if spring callback fails
171
+ useEffect(() => {
172
+ if (!props.open && mounted) {
173
+ const fallbackTimeoutId = setTimeout(() => {
174
+ // Only unmount if we're still in the closed state after timeout
175
+ if (!props.open) {
176
+ cancelAnimationFrame(timerRef.current);
177
+ setMounted(false);
178
+ setIsAnimating(false);
179
+ shouldCallOnDismiss.current = false;
180
+ isForceClosedRef.current = true;
181
+ }
182
+ }, 500);
183
+
184
+ return () => clearTimeout(fallbackTimeoutId);
185
+ }
186
+ return undefined;
187
+ }, [props.open, mounted]);
188
+
189
+ // Cleanup effect - let React handle DOM cleanup naturally
190
+ useEffect(() => {
191
+ return () => {
192
+ // Minimal cleanup - only clear empty modal targets to prevent memory leaks
193
+ // Let React handle the component unmounting naturally
194
+ setTimeout(() => {
195
+ try {
196
+ const modalTarget = document.querySelector('.hui-modal-target');
197
+ // Only clean if modal target is completely empty and we're sure React is done
198
+ if (modalTarget && modalTarget.children.length === 0) {
199
+ modalTarget.innerHTML = '';
200
+ }
201
+ } catch {
202
+ // Ignore cleanup errors during rapid state changes
203
+ }
204
+ }, 200); // Longer delay to avoid race conditions with React
205
+ };
206
+ }, []); // Only run on component unmount
207
+
208
+ // === Early Return for SSR and Unmounted State ===
209
+ if (!mounted || !modalTarget) {
210
+ return null;
211
+ }
212
+
213
+ // === Render ===
214
+ // Extract onDismiss from props to avoid conflicts with internal handler
215
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
216
+ const { onDismiss: _, ...bottomSheetProps } = props as Props & { onDismiss?: () => void };
217
+
218
+ return createPortal(
219
+ <div
220
+ aria-hidden={!props.open}
221
+ role="presentation"
222
+ >
223
+ <_BottomSheet
224
+ {...bottomSheetProps}
225
+ initialState={initialStateRef.current}
226
+ lastSnapRef={lastSnapRef}
227
+ onCloseEnd={onCloseEnd}
228
+ onDismiss={handleInternalDismiss}
229
+ onSpringEnd={handleSpringEnd}
230
+ onSpringStart={handleSpringStart}
231
+ open={shouldShow}
232
+ ref={ref}
233
+ />
234
+ </div>,
235
+ modalTarget
236
+ );
237
+ });
@@ -0,0 +1,147 @@
1
+ import { atom } from 'jotai';
2
+
3
+ /**
4
+ * Bottom sheet state types
5
+ */
6
+ export type BottomSheetState = 'closed' | 'opening' | 'open' | 'closing' | 'dragging' | 'snapping' | 'resizing';
7
+
8
+ export type BottomSheetEvent =
9
+ | { type: 'OPEN' }
10
+ | { type: 'CLOSE' }
11
+ | { type: 'DRAG' }
12
+ | { type: 'RESIZE' }
13
+ | {
14
+ payload: {
15
+ source: 'dragging' | 'custom' | string;
16
+ velocity: number;
17
+ y: number;
18
+ };
19
+ type: 'SNAP';
20
+ };
21
+
22
+ /** The payload shape carried by SNAP events. */
23
+ export type SnapPayload = Extract<BottomSheetEvent, { type: 'SNAP' }>['payload'];
24
+
25
+ export type BottomSheetContext = {
26
+ initialState: 'OPEN' | 'CLOSED';
27
+ snapSource?: 'dragging' | 'custom' | string;
28
+ velocity?: number;
29
+ y?: number;
30
+ };
31
+
32
+ /**
33
+ * Core state atoms
34
+ */
35
+ export const bottomSheetStateAtom = atom<BottomSheetState>('closed');
36
+ export const bottomSheetContextAtom = atom<BottomSheetContext>({ initialState: 'CLOSED' });
37
+
38
+ /**
39
+ * Derived state atoms
40
+ */
41
+ export const isOpenAtom = atom((get) => {
42
+ const state = get(bottomSheetStateAtom);
43
+ return (
44
+ state === 'open' || state === 'opening' || state === 'dragging' || state === 'snapping' || state === 'resizing'
45
+ );
46
+ });
47
+
48
+ export const isClosedAtom = atom((get) => {
49
+ const state = get(bottomSheetStateAtom);
50
+ return state === 'closed';
51
+ });
52
+
53
+ export const isTransitioningAtom = atom((get) => {
54
+ const state = get(bottomSheetStateAtom);
55
+ return state === 'opening' || state === 'closing' || state === 'snapping' || state === 'resizing';
56
+ });
57
+
58
+ export const isDraggingAtom = atom((get) => {
59
+ const state = get(bottomSheetStateAtom);
60
+ return state === 'dragging';
61
+ });
62
+
63
+ /**
64
+ * Action atoms for state transitions
65
+ */
66
+ export const sendEventAtom = atom(null, (get, set, event: BottomSheetEvent) => {
67
+ const currentState = get(bottomSheetStateAtom);
68
+ const context = get(bottomSheetContextAtom);
69
+
70
+ // Add guards to prevent rapid state changes
71
+ switch (event.type) {
72
+ case 'OPEN':
73
+ if (currentState === 'closed' || currentState === 'closing') {
74
+ set(bottomSheetStateAtom, 'opening');
75
+ }
76
+ break;
77
+
78
+ case 'CLOSE':
79
+ if (currentState !== 'closed' && currentState !== 'closing') {
80
+ set(bottomSheetStateAtom, 'closing');
81
+ }
82
+ break;
83
+
84
+ case 'DRAG':
85
+ // Only allow drag if not already in a transitional state
86
+ if (
87
+ currentState === 'open' ||
88
+ (currentState === 'opening' && context.initialState === 'OPEN') ||
89
+ currentState === 'snapping' ||
90
+ currentState === 'resizing'
91
+ ) {
92
+ set(bottomSheetStateAtom, 'dragging');
93
+ }
94
+ break;
95
+
96
+ case 'SNAP':
97
+ // Only allow snap from dragging or stable open state
98
+ if (currentState === 'dragging' || currentState === 'open') {
99
+ // Batch the context and state updates to prevent multiple renders
100
+ const newContext = {
101
+ ...context,
102
+ snapSource: event.payload.source,
103
+ velocity: event.payload.velocity,
104
+ y: event.payload.y,
105
+ };
106
+
107
+ set(bottomSheetContextAtom, newContext);
108
+ set(bottomSheetStateAtom, 'snapping');
109
+ }
110
+ break;
111
+
112
+ case 'RESIZE':
113
+ // Only allow resize from stable states
114
+ if (currentState === 'open') {
115
+ set(bottomSheetStateAtom, 'resizing');
116
+ }
117
+ break;
118
+
119
+ default:
120
+ break;
121
+ }
122
+ });
123
+
124
+ /**
125
+ * Transition completion atoms
126
+ */
127
+ export const completeTransitionAtom = atom(null, (get, set, targetState: BottomSheetState) => {
128
+ const currentState = get(bottomSheetStateAtom);
129
+
130
+ // Only complete transitions if we're currently in a transitioning state
131
+ if (get(isTransitioningAtom) || currentState === 'dragging') {
132
+ set(bottomSheetStateAtom, targetState);
133
+ }
134
+ });
135
+
136
+ /**
137
+ * Reset atom for cleanup
138
+ */
139
+ export const resetStateAtom = atom(null, (get, set, initialState: 'OPEN' | 'CLOSED' = 'CLOSED') => {
140
+ set(bottomSheetStateAtom, initialState === 'OPEN' ? 'open' : 'closed');
141
+ set(bottomSheetContextAtom, {
142
+ initialState,
143
+ snapSource: undefined,
144
+ velocity: undefined,
145
+ y: undefined,
146
+ });
147
+ });
@@ -0,0 +1,246 @@
1
+ import { useAtom, useAtomValue, useSetAtom } from 'jotai';
2
+ import { useCallback, useEffect, useRef } from 'react';
3
+
4
+ import {
5
+ type BottomSheetContext,
6
+ bottomSheetContextAtom,
7
+ type BottomSheetEvent,
8
+ type BottomSheetState,
9
+ bottomSheetStateAtom,
10
+ completeTransitionAtom,
11
+ isClosedAtom,
12
+ isDraggingAtom,
13
+ isOpenAtom,
14
+ isTransitioningAtom,
15
+ resetStateAtom,
16
+ sendEventAtom,
17
+ type SnapPayload,
18
+ } from './atoms';
19
+
20
+ /**
21
+ * Services interface matching the XState pattern
22
+ */
23
+ export interface BottomSheetServices {
24
+ activate: () => Promise<void>;
25
+ closeSmoothly: () => Promise<void>;
26
+ deactivate: () => Promise<void>;
27
+ onCloseEnd: () => Promise<void>;
28
+ onCloseStart: () => Promise<void>;
29
+ onOpenEnd: () => Promise<void>;
30
+ onOpenStart: () => Promise<void>;
31
+ onResizeEnd: () => Promise<void>;
32
+ onResizeStart: () => Promise<void>;
33
+ onSnapEnd: (context: BottomSheetContext) => Promise<void>;
34
+ onSnapStart: (context: BottomSheetContext) => Promise<void>;
35
+ openImmediately: () => Promise<void>;
36
+ openSmoothly: () => Promise<void>;
37
+ renderVisuallyHidden: () => Promise<void>;
38
+ resizeSmoothly: () => Promise<void>;
39
+ snapSmoothly: (context: BottomSheetContext) => Promise<void>;
40
+ }
41
+
42
+ /**
43
+ * Actions interface matching the XState pattern
44
+ */
45
+ export interface BottomSheetActions {
46
+ onCloseCancel: () => void;
47
+ onCloseEnd: () => void;
48
+ onOpenCancel: () => void;
49
+ onOpenEnd: () => void;
50
+ onResizeCancel: () => void;
51
+ onResizeEnd: () => void;
52
+ onSnapCancel: (context: BottomSheetContext) => void;
53
+ onSnapEnd: (context: BottomSheetContext) => void;
54
+ }
55
+
56
+ /**
57
+ * Hook that provides bottom sheet state machine functionality using Jotai
58
+ */
59
+ export const useBottomSheetStateMachine = (
60
+ services: BottomSheetServices,
61
+ actions: BottomSheetActions,
62
+ initialContext: BottomSheetContext
63
+ ) => {
64
+ const [state] = useAtom(bottomSheetStateAtom);
65
+ const [context, setContext] = useAtom(bottomSheetContextAtom);
66
+ const sendEvent = useSetAtom(sendEventAtom);
67
+ const completeTransition = useSetAtom(completeTransitionAtom);
68
+ const resetState = useSetAtom(resetStateAtom);
69
+
70
+ const isOpen = useAtomValue(isOpenAtom);
71
+ const isClosed = useAtomValue(isClosedAtom);
72
+ const isTransitioning = useAtomValue(isTransitioningAtom);
73
+ const isDragging = useAtomValue(isDraggingAtom);
74
+
75
+ // Track previous state for transition logic
76
+ const prevStateRef = useRef<BottomSheetState>(state);
77
+ const servicesRef = useRef(services);
78
+ const actionsRef = useRef(actions);
79
+
80
+ // Update refs when services/actions change
81
+ useEffect(() => {
82
+ servicesRef.current = services;
83
+ actionsRef.current = actions;
84
+ }, [services, actions]);
85
+
86
+ // Initialize context only once on mount
87
+ useEffect(() => {
88
+ setContext(initialContext);
89
+ // eslint-disable-next-line react-hooks/exhaustive-deps
90
+ }, [setContext]); // Only depend on setContext, not initialContext to avoid infinite loops
91
+
92
+ // Handle state transitions and side effects
93
+ useEffect(() => {
94
+ const currentServices = servicesRef.current;
95
+ const currentActions = actionsRef.current;
96
+ const prevState = prevStateRef.current;
97
+ const currentContext = context; // Capture context at the time of effect
98
+
99
+ const handleStateTransition = async () => {
100
+ try {
101
+ switch (state) {
102
+ case 'opening':
103
+ if (prevState === 'closed') {
104
+ await currentServices.onOpenStart();
105
+
106
+ if (currentContext.initialState === 'OPEN') {
107
+ await currentServices.renderVisuallyHidden();
108
+ await currentServices.activate();
109
+ await currentServices.openImmediately();
110
+ } else {
111
+ await currentServices.renderVisuallyHidden();
112
+ await currentServices.activate();
113
+ await currentServices.openSmoothly();
114
+ }
115
+
116
+ await currentServices.onOpenEnd();
117
+ completeTransition('open');
118
+ } else if (prevState === 'closing') {
119
+ // Cancelled close, resume opening
120
+ currentActions.onCloseCancel();
121
+ await currentServices.onOpenStart();
122
+ await currentServices.renderVisuallyHidden();
123
+ await currentServices.activate();
124
+ await currentServices.openSmoothly();
125
+ await currentServices.onOpenEnd();
126
+ completeTransition('open');
127
+ }
128
+ break;
129
+
130
+ case 'closing':
131
+ if (prevState !== 'closed') {
132
+ if (prevState === 'opening') {
133
+ currentActions.onOpenCancel();
134
+ } else if (prevState === 'resizing') {
135
+ currentActions.onResizeCancel();
136
+ } else if (prevState === 'snapping') {
137
+ currentActions.onSnapCancel(currentContext);
138
+ }
139
+
140
+ await currentServices.onCloseStart();
141
+ await currentServices.deactivate();
142
+ await currentServices.closeSmoothly();
143
+ await currentServices.onCloseEnd();
144
+ currentActions.onCloseEnd();
145
+ completeTransition('closed');
146
+ }
147
+ break;
148
+
149
+ case 'resizing':
150
+ if (prevState === 'open' || prevState === 'opening') {
151
+ await currentServices.onResizeStart();
152
+ await currentServices.resizeSmoothly();
153
+ await currentServices.onResizeEnd();
154
+ completeTransition('open');
155
+ }
156
+ break;
157
+
158
+ case 'snapping':
159
+ // 'dragging' → snap on release; 'open' → the imperative snapTo API.
160
+ // (Upstream only serviced the dragging path, so snapTo from a resting
161
+ // sheet entered 'snapping' and stalled without ever animating.)
162
+ if (prevState === 'dragging' || prevState === 'open') {
163
+ await currentServices.onSnapStart(currentContext);
164
+ await currentServices.snapSmoothly(currentContext);
165
+ await currentServices.onSnapEnd(currentContext);
166
+ completeTransition('open');
167
+ }
168
+ break;
169
+
170
+ case 'dragging':
171
+ // Dragging is handled by gesture handlers, no async operations needed
172
+ if (prevState === 'opening') {
173
+ currentActions.onOpenEnd();
174
+ } else if (prevState === 'closing') {
175
+ currentActions.onCloseCancel();
176
+ } else if (prevState === 'resizing') {
177
+ currentActions.onResizeCancel();
178
+ } else if (prevState === 'snapping') {
179
+ currentActions.onSnapCancel(currentContext);
180
+ }
181
+ break;
182
+ case 'closed':
183
+ case 'open':
184
+ default:
185
+ break;
186
+ }
187
+ } catch (error) {
188
+ // eslint-disable-next-line no-console
189
+ console.error('Bottom sheet state transition error:', error);
190
+ // On error, try to recover to a stable state
191
+ if (state === 'opening' || state === 'closing' || state === 'resizing' || state === 'snapping') {
192
+ completeTransition(state === 'closing' ? 'closed' : 'open');
193
+ }
194
+ }
195
+ };
196
+
197
+ if (prevState !== state) {
198
+ handleStateTransition();
199
+ prevStateRef.current = state;
200
+ }
201
+ // eslint-disable-next-line react-hooks/exhaustive-deps
202
+ }, [state, completeTransition]); // Removed context from dependencies
203
+
204
+ // Send event function with proper typing
205
+ const send = useCallback(
206
+ (type: BottomSheetEvent['type'], payload?: SnapPayload) => {
207
+ if (type === 'SNAP' && payload) {
208
+ sendEvent({ payload, type: 'SNAP' });
209
+ } else {
210
+ sendEvent({ type } as BottomSheetEvent);
211
+ }
212
+ },
213
+ [sendEvent]
214
+ );
215
+
216
+ // Reset function for cleanup
217
+ const reset = useCallback(
218
+ (initialState: 'OPEN' | 'CLOSED' = 'CLOSED') => {
219
+ resetState(initialState);
220
+ prevStateRef.current = initialState === 'OPEN' ? 'open' : 'closed';
221
+ },
222
+ [resetState]
223
+ );
224
+
225
+ return {
226
+ // Current state
227
+ current: {
228
+ context,
229
+ matches: (stateName: string) => state === stateName,
230
+ value: state,
231
+ },
232
+ isClosed,
233
+ isDragging,
234
+
235
+ // Derived state
236
+ isOpen,
237
+ isTransitioning,
238
+ reset,
239
+
240
+ // Actions
241
+ send,
242
+
243
+ // State value for easy access
244
+ state,
245
+ };
246
+ };