@allxsmith/bestax-bulma 5.27.0 → 5.27.2

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 (348) hide show
  1. package/dist/bestax.css +1 -1
  2. package/dist/bestax.css.map +1 -1
  3. package/dist/esm/columns/Column.js +48 -0
  4. package/dist/esm/columns/Column.js.map +1 -0
  5. package/dist/esm/columns/Columns.js +53 -0
  6. package/dist/esm/columns/Columns.js.map +1 -0
  7. package/dist/esm/components/Avatar.js +299 -0
  8. package/dist/esm/components/Avatar.js.map +1 -0
  9. package/dist/esm/components/Avatars.js +81 -0
  10. package/dist/esm/components/Avatars.js.map +1 -0
  11. package/dist/esm/components/Badge.js +105 -0
  12. package/dist/esm/components/Badge.js.map +1 -0
  13. package/dist/esm/components/Breadcrumb.js +36 -0
  14. package/dist/esm/components/Breadcrumb.js.map +1 -0
  15. package/dist/esm/components/Card.js +252 -0
  16. package/dist/esm/components/Card.js.map +1 -0
  17. package/dist/esm/components/Carousel.js +351 -0
  18. package/dist/esm/components/Carousel.js.map +1 -0
  19. package/dist/esm/components/Collapse.js +193 -0
  20. package/dist/esm/components/Collapse.js.map +1 -0
  21. package/dist/esm/components/Collapses.js +99 -0
  22. package/dist/esm/components/Collapses.js.map +1 -0
  23. package/dist/esm/components/Dialog.js +230 -0
  24. package/dist/esm/components/Dialog.js.map +1 -0
  25. package/dist/esm/components/Dropdown.js +362 -0
  26. package/dist/esm/components/Dropdown.js.map +1 -0
  27. package/dist/esm/components/Loading.js +87 -0
  28. package/dist/esm/components/Loading.js.map +1 -0
  29. package/dist/esm/components/Menu.js +117 -0
  30. package/dist/esm/components/Menu.js.map +1 -0
  31. package/dist/esm/components/Message.js +56 -0
  32. package/dist/esm/components/Message.js.map +1 -0
  33. package/dist/esm/components/Modal.js +354 -0
  34. package/dist/esm/components/Modal.js.map +1 -0
  35. package/dist/esm/components/Navbar.js +287 -0
  36. package/dist/esm/components/Navbar.js.map +1 -0
  37. package/dist/esm/components/Pagination.js +191 -0
  38. package/dist/esm/components/Pagination.js.map +1 -0
  39. package/dist/esm/components/Panel.js +100 -0
  40. package/dist/esm/components/Panel.js.map +1 -0
  41. package/dist/esm/components/Popover.js +298 -0
  42. package/dist/esm/components/Popover.js.map +1 -0
  43. package/dist/esm/components/Reveal.js +157 -0
  44. package/dist/esm/components/Reveal.js.map +1 -0
  45. package/dist/esm/components/Sidebar.js +209 -0
  46. package/dist/esm/components/Sidebar.js.map +1 -0
  47. package/dist/esm/components/Steps.js +128 -0
  48. package/dist/esm/components/Steps.js.map +1 -0
  49. package/dist/esm/components/Tabs.js +335 -0
  50. package/dist/esm/components/Tabs.js.map +1 -0
  51. package/dist/esm/components/Toast.js +322 -0
  52. package/dist/esm/components/Toast.js.map +1 -0
  53. package/dist/esm/components/Tooltip.js +202 -0
  54. package/dist/esm/components/Tooltip.js.map +1 -0
  55. package/dist/esm/components/collapsesContext.js +12 -0
  56. package/dist/esm/components/collapsesContext.js.map +1 -0
  57. package/dist/esm/elements/Block.js +29 -0
  58. package/dist/esm/elements/Block.js.map +1 -0
  59. package/dist/esm/elements/Box.js +32 -0
  60. package/dist/esm/elements/Box.js.map +1 -0
  61. package/dist/esm/elements/Button.js +139 -0
  62. package/dist/esm/elements/Button.js.map +1 -0
  63. package/dist/esm/elements/Buttons.js +42 -0
  64. package/dist/esm/elements/Buttons.js.map +1 -0
  65. package/dist/esm/elements/Code.js +25 -0
  66. package/dist/esm/elements/Code.js.map +1 -0
  67. package/dist/esm/elements/Content.js +33 -0
  68. package/dist/esm/elements/Content.js.map +1 -0
  69. package/dist/esm/elements/Delete.js +35 -0
  70. package/dist/esm/elements/Delete.js.map +1 -0
  71. package/dist/esm/elements/Divider.js +27 -0
  72. package/dist/esm/elements/Divider.js.map +1 -0
  73. package/dist/esm/elements/Emphasis.js +25 -0
  74. package/dist/esm/elements/Emphasis.js.map +1 -0
  75. package/dist/esm/elements/Figure.js +58 -0
  76. package/dist/esm/elements/Figure.js.map +1 -0
  77. package/dist/esm/elements/Icon.js +256 -0
  78. package/dist/esm/elements/Icon.js.map +1 -0
  79. package/dist/esm/elements/IconText.js +36 -0
  80. package/dist/esm/elements/IconText.js.map +1 -0
  81. package/dist/esm/elements/Image.js +46 -0
  82. package/dist/esm/elements/Image.js.map +1 -0
  83. package/dist/esm/elements/Link.js +36 -0
  84. package/dist/esm/elements/Link.js.map +1 -0
  85. package/dist/esm/elements/LinkButton.js +37 -0
  86. package/dist/esm/elements/LinkButton.js.map +1 -0
  87. package/dist/esm/elements/ListItem.js +28 -0
  88. package/dist/esm/elements/ListItem.js.map +1 -0
  89. package/dist/esm/elements/Loader.js +37 -0
  90. package/dist/esm/elements/Loader.js.map +1 -0
  91. package/dist/esm/elements/Notification.js +316 -0
  92. package/dist/esm/elements/Notification.js.map +1 -0
  93. package/dist/esm/elements/OrderedList.js +31 -0
  94. package/dist/esm/elements/OrderedList.js.map +1 -0
  95. package/dist/esm/elements/Paragraph.js +28 -0
  96. package/dist/esm/elements/Paragraph.js.map +1 -0
  97. package/dist/esm/elements/Pre.js +25 -0
  98. package/dist/esm/elements/Pre.js.map +1 -0
  99. package/dist/esm/elements/Progress.js +33 -0
  100. package/dist/esm/elements/Progress.js.map +1 -0
  101. package/dist/esm/elements/Skeleton.js +30 -0
  102. package/dist/esm/elements/Skeleton.js.map +1 -0
  103. package/dist/esm/elements/Span.js +28 -0
  104. package/dist/esm/elements/Span.js.map +1 -0
  105. package/dist/esm/elements/Strong.js +25 -0
  106. package/dist/esm/elements/Strong.js.map +1 -0
  107. package/dist/esm/elements/SubTitle.js +51 -0
  108. package/dist/esm/elements/SubTitle.js.map +1 -0
  109. package/dist/esm/elements/Table.js +51 -0
  110. package/dist/esm/elements/Table.js.map +1 -0
  111. package/dist/esm/elements/Tag.js +49 -0
  112. package/dist/esm/elements/Tag.js.map +1 -0
  113. package/dist/esm/elements/Tags.js +34 -0
  114. package/dist/esm/elements/Tags.js.map +1 -0
  115. package/dist/esm/elements/Tbody.js +26 -0
  116. package/dist/esm/elements/Tbody.js.map +1 -0
  117. package/dist/esm/elements/Td.js +61 -0
  118. package/dist/esm/elements/Td.js.map +1 -0
  119. package/dist/esm/elements/Tfoot.js +26 -0
  120. package/dist/esm/elements/Tfoot.js.map +1 -0
  121. package/dist/esm/elements/Th.js +34 -0
  122. package/dist/esm/elements/Th.js.map +1 -0
  123. package/dist/esm/elements/Thead.js +26 -0
  124. package/dist/esm/elements/Thead.js.map +1 -0
  125. package/dist/esm/elements/Title.js +44 -0
  126. package/dist/esm/elements/Title.js.map +1 -0
  127. package/dist/esm/elements/Tr.js +31 -0
  128. package/dist/esm/elements/Tr.js.map +1 -0
  129. package/dist/esm/elements/UnorderedList.js +31 -0
  130. package/dist/esm/elements/UnorderedList.js.map +1 -0
  131. package/dist/esm/elements/iconProps.js +49 -0
  132. package/dist/esm/elements/iconProps.js.map +1 -0
  133. package/dist/esm/form/Autocomplete.js +279 -0
  134. package/dist/esm/form/Autocomplete.js.map +1 -0
  135. package/dist/esm/form/Checkbox.js +111 -0
  136. package/dist/esm/form/Checkbox.js.map +1 -0
  137. package/dist/esm/form/Checkboxes.js +90 -0
  138. package/dist/esm/form/Checkboxes.js.map +1 -0
  139. package/dist/esm/form/Control.js +79 -0
  140. package/dist/esm/form/Control.js.map +1 -0
  141. package/dist/esm/form/DateInput.js +88 -0
  142. package/dist/esm/form/DateInput.js.map +1 -0
  143. package/dist/esm/form/DateInputBase.js +263 -0
  144. package/dist/esm/form/DateInputBase.js.map +1 -0
  145. package/dist/esm/form/DateRangeInput.js +77 -0
  146. package/dist/esm/form/DateRangeInput.js.map +1 -0
  147. package/dist/esm/form/DateRangeInputBase.js +301 -0
  148. package/dist/esm/form/DateRangeInputBase.js.map +1 -0
  149. package/dist/esm/form/DateTimeInput.js +88 -0
  150. package/dist/esm/form/DateTimeInput.js.map +1 -0
  151. package/dist/esm/form/DateTimeInputBase.js +333 -0
  152. package/dist/esm/form/DateTimeInputBase.js.map +1 -0
  153. package/dist/esm/form/Field.js +167 -0
  154. package/dist/esm/form/Field.js.map +1 -0
  155. package/dist/esm/form/File.js +112 -0
  156. package/dist/esm/form/File.js.map +1 -0
  157. package/dist/esm/form/FormContext.js +194 -0
  158. package/dist/esm/form/FormContext.js.map +1 -0
  159. package/dist/esm/form/Input.js +88 -0
  160. package/dist/esm/form/Input.js.map +1 -0
  161. package/dist/esm/form/InputBase.js +40 -0
  162. package/dist/esm/form/InputBase.js.map +1 -0
  163. package/dist/esm/form/Numberinput.js +201 -0
  164. package/dist/esm/form/Numberinput.js.map +1 -0
  165. package/dist/esm/form/Radio.js +108 -0
  166. package/dist/esm/form/Radio.js.map +1 -0
  167. package/dist/esm/form/Radios.js +92 -0
  168. package/dist/esm/form/Radios.js.map +1 -0
  169. package/dist/esm/form/Rate.js +280 -0
  170. package/dist/esm/form/Rate.js.map +1 -0
  171. package/dist/esm/form/Select.js +81 -0
  172. package/dist/esm/form/Select.js.map +1 -0
  173. package/dist/esm/form/SelectBase.js +54 -0
  174. package/dist/esm/form/SelectBase.js.map +1 -0
  175. package/dist/esm/form/Slider.js +461 -0
  176. package/dist/esm/form/Slider.js.map +1 -0
  177. package/dist/esm/form/Switch.js +96 -0
  178. package/dist/esm/form/Switch.js.map +1 -0
  179. package/dist/esm/form/Taginput.js +351 -0
  180. package/dist/esm/form/Taginput.js.map +1 -0
  181. package/dist/esm/form/TextArea.js +77 -0
  182. package/dist/esm/form/TextArea.js.map +1 -0
  183. package/dist/esm/form/TextAreaBase.js +45 -0
  184. package/dist/esm/form/TextAreaBase.js.map +1 -0
  185. package/dist/esm/form/TimeInput.js +84 -0
  186. package/dist/esm/form/TimeInput.js.map +1 -0
  187. package/dist/esm/form/TimeInputBase.js +246 -0
  188. package/dist/esm/form/TimeInputBase.js.map +1 -0
  189. package/dist/esm/form/_pickerInternals/Calendar.js +760 -0
  190. package/dist/esm/form/_pickerInternals/Calendar.js.map +1 -0
  191. package/dist/esm/form/_pickerInternals/PickerPopover.js +95 -0
  192. package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -0
  193. package/dist/esm/form/_pickerInternals/TimeWheels.js +721 -0
  194. package/dist/esm/form/_pickerInternals/TimeWheels.js.map +1 -0
  195. package/dist/esm/form/_pickerInternals/audioTick.js +109 -0
  196. package/dist/esm/form/_pickerInternals/audioTick.js.map +1 -0
  197. package/dist/esm/form/_pickerInternals/dateUtils.js +267 -0
  198. package/dist/esm/form/_pickerInternals/dateUtils.js.map +1 -0
  199. package/dist/esm/form/_pickerInternals/formatters.js +322 -0
  200. package/dist/esm/form/_pickerInternals/formatters.js.map +1 -0
  201. package/dist/esm/form/_pickerInternals/haptics.js +38 -0
  202. package/dist/esm/form/_pickerInternals/haptics.js.map +1 -0
  203. package/dist/esm/form/_pickerInternals/nativeInputSupport.js +25 -0
  204. package/dist/esm/form/_pickerInternals/nativeInputSupport.js.map +1 -0
  205. package/dist/esm/form/_pickerInternals/pickerTypes.js +50 -0
  206. package/dist/esm/form/_pickerInternals/pickerTypes.js.map +1 -0
  207. package/dist/esm/form/_pickerInternals/segmentMap.js +315 -0
  208. package/dist/esm/form/_pickerInternals/segmentMap.js.map +1 -0
  209. package/dist/esm/form/_pickerInternals/useNativeMobilePicker.js +49 -0
  210. package/dist/esm/form/_pickerInternals/useNativeMobilePicker.js.map +1 -0
  211. package/dist/esm/form/_pickerInternals/useSegmentedEntry.js +427 -0
  212. package/dist/esm/form/_pickerInternals/useSegmentedEntry.js.map +1 -0
  213. package/dist/esm/form/controlLoading.js +18 -0
  214. package/dist/esm/form/controlLoading.js.map +1 -0
  215. package/dist/esm/form/useAutoLabelId.js +88 -0
  216. package/dist/esm/form/useAutoLabelId.js.map +1 -0
  217. package/dist/esm/grid/Cell.js +35 -0
  218. package/dist/esm/grid/Cell.js.map +1 -0
  219. package/dist/esm/grid/Grid.js +51 -0
  220. package/dist/esm/grid/Grid.js.map +1 -0
  221. package/dist/esm/helpers/ClientOnly.js +33 -0
  222. package/dist/esm/helpers/ClientOnly.js.map +1 -0
  223. package/dist/esm/helpers/Config.js +60 -0
  224. package/dist/esm/helpers/Config.js.map +1 -0
  225. package/dist/esm/helpers/Theme.js +947 -0
  226. package/dist/esm/helpers/Theme.js.map +1 -0
  227. package/dist/esm/helpers/anchorAttrs.js +72 -0
  228. package/dist/esm/helpers/anchorAttrs.js.map +1 -0
  229. package/dist/esm/helpers/bulmaClassHelpers.js +415 -0
  230. package/dist/esm/helpers/bulmaClassHelpers.js.map +1 -0
  231. package/dist/esm/helpers/buttonType.js +24 -0
  232. package/dist/esm/helpers/buttonType.js.map +1 -0
  233. package/dist/esm/helpers/classNames.js +137 -0
  234. package/dist/esm/helpers/classNames.js.map +1 -0
  235. package/dist/esm/helpers/colorDeprecations.js +50 -0
  236. package/dist/esm/helpers/colorDeprecations.js.map +1 -0
  237. package/dist/esm/helpers/devWarnings.js +27 -0
  238. package/dist/esm/helpers/devWarnings.js.map +1 -0
  239. package/dist/esm/helpers/inertProps.js +27 -0
  240. package/dist/esm/helpers/inertProps.js.map +1 -0
  241. package/dist/esm/helpers/mergeBulmaStyles.js +20 -0
  242. package/dist/esm/helpers/mergeBulmaStyles.js.map +1 -0
  243. package/dist/esm/helpers/polymorphic.js +18 -0
  244. package/dist/esm/helpers/polymorphic.js.map +1 -0
  245. package/dist/esm/helpers/portal.js +76 -0
  246. package/dist/esm/helpers/portal.js.map +1 -0
  247. package/dist/esm/helpers/positionStacks.js +45 -0
  248. package/dist/esm/helpers/positionStacks.js.map +1 -0
  249. package/dist/esm/helpers/scrollLock.js +38 -0
  250. package/dist/esm/helpers/scrollLock.js.map +1 -0
  251. package/dist/esm/helpers/shadowDom.js +71 -0
  252. package/dist/esm/helpers/shadowDom.js.map +1 -0
  253. package/dist/esm/helpers/statusRegion.js +282 -0
  254. package/dist/esm/helpers/statusRegion.js.map +1 -0
  255. package/dist/esm/helpers/useAnchoredPosition.js +86 -0
  256. package/dist/esm/helpers/useAnchoredPosition.js.map +1 -0
  257. package/dist/esm/helpers/useBulmaClasses.js +158 -0
  258. package/dist/esm/helpers/useBulmaClasses.js.map +1 -0
  259. package/dist/esm/helpers/useClientLayoutEffect.js +13 -0
  260. package/dist/esm/helpers/useClientLayoutEffect.js.map +1 -0
  261. package/dist/esm/helpers/useColorClasses.js +84 -0
  262. package/dist/esm/helpers/useColorClasses.js.map +1 -0
  263. package/dist/esm/helpers/useFlexboxClasses.js +92 -0
  264. package/dist/esm/helpers/useFlexboxClasses.js.map +1 -0
  265. package/dist/esm/helpers/useFocusTrap.js +470 -0
  266. package/dist/esm/helpers/useFocusTrap.js.map +1 -0
  267. package/dist/esm/helpers/useIsHydrated.js +31 -0
  268. package/dist/esm/helpers/useIsHydrated.js.map +1 -0
  269. package/dist/esm/helpers/useOtherClasses.js +115 -0
  270. package/dist/esm/helpers/useOtherClasses.js.map +1 -0
  271. package/dist/esm/helpers/useSpacingClasses.js +82 -0
  272. package/dist/esm/helpers/useSpacingClasses.js.map +1 -0
  273. package/dist/esm/helpers/useTypographyClasses.js +93 -0
  274. package/dist/esm/helpers/useTypographyClasses.js.map +1 -0
  275. package/dist/esm/helpers/useVisibilityClasses.js +134 -0
  276. package/dist/esm/helpers/useVisibilityClasses.js.map +1 -0
  277. package/dist/esm/helpers/withSubComponents.js +24 -0
  278. package/dist/esm/helpers/withSubComponents.js.map +1 -0
  279. package/dist/esm/layout/Container.js +48 -0
  280. package/dist/esm/layout/Container.js.map +1 -0
  281. package/dist/esm/layout/Footer.js +33 -0
  282. package/dist/esm/layout/Footer.js.map +1 -0
  283. package/dist/esm/layout/Hero.js +90 -0
  284. package/dist/esm/layout/Hero.js.map +1 -0
  285. package/dist/esm/layout/Level.js +110 -0
  286. package/dist/esm/layout/Level.js.map +1 -0
  287. package/dist/esm/layout/Media.js +86 -0
  288. package/dist/esm/layout/Media.js.map +1 -0
  289. package/dist/esm/layout/Section.js +30 -0
  290. package/dist/esm/layout/Section.js.map +1 -0
  291. package/dist/extras.css +1 -1
  292. package/dist/extras.css.map +1 -1
  293. package/dist/index.cjs +187 -57
  294. package/dist/index.cjs.map +1 -1
  295. package/dist/index.esm.js +115 -17516
  296. package/dist/index.esm.js.map +1 -1
  297. package/dist/types/elements/Icon.d.ts +10 -7
  298. package/dist/types/form/Autocomplete.d.ts +1 -1
  299. package/dist/types/form/Checkboxes.d.ts +1 -1
  300. package/dist/types/form/DateInput.d.ts +1 -1
  301. package/dist/types/form/DateInputBase.d.ts +3 -4
  302. package/dist/types/form/DateRangeInput.d.ts +1 -1
  303. package/dist/types/form/DateTimeInput.d.ts +1 -1
  304. package/dist/types/form/DateTimeInputBase.d.ts +3 -4
  305. package/dist/types/form/Field.d.ts +2 -2
  306. package/dist/types/form/File.d.ts +4 -4
  307. package/dist/types/form/FormContext.d.ts +24 -2
  308. package/dist/types/form/Numberinput.d.ts +1 -1
  309. package/dist/types/form/Radios.d.ts +1 -1
  310. package/dist/types/form/Rate.d.ts +1 -1
  311. package/dist/types/form/Slider.d.ts +1 -1
  312. package/dist/types/form/Taginput.d.ts +1 -1
  313. package/dist/types/form/TimeInput.d.ts +1 -1
  314. package/dist/types/form/useAutoLabelId.d.ts +25 -4
  315. package/dist/types/helpers/Config.d.ts +3 -4
  316. package/dist/types/helpers/Theme.d.ts +44 -40
  317. package/dist/types-cjs/elements/Icon.d.ts +10 -7
  318. package/dist/types-cjs/form/Autocomplete.d.ts +1 -1
  319. package/dist/types-cjs/form/Checkboxes.d.ts +1 -1
  320. package/dist/types-cjs/form/DateInput.d.ts +1 -1
  321. package/dist/types-cjs/form/DateInputBase.d.ts +3 -4
  322. package/dist/types-cjs/form/DateRangeInput.d.ts +1 -1
  323. package/dist/types-cjs/form/DateTimeInput.d.ts +1 -1
  324. package/dist/types-cjs/form/DateTimeInputBase.d.ts +3 -4
  325. package/dist/types-cjs/form/Field.d.ts +2 -2
  326. package/dist/types-cjs/form/File.d.ts +4 -4
  327. package/dist/types-cjs/form/FormContext.d.ts +24 -2
  328. package/dist/types-cjs/form/Numberinput.d.ts +1 -1
  329. package/dist/types-cjs/form/Radios.d.ts +1 -1
  330. package/dist/types-cjs/form/Rate.d.ts +1 -1
  331. package/dist/types-cjs/form/Slider.d.ts +1 -1
  332. package/dist/types-cjs/form/Taginput.d.ts +1 -1
  333. package/dist/types-cjs/form/TimeInput.d.ts +1 -1
  334. package/dist/types-cjs/form/useAutoLabelId.d.ts +25 -4
  335. package/dist/types-cjs/helpers/Config.d.ts +3 -4
  336. package/dist/types-cjs/helpers/Theme.d.ts +44 -40
  337. package/dist/versions/bestax-no-dark-mode.css +1 -1
  338. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  339. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  340. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  341. package/dist/versions/bestax-no-helpers.css +1 -1
  342. package/dist/versions/bestax-no-helpers.css.map +1 -1
  343. package/dist/versions/bestax-prefixed.css +1 -1
  344. package/dist/versions/bestax-prefixed.css.map +1 -1
  345. package/package.json +1 -1
  346. package/src/scss/form/_dateinput.scss +37 -6
  347. package/src/scss/form/_datetimeinput.scss +7 -2
  348. package/src/scss/form/_picker-popover.scss +1 -4
@@ -0,0 +1,298 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ import { jsx, jsxs } from 'react/jsx-runtime';
3
+ import { createContext, useContext, useRef, useId, useState, useCallback, useMemo, useEffect, cloneElement } from 'react';
4
+ import { classNames, usePrefixedClassNames } from '../helpers/classNames.js';
5
+ import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
6
+ import { withSubComponents } from '../helpers/withSubComponents.js';
7
+ import { Portal } from '../helpers/portal.js';
8
+ import { useIsHydrated } from '../helpers/useIsHydrated.js';
9
+ import { useFocusTrap, firstTabStop } from '../helpers/useFocusTrap.js';
10
+ import { useAnchoredPosition, marginGap } from '../helpers/useAnchoredPosition.js';
11
+ import { useClientLayoutEffect } from '../helpers/useClientLayoutEffect.js';
12
+ import { getDeepestActiveElement, isEventInside } from '../helpers/shadowDom.js';
13
+ import { buttonType } from '../helpers/buttonType.js';
14
+ import { warnOnce } from '../helpers/devWarnings.js';
15
+ import { Button } from '../elements/Button.js';
16
+
17
+ const PopoverContext = createContext(null);
18
+ /** Intrinsic elements that are controls already, and keep their own role. */
19
+ const NATIVE_CONTROLS = new Set([
20
+ 'button',
21
+ 'input',
22
+ 'select',
23
+ 'textarea',
24
+ 'summary',
25
+ ]);
26
+ /**
27
+ * Whether the browser answers this key on `el` itself, by clicking it or by
28
+ * using the key as input, so the trigger's click handler covers it.
29
+ */
30
+ function handlesKeyItself(el, key) {
31
+ if (NATIVE_CONTROLS.has(el.localName))
32
+ return true;
33
+ return el.localName === 'a' && key === 'Enter' && el.hasAttribute('href');
34
+ }
35
+ /** The innermost dialog the event passed through, which is the one its Escape belongs to. */
36
+ function nearestDialog(event) {
37
+ return (event.composedPath().find(node => {
38
+ const role = node.getAttribute?.('role');
39
+ return role === 'dialog' || role === 'alertdialog';
40
+ }) ?? null);
41
+ }
42
+ /**
43
+ * The `Popover` component opens a panel of interactive content, such as a filter form or a set of share options, anchored to the element that toggles it.
44
+ *
45
+ * The panel is a non-modal `role="dialog"`: focus moves into it on open
46
+ * and returns to the trigger on close, while the rest of the page stays
47
+ * reachable by pointer and assistive technology. For hover-only hints use
48
+ * `Tooltip`, and for a list of actions use `Dropdown`.
49
+ *
50
+ * @function
51
+ * @param {PopoverProps} props - Props for the Popover component.
52
+ * @returns {JSX.Element} The trigger in its wrapper, and the panel while open.
53
+ *
54
+ * @example
55
+ * <Popover trigger={<Button>Filters</Button>}>
56
+ * <Popover.Header>Filter rows</Popover.Header>
57
+ * <Popover.Body>…</Popover.Body>
58
+ * <Popover.Footer>
59
+ * <Popover.Close>Done</Popover.Close>
60
+ * </Popover.Footer>
61
+ * </Popover>
62
+ */
63
+ const PopoverComponent = ({ trigger, children, open: controlledOpen, defaultOpen = false, onOpenChange, position = 'bottom-left', appendToBody = false, trapFocus = true, closeOnClickOutside = true, closeOnEscape = true, ariaLabel, className, contentClassName, ...props }) => {
64
+ const { bulmaHelperClasses, rest } = useBulmaClasses(props);
65
+ const rootRef = useRef(null);
66
+ const panelRef = useRef(null);
67
+ // The last pointerdown React saw inside the panel. React's tree includes
68
+ // content the panel portals elsewhere, which the DOM path doesn't.
69
+ const insidePointerRef = useRef(null);
70
+ const baseId = useId();
71
+ const panelId = `${baseId}-panel`;
72
+ const titleId = `${baseId}-title`;
73
+ const isControlled = controlledOpen !== undefined;
74
+ const [internalOpen, setInternalOpen] = useState(defaultOpen);
75
+ const isOpen = controlledOpen ?? internalOpen;
76
+ const requestOpen = useCallback((next) => {
77
+ onOpenChange?.(next);
78
+ if (!isControlled)
79
+ setInternalOpen(next);
80
+ }, [isControlled, onOpenChange]);
81
+ const close = useCallback(() => requestOpen(false), [requestOpen]);
82
+ // A portaled panel has no server markup, so it only exists from the commit
83
+ // after hydration. Everything that measures or focuses it waits for that.
84
+ const hydrated = useIsHydrated();
85
+ const panelMounted = isOpen && (hydrated || !appendToBody);
86
+ const resolved = useAnchoredPosition(rootRef, panelRef, {
87
+ active: panelMounted,
88
+ position,
89
+ fixed: appendToBody,
90
+ // The gap comes from `--bulma-popover-offset` in the stylesheet, so the
91
+ // coordinates leave it out and `auto` reads it off the panel.
92
+ offset: 0,
93
+ styledGap: marginGap,
94
+ });
95
+ // The trigger renders first inside the wrapper. Read when needed rather
96
+ // than held, so a trigger that remounted is still the one found.
97
+ const triggerNode = useCallback(() => {
98
+ const first = rootRef.current?.firstElementChild;
99
+ return first && first !== panelRef.current ? first : null;
100
+ }, []);
101
+ const restoreFocusRef = useMemo(() => ({
102
+ get current() {
103
+ return triggerNode();
104
+ },
105
+ }), [triggerNode]);
106
+ useFocusTrap(panelRef, {
107
+ active: panelMounted && trapFocus,
108
+ restoreFocus: restoreFocusRef,
109
+ });
110
+ // Without the trap, focus still arrives in the panel and goes back to the
111
+ // trigger, on the trap's terms: only while the panel still holds it.
112
+ useEffect(() => {
113
+ const panel = panelRef.current;
114
+ if (!panelMounted || trapFocus || !panel)
115
+ return undefined;
116
+ (firstTabStop(panel) ?? panel).focus();
117
+ return () => {
118
+ const doc = panel.ownerDocument;
119
+ const now = getDeepestActiveElement(doc);
120
+ if (!now || now === doc.body || panel.contains(now)) {
121
+ triggerNode()?.focus();
122
+ }
123
+ };
124
+ }, [panelMounted, trapFocus, triggerNode]);
125
+ useEffect(() => {
126
+ if (!panelMounted || !closeOnClickOutside)
127
+ return undefined;
128
+ const handlePointerDown = (e) => {
129
+ if (e === insidePointerRef.current || isEventInside(e, rootRef.current)) {
130
+ return;
131
+ }
132
+ close();
133
+ };
134
+ // The wrapper is on the page whenever the panel is. Its document, an
135
+ // iframe's when the tree renders into one, is where presses land.
136
+ const doc = rootRef.current.ownerDocument;
137
+ doc.addEventListener('pointerdown', handlePointerDown);
138
+ return () => doc.removeEventListener('pointerdown', handlePointerDown);
139
+ }, [panelMounted, closeOnClickOutside, close]);
140
+ const handlePanelKeyDown = (e) => {
141
+ if (e.key !== 'Escape' || !closeOnEscape || e.defaultPrevented)
142
+ return;
143
+ // React bubbles the key here from portaled content as well, so a dialog
144
+ // of its own on the way (a nested popover, a picker's calendar) owns it.
145
+ const owner = nearestDialog(e.nativeEvent);
146
+ if (owner && owner !== panelRef.current)
147
+ return;
148
+ e.preventDefault();
149
+ close();
150
+ };
151
+ const triggerProps = trigger.props;
152
+ const handleTriggerClick = (e) => {
153
+ triggerProps.onClick?.(e);
154
+ if (!e.defaultPrevented)
155
+ requestOpen(!isOpen);
156
+ };
157
+ const handleTriggerKeyDown = (e) => {
158
+ triggerProps.onKeyDown?.(e);
159
+ // A key on something inside the trigger is that element's to answer.
160
+ if (e.defaultPrevented || e.target !== e.currentTarget)
161
+ return;
162
+ if (e.key === 'Escape') {
163
+ if (isOpen && closeOnEscape) {
164
+ e.preventDefault();
165
+ close();
166
+ }
167
+ return;
168
+ }
169
+ if (e.key !== 'Enter' && e.key !== ' ')
170
+ return;
171
+ if (handlesKeyItself(e.currentTarget, e.key))
172
+ return;
173
+ // Space would scroll the page; a held key repeats.
174
+ e.preventDefault();
175
+ if (!e.repeat)
176
+ requestOpen(!isOpen);
177
+ };
178
+ const needsButtonRole = typeof trigger.type === 'string' &&
179
+ !NATIVE_CONTROLS.has(trigger.type) &&
180
+ !(trigger.type === 'a' && triggerProps.href != null);
181
+ const clonedTrigger = cloneElement(trigger, {
182
+ ...(needsButtonRole
183
+ ? {
184
+ role: triggerProps.role ?? 'button',
185
+ tabIndex: triggerProps.tabIndex ?? 0,
186
+ }
187
+ : {}),
188
+ 'aria-haspopup': 'dialog',
189
+ 'aria-expanded': isOpen,
190
+ 'aria-controls': panelMounted ? panelId : undefined,
191
+ onClick: handleTriggerClick,
192
+ onKeyDown: handleTriggerKeyDown,
193
+ });
194
+ const rootClasses = classNames(usePrefixedClassNames('popover', { 'is-active': isOpen }), bulmaHelperClasses, className);
195
+ const panelClasses = classNames(usePrefixedClassNames('popover-content', {
196
+ [`is-${resolved.position}`]: true,
197
+ 'is-portal': appendToBody,
198
+ }), contentClassName);
199
+ return (jsxs("div", { className: rootClasses, ...rest, ref: rootRef, children: [clonedTrigger, isOpen && (jsx(Portal, { disabled: !appendToBody, children: jsx(PopoverPanel, { panelRef: panelRef, titleId: titleId, ariaLabel: ariaLabel, close: close, id: panelId, className: panelClasses, style: appendToBody
200
+ ? {
201
+ position: 'fixed',
202
+ top: resolved.top,
203
+ left: resolved.left,
204
+ }
205
+ : undefined, onKeyDown: handlePanelKeyDown, onPointerDownCapture: e => {
206
+ insidePointerRef.current = e.nativeEvent;
207
+ }, children: children }) }))] }));
208
+ };
209
+ /**
210
+ * The open panel. It mounts with each opening, so it counts the
211
+ * `Popover.Header`s inside it afresh every time.
212
+ */
213
+ function PopoverPanel({ panelRef, titleId, ariaLabel, close, children, ...attrs }) {
214
+ // Headers register in a layout effect, after this first render, and this
215
+ // panel's own layout effect runs after theirs. Until then the panel assumes
216
+ // it has one, so a panel that does is named from its first commit, before
217
+ // focus moves in, and one that doesn't drops the reference before it paints.
218
+ const [titlesCounted, setTitlesCounted] = useState(false);
219
+ const [titleCount, setTitleCount] = useState(0);
220
+ const registerTitle = useCallback(() => {
221
+ setTitleCount(n => n + 1);
222
+ return () => setTitleCount(n => n - 1);
223
+ }, []);
224
+ useClientLayoutEffect(() => {
225
+ setTitlesCounted(true);
226
+ }, []);
227
+ const named = Boolean(ariaLabel) || titleCount > 0;
228
+ useEffect(() => {
229
+ if (titlesCounted && !named) {
230
+ warnOnce('Popover:unnamed', '[bestax-bulma] <Popover> opened a panel with no accessible name. ' +
231
+ 'Pass ariaLabel, or render a Popover.Header inside it.');
232
+ }
233
+ }, [titlesCounted, named]);
234
+ const context = useMemo(() => ({ titleId, registerTitle, close }), [titleId, registerTitle, close]);
235
+ return (jsx(PopoverContext.Provider, { value: context, children: jsx("div", { ...attrs, ref: panelRef, role: "dialog", "aria-label": ariaLabel, "aria-labelledby": !ariaLabel && (!titlesCounted || titleCount > 0) ? titleId : undefined, tabIndex: -1, children: children }) }));
236
+ }
237
+ /**
238
+ * The popover's title, which names the panel for assistive technology.
239
+ *
240
+ * @function
241
+ * @param {PopoverHeaderProps} props - Props for the Popover.Header component.
242
+ * @returns {JSX.Element} The header element.
243
+ */
244
+ const PopoverHeader = ({ className, ...props }) => {
245
+ const context = useContext(PopoverContext);
246
+ const registerTitle = context?.registerTitle;
247
+ // Before paint, so the panel is named by the time it shows.
248
+ useClientLayoutEffect(() => registerTitle?.(), [registerTitle]);
249
+ const { bulmaHelperClasses, rest } = useBulmaClasses(props);
250
+ return (jsx("div", { className: classNames(usePrefixedClassNames('popover-header'), bulmaHelperClasses, className), ...rest, id: context?.titleId }));
251
+ };
252
+ /**
253
+ * The popover's main content area.
254
+ *
255
+ * @function
256
+ * @param {PopoverBodyProps} props - Props for the Popover.Body component.
257
+ * @returns {JSX.Element} The body element.
258
+ */
259
+ const PopoverBody = ({ className, ...props }) => {
260
+ const { bulmaHelperClasses, rest } = useBulmaClasses(props);
261
+ return (jsx("div", { className: classNames(usePrefixedClassNames('popover-body'), bulmaHelperClasses, className), ...rest }));
262
+ };
263
+ /**
264
+ * A row of actions along the bottom of the popover, aligned to the end.
265
+ *
266
+ * @function
267
+ * @param {PopoverFooterProps} props - Props for the Popover.Footer component.
268
+ * @returns {JSX.Element} The footer element.
269
+ */
270
+ const PopoverFooter = ({ className, ...props }) => {
271
+ const { bulmaHelperClasses, rest } = useBulmaClasses(props);
272
+ return (jsx("div", { className: classNames(usePrefixedClassNames('popover-footer'), bulmaHelperClasses, className), ...rest }));
273
+ };
274
+ /**
275
+ * A `Button` that closes the popover, handing focus back to the trigger.
276
+ *
277
+ * @function
278
+ * @param {PopoverCloseProps} props - Props for the Popover.Close component.
279
+ * @returns {JSX.Element} The close button.
280
+ */
281
+ const PopoverClose = ({ onClick, ...props }) => {
282
+ const context = useContext(PopoverContext);
283
+ return (jsx(Button, { ...props, type: buttonType(props.type), onClick: (e) => {
284
+ onClick?.(e);
285
+ if (!e.defaultPrevented)
286
+ context?.close();
287
+ } }));
288
+ };
289
+ /** Popover with Header, Body, Footer and Close sub-components. */
290
+ const Popover = withSubComponents(PopoverComponent, {
291
+ Header: PopoverHeader,
292
+ Body: PopoverBody,
293
+ Footer: PopoverFooter,
294
+ Close: PopoverClose,
295
+ }, 'Popover');
296
+
297
+ export { Popover, PopoverBody, PopoverClose, PopoverFooter, PopoverHeader };
298
+ //# sourceMappingURL=Popover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Popover.js","sources":["../../../src/components/Popover.tsx"],"sourcesContent":["import React, {\n cloneElement,\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { Portal } from '../helpers/portal';\nimport { useIsHydrated } from '../helpers/useIsHydrated';\nimport { firstTabStop, useFocusTrap } from '../helpers/useFocusTrap';\nimport { marginGap, useAnchoredPosition } from '../helpers/useAnchoredPosition';\nimport { useClientLayoutEffect } from '../helpers/useClientLayoutEffect';\nimport { getDeepestActiveElement, isEventInside } from '../helpers/shadowDom';\nimport { buttonType } from '../helpers/buttonType';\nimport { warnOnce } from '../helpers/devWarnings';\nimport { Button, ButtonOwnProps } from '../elements/Button';\nimport type { PickerPosition } from '../form/_pickerInternals/pickerTypes';\n\n/**\n * Where the panel opens against its trigger: below (`bottom-*`) or above\n * (`top-*`), lined up with the trigger's left or right edge. `auto` picks the\n * one that keeps the panel in the viewport, preferring below and lined up on\n * the left. The same union the date and time pickers take.\n */\nexport type PopoverPosition = PickerPosition;\n\n/**\n * Props for the Popover component. `className`, `id`, the other HTML\n * attributes and the helper props land on the wrapper around the trigger,\n * not on the panel; `contentClassName` reaches the panel.\n * @extraProp {string} [className] - Additional classes for the wrapper around the trigger. The panel takes `contentClassName`.\n */\nexport interface PopoverProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'children'>,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor'> {\n /**\n * The element that opens and closes the popover, such as a `Button`.\n * Popover gives it `aria-haspopup=\"dialog\"`, `aria-expanded`,\n * `aria-controls` while the panel is open, and click and key handlers that\n * run after its own (call `preventDefault()` in yours to keep the popover\n * from toggling). It has to be a single element that passes `onClick` and\n * `onKeyDown` to its DOM node. Enter and Space toggle a trigger the browser\n * doesn't click on its own, and an intrinsic element that isn't already a\n * control (a `<span>`) also gets `role=\"button\"` and `tabIndex={0}` unless\n * it sets them; a component that renders one has to take those itself.\n */\n trigger: React.ReactElement;\n /** The panel's content, usually `Popover.Header`, `Popover.Body` and `Popover.Footer`. */\n children?: React.ReactNode;\n /**\n * Controlled open state. When set, the trigger and every dismissal only\n * report through `onOpenChange`.\n */\n open?: boolean;\n /**\n * Initial open state when uncontrolled. Opening moves focus into the\n * panel, so a popover that starts open takes focus once the page loads.\n * @defaultValue false\n */\n defaultOpen?: boolean;\n /**\n * Called with the state asked for: `true` from the trigger opening it,\n * `false` from the trigger, `Popover.Close`, Escape or an outside\n * `pointerdown`. Fires in both controlled and uncontrolled use.\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * Where the panel opens against the trigger.\n * @defaultValue 'bottom-left'\n */\n position?: PopoverPosition;\n /**\n * Render the panel at the end of `document.body` through `Portal`, fixed to\n * the viewport, so an ancestor's `overflow`, `transform` or stacking context\n * can't clip it. The panel then shows from the commit after hydration,\n * never in server markup. It is measured against the trigger when it opens\n * and on resize and scroll, so it doesn't follow content that changes size\n * while it is open. Theming variables set on an ancestor of the trigger\n * don't reach it there.\n * @defaultValue false\n */\n appendToBody?: boolean;\n /**\n * Keep Tab and Shift+Tab inside the panel while it is open, as the ARIA\n * dialog pattern does for a non-modal dialog. Pointer focus leaves freely\n * and the page stays usable. With `false`, Tab moves past the panel and\n * the popover stays open. Focus moves into the panel on open and back to\n * the trigger on close either way.\n * @defaultValue true\n */\n trapFocus?: boolean;\n /**\n * Close on a `pointerdown` outside the trigger and the panel. Content the\n * panel renders through a portal (a nested `Popover`, a portaled picker)\n * still counts as inside.\n * @defaultValue true\n */\n closeOnClickOutside?: boolean;\n /**\n * Close on Escape while focus is in the panel or on the trigger. A dialog\n * nested in the panel, such as a date picker's calendar, takes its own\n * Escape first, and so does content that calls `preventDefault()` on it.\n * @defaultValue true\n */\n closeOnEscape?: boolean;\n /**\n * The panel's accessible name. Without it the panel is named by its\n * `Popover.Header`, and a development build warns when it has neither.\n */\n ariaLabel?: string;\n /** Additional classes for the panel (`.popover-content`). */\n contentClassName?: string;\n}\n\ninterface PopoverContextValue {\n /** The id `Popover.Header` takes, which names the panel. */\n titleId: string;\n /** Records a mounted `Popover.Header`; the returned function forgets it. */\n registerTitle: () => () => void;\n /** Asks the popover to close. */\n close: () => void;\n}\n\nconst PopoverContext = createContext<PopoverContextValue | null>(null);\n\n/** The trigger props Popover reads before replacing them. */\ninterface TriggerProps {\n onClick?: (event: React.MouseEvent<HTMLElement>) => void;\n onKeyDown?: (event: React.KeyboardEvent<HTMLElement>) => void;\n role?: string;\n tabIndex?: number;\n href?: unknown;\n}\n\n/** Intrinsic elements that are controls already, and keep their own role. */\nconst NATIVE_CONTROLS = new Set([\n 'button',\n 'input',\n 'select',\n 'textarea',\n 'summary',\n]);\n\n/**\n * Whether the browser answers this key on `el` itself, by clicking it or by\n * using the key as input, so the trigger's click handler covers it.\n */\nfunction handlesKeyItself(el: Element, key: string): boolean {\n if (NATIVE_CONTROLS.has(el.localName)) return true;\n return el.localName === 'a' && key === 'Enter' && el.hasAttribute('href');\n}\n\n/** The innermost dialog the event passed through, which is the one its Escape belongs to. */\nfunction nearestDialog(event: Event): EventTarget | null {\n return (\n event.composedPath().find(node => {\n const role = (node as Element).getAttribute?.('role');\n return role === 'dialog' || role === 'alertdialog';\n }) ?? null\n );\n}\n\n/**\n * The `Popover` component opens a panel of interactive content, such as a filter form or a set of share options, anchored to the element that toggles it.\n *\n * The panel is a non-modal `role=\"dialog\"`: focus moves into it on open\n * and returns to the trigger on close, while the rest of the page stays\n * reachable by pointer and assistive technology. For hover-only hints use\n * `Tooltip`, and for a list of actions use `Dropdown`.\n *\n * @function\n * @param {PopoverProps} props - Props for the Popover component.\n * @returns {JSX.Element} The trigger in its wrapper, and the panel while open.\n *\n * @example\n * <Popover trigger={<Button>Filters</Button>}>\n * <Popover.Header>Filter rows</Popover.Header>\n * <Popover.Body>…</Popover.Body>\n * <Popover.Footer>\n * <Popover.Close>Done</Popover.Close>\n * </Popover.Footer>\n * </Popover>\n */\nconst PopoverComponent: React.FC<PopoverProps> = ({\n trigger,\n children,\n open: controlledOpen,\n defaultOpen = false,\n onOpenChange,\n position = 'bottom-left',\n appendToBody = false,\n trapFocus = true,\n closeOnClickOutside = true,\n closeOnEscape = true,\n ariaLabel,\n className,\n contentClassName,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const rootRef = useRef<HTMLDivElement>(null);\n const panelRef = useRef<HTMLDivElement>(null);\n // The last pointerdown React saw inside the panel. React's tree includes\n // content the panel portals elsewhere, which the DOM path doesn't.\n const insidePointerRef = useRef<Event | null>(null);\n const baseId = useId();\n const panelId = `${baseId}-panel`;\n const titleId = `${baseId}-title`;\n\n const isControlled = controlledOpen !== undefined;\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const isOpen = controlledOpen ?? internalOpen;\n\n const requestOpen = useCallback(\n (next: boolean) => {\n onOpenChange?.(next);\n if (!isControlled) setInternalOpen(next);\n },\n [isControlled, onOpenChange]\n );\n const close = useCallback(() => requestOpen(false), [requestOpen]);\n\n // A portaled panel has no server markup, so it only exists from the commit\n // after hydration. Everything that measures or focuses it waits for that.\n const hydrated = useIsHydrated();\n const panelMounted = isOpen && (hydrated || !appendToBody);\n\n const resolved = useAnchoredPosition(rootRef, panelRef, {\n active: panelMounted,\n position,\n fixed: appendToBody,\n // The gap comes from `--bulma-popover-offset` in the stylesheet, so the\n // coordinates leave it out and `auto` reads it off the panel.\n offset: 0,\n styledGap: marginGap,\n });\n\n // The trigger renders first inside the wrapper. Read when needed rather\n // than held, so a trigger that remounted is still the one found.\n const triggerNode = useCallback((): HTMLElement | null => {\n const first = rootRef.current?.firstElementChild;\n return first && first !== panelRef.current ? (first as HTMLElement) : null;\n }, []);\n const restoreFocusRef = useMemo(\n () => ({\n get current() {\n return triggerNode();\n },\n }),\n [triggerNode]\n );\n\n useFocusTrap(panelRef, {\n active: panelMounted && trapFocus,\n restoreFocus: restoreFocusRef,\n });\n\n // Without the trap, focus still arrives in the panel and goes back to the\n // trigger, on the trap's terms: only while the panel still holds it.\n useEffect(() => {\n const panel = panelRef.current;\n if (!panelMounted || trapFocus || !panel) return undefined;\n (firstTabStop(panel) ?? panel).focus();\n return () => {\n const doc = panel.ownerDocument;\n const now = getDeepestActiveElement(doc);\n if (!now || now === doc.body || panel.contains(now)) {\n triggerNode()?.focus();\n }\n };\n }, [panelMounted, trapFocus, triggerNode]);\n\n useEffect(() => {\n if (!panelMounted || !closeOnClickOutside) return undefined;\n const handlePointerDown = (e: PointerEvent) => {\n if (e === insidePointerRef.current || isEventInside(e, rootRef.current)) {\n return;\n }\n close();\n };\n // The wrapper is on the page whenever the panel is. Its document, an\n // iframe's when the tree renders into one, is where presses land.\n const doc = (rootRef.current as HTMLDivElement).ownerDocument;\n doc.addEventListener('pointerdown', handlePointerDown);\n return () => doc.removeEventListener('pointerdown', handlePointerDown);\n }, [panelMounted, closeOnClickOutside, close]);\n\n const handlePanelKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (e.key !== 'Escape' || !closeOnEscape || e.defaultPrevented) return;\n // React bubbles the key here from portaled content as well, so a dialog\n // of its own on the way (a nested popover, a picker's calendar) owns it.\n const owner = nearestDialog(e.nativeEvent);\n if (owner && owner !== panelRef.current) return;\n e.preventDefault();\n close();\n };\n\n const triggerProps = trigger.props as TriggerProps;\n\n const handleTriggerClick = (e: React.MouseEvent<HTMLElement>) => {\n triggerProps.onClick?.(e);\n if (!e.defaultPrevented) requestOpen(!isOpen);\n };\n\n const handleTriggerKeyDown = (e: React.KeyboardEvent<HTMLElement>) => {\n triggerProps.onKeyDown?.(e);\n // A key on something inside the trigger is that element's to answer.\n if (e.defaultPrevented || e.target !== e.currentTarget) return;\n if (e.key === 'Escape') {\n if (isOpen && closeOnEscape) {\n e.preventDefault();\n close();\n }\n return;\n }\n if (e.key !== 'Enter' && e.key !== ' ') return;\n if (handlesKeyItself(e.currentTarget, e.key)) return;\n // Space would scroll the page; a held key repeats.\n e.preventDefault();\n if (!e.repeat) requestOpen(!isOpen);\n };\n\n const needsButtonRole =\n typeof trigger.type === 'string' &&\n !NATIVE_CONTROLS.has(trigger.type) &&\n !(trigger.type === 'a' && triggerProps.href != null);\n\n const clonedTrigger = cloneElement(\n trigger as React.ReactElement<Record<string, unknown>>,\n {\n ...(needsButtonRole\n ? {\n role: triggerProps.role ?? 'button',\n tabIndex: triggerProps.tabIndex ?? 0,\n }\n : {}),\n 'aria-haspopup': 'dialog',\n 'aria-expanded': isOpen,\n 'aria-controls': panelMounted ? panelId : undefined,\n onClick: handleTriggerClick,\n onKeyDown: handleTriggerKeyDown,\n }\n );\n\n const rootClasses = classNames(\n usePrefixedClassNames('popover', { 'is-active': isOpen }),\n bulmaHelperClasses,\n className\n );\n const panelClasses = classNames(\n usePrefixedClassNames('popover-content', {\n [`is-${resolved.position}`]: true,\n 'is-portal': appendToBody,\n }),\n contentClassName\n );\n\n return (\n // The ref after the spread: React 19 hands a function component a `ref`\n // prop like any other, and the wrapper has to stay ours.\n <div className={rootClasses} {...rest} ref={rootRef}>\n {clonedTrigger}\n {isOpen && (\n <Portal disabled={!appendToBody}>\n <PopoverPanel\n panelRef={panelRef}\n titleId={titleId}\n ariaLabel={ariaLabel}\n close={close}\n id={panelId}\n className={panelClasses}\n style={\n appendToBody\n ? {\n position: 'fixed',\n top: resolved.top,\n left: resolved.left,\n }\n : undefined\n }\n onKeyDown={handlePanelKeyDown}\n onPointerDownCapture={e => {\n insidePointerRef.current = e.nativeEvent;\n }}\n >\n {children}\n </PopoverPanel>\n </Portal>\n )}\n </div>\n );\n};\n\ninterface PopoverPanelProps extends React.HTMLAttributes<HTMLDivElement> {\n panelRef: React.RefObject<HTMLDivElement | null>;\n titleId: string;\n ariaLabel?: string;\n close: () => void;\n}\n\n/**\n * The open panel. It mounts with each opening, so it counts the\n * `Popover.Header`s inside it afresh every time.\n */\nfunction PopoverPanel({\n panelRef,\n titleId,\n ariaLabel,\n close,\n children,\n ...attrs\n}: PopoverPanelProps) {\n // Headers register in a layout effect, after this first render, and this\n // panel's own layout effect runs after theirs. Until then the panel assumes\n // it has one, so a panel that does is named from its first commit, before\n // focus moves in, and one that doesn't drops the reference before it paints.\n const [titlesCounted, setTitlesCounted] = useState(false);\n const [titleCount, setTitleCount] = useState(0);\n const registerTitle = useCallback(() => {\n setTitleCount(n => n + 1);\n return () => setTitleCount(n => n - 1);\n }, []);\n useClientLayoutEffect(() => {\n setTitlesCounted(true);\n }, []);\n const named = Boolean(ariaLabel) || titleCount > 0;\n\n useEffect(() => {\n if (titlesCounted && !named) {\n warnOnce(\n 'Popover:unnamed',\n '[bestax-bulma] <Popover> opened a panel with no accessible name. ' +\n 'Pass ariaLabel, or render a Popover.Header inside it.'\n );\n }\n }, [titlesCounted, named]);\n\n const context = useMemo(\n () => ({ titleId, registerTitle, close }),\n [titleId, registerTitle, close]\n );\n\n return (\n <PopoverContext.Provider value={context}>\n <div\n {...attrs}\n ref={panelRef}\n role=\"dialog\"\n aria-label={ariaLabel}\n aria-labelledby={\n !ariaLabel && (!titlesCounted || titleCount > 0) ? titleId : undefined\n }\n tabIndex={-1}\n >\n {children}\n </div>\n </PopoverContext.Provider>\n );\n}\n\n/**\n * Props for the Popover.Header component. Its `id` is the one the panel's\n * `aria-labelledby` names, so it isn't yours to set.\n */\nexport interface PopoverHeaderProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'id'>,\n BulmaClassesProps {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * The popover's title, which names the panel for assistive technology.\n *\n * @function\n * @param {PopoverHeaderProps} props - Props for the Popover.Header component.\n * @returns {JSX.Element} The header element.\n */\nexport const PopoverHeader: React.FC<PopoverHeaderProps> = ({\n className,\n ...props\n}) => {\n const context = useContext(PopoverContext);\n const registerTitle = context?.registerTitle;\n // Before paint, so the panel is named by the time it shows.\n useClientLayoutEffect(() => registerTitle?.(), [registerTitle]);\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n return (\n <div\n className={classNames(\n usePrefixedClassNames('popover-header'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n id={context?.titleId}\n />\n );\n};\n\n/**\n * Props for the Popover.Body component.\n */\nexport interface PopoverBodyProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n BulmaClassesProps {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * The popover's main content area.\n *\n * @function\n * @param {PopoverBodyProps} props - Props for the Popover.Body component.\n * @returns {JSX.Element} The body element.\n */\nexport const PopoverBody: React.FC<PopoverBodyProps> = ({\n className,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n return (\n <div\n className={classNames(\n usePrefixedClassNames('popover-body'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n />\n );\n};\n\n/**\n * Props for the Popover.Footer component.\n */\nexport interface PopoverFooterProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>,\n BulmaClassesProps {\n /** Additional CSS classes. */\n className?: string;\n}\n\n/**\n * A row of actions along the bottom of the popover, aligned to the end.\n *\n * @function\n * @param {PopoverFooterProps} props - Props for the Popover.Footer component.\n * @returns {JSX.Element} The footer element.\n */\nexport const PopoverFooter: React.FC<PopoverFooterProps> = ({\n className,\n ...props\n}) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n return (\n <div\n className={classNames(\n usePrefixedClassNames('popover-footer'),\n bulmaHelperClasses,\n className\n )}\n {...rest}\n />\n );\n};\n\n/**\n * Props for the Popover.Close component: the props of a `Button` rendered as\n * a `<button>`.\n * @extraProp {'button' | 'submit' | 'reset'} [type='button'] - Button type. Defaults to `'button'`, so a close button inside a form doesn't submit it.\n * @extraProp {React.MouseEventHandler<HTMLButtonElement>} [onClick] - Runs before the popover closes. Call `preventDefault()` to keep it open.\n */\nexport interface PopoverCloseProps\n extends\n ButtonOwnProps,\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, keyof ButtonOwnProps> {}\n\n/**\n * A `Button` that closes the popover, handing focus back to the trigger.\n *\n * @function\n * @param {PopoverCloseProps} props - Props for the Popover.Close component.\n * @returns {JSX.Element} The close button.\n */\nexport const PopoverClose: React.FC<PopoverCloseProps> = ({\n onClick,\n ...props\n}) => {\n const context = useContext(PopoverContext);\n return (\n <Button\n {...props}\n type={buttonType(props.type)}\n onClick={(e: React.MouseEvent<HTMLButtonElement>) => {\n onClick?.(e);\n if (!e.defaultPrevented) context?.close();\n }}\n />\n );\n};\n\n/** Popover with Header, Body, Footer and Close sub-components. */\nexport const Popover = withSubComponents(\n PopoverComponent,\n {\n Header: PopoverHeader,\n Body: PopoverBody,\n Footer: PopoverFooter,\n Close: PopoverClose,\n },\n 'Popover'\n);\n\nexport default Popover;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
@@ -0,0 +1,157 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ import { jsx } from 'react/jsx-runtime';
3
+ import React, { useState, useEffect, Children, isValidElement, cloneElement } from 'react';
4
+ import { prefixedClassNames, classNames, usePrefixedClassNames } from '../helpers/classNames.js';
5
+ import { useClassPrefix } from '../helpers/Config.js';
6
+ import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
7
+
8
+ /**
9
+ * Detects the user's `prefers-reduced-motion` preference. Always `false` on
10
+ * the server and on the very first client render, so SSR output and the
11
+ * initial hydration pass always agree.
12
+ *
13
+ * @function
14
+ * @returns {boolean} Whether the user has requested reduced motion.
15
+ */
16
+ function usePrefersReducedMotion() {
17
+ const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);
18
+ useEffect(() => {
19
+ if (typeof window === 'undefined' || !window.matchMedia)
20
+ return undefined;
21
+ const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');
22
+ // eslint-disable-next-line react-hooks/set-state-in-effect -- reads the live media query on mount
23
+ setPrefersReducedMotion(mediaQuery.matches);
24
+ const handleChange = (event) => {
25
+ setPrefersReducedMotion(event.matches);
26
+ };
27
+ mediaQuery.addEventListener('change', handleChange);
28
+ return () => mediaQuery.removeEventListener('change', handleChange);
29
+ }, []);
30
+ return prefersReducedMotion;
31
+ }
32
+ /**
33
+ * The `Reveal` component animates its content into view as it scrolls into the viewport, backed by `IntersectionObserver`.
34
+ *
35
+ * @function
36
+ * @param {RevealProps} props - Props for the Reveal component.
37
+ * @returns {JSX.Element} The rendered reveal wrapper.
38
+ *
39
+ * @example
40
+ * // Fade a section up into view
41
+ * <Reveal animation="fade-up" as={Section}>
42
+ * <Title>Why Grass Doctor</Title>
43
+ * </Reveal>
44
+ *
45
+ * @example
46
+ * // Stagger a set of cards as they enter the viewport
47
+ * <Reveal animation="fade-up" cascade cascadeInterval={80}>
48
+ * {services.map(service => (
49
+ * <Card key={service.name}>{service.name}</Card>
50
+ * ))}
51
+ * </Reveal>
52
+ */
53
+ function RevealImpl(revealProps) {
54
+ const { animation = 'fade-up', delay = 0, duration = 600, threshold = 0.15, once = true, as: Component = 'div', cascade = false, cascadeInterval = 80, className, style, children, ...props } = revealProps;
55
+ const { bulmaHelperClasses, rest } = useBulmaClasses(props);
56
+ const classPrefix = useClassPrefix();
57
+ const prefersReducedMotion = usePrefersReducedMotion();
58
+ const [node, setNode] = useState(null);
59
+ const [isMounted, setIsMounted] = useState(false);
60
+ const [isRevealed, setIsRevealed] = useState(false);
61
+ // IntersectionObserver throws a RangeError for NaN or thresholds outside
62
+ // 0-1, so clamp valid numbers and fall back to the default for anything else.
63
+ const observerThreshold = Number.isFinite(threshold)
64
+ ? Math.min(Math.max(threshold, 0), 1)
65
+ : 0.15;
66
+ useEffect(() => {
67
+ // eslint-disable-next-line react-hooks/set-state-in-effect -- flips to true once mounted on the client so SSR/first-paint markup matches the server
68
+ setIsMounted(true);
69
+ }, []);
70
+ useEffect(() => {
71
+ if (prefersReducedMotion) {
72
+ // eslint-disable-next-line react-hooks/set-state-in-effect -- reduced motion skips straight to the revealed state
73
+ setIsRevealed(true);
74
+ return undefined;
75
+ }
76
+ if (typeof IntersectionObserver === 'undefined') {
77
+ setIsRevealed(true);
78
+ return undefined;
79
+ }
80
+ // The ref callback attaches after this effect's first pass; it re-runs
81
+ // once `node` becomes available since it's a dependency.
82
+ if (!node)
83
+ return undefined;
84
+ const observer = new IntersectionObserver(([entry]) => {
85
+ if (entry.isIntersecting) {
86
+ setIsRevealed(true);
87
+ if (once)
88
+ observer.unobserve(node);
89
+ }
90
+ else if (!once) {
91
+ setIsRevealed(false);
92
+ }
93
+ }, { threshold: observerThreshold });
94
+ observer.observe(node);
95
+ return () => observer.disconnect();
96
+ }, [node, prefersReducedMotion, once, observerThreshold]);
97
+ // Only apply the hidden/animating state once mounted on the client with
98
+ // motion allowed; otherwise render the final, visible state (SSR-safe).
99
+ const isAnimated = isMounted && !prefersReducedMotion;
100
+ const revealed = !isAnimated || isRevealed;
101
+ const itemAnimationClasses = prefixedClassNames(classPrefix, {
102
+ [`reveal-${animation}`]: isAnimated,
103
+ 'is-revealed': revealed,
104
+ });
105
+ const combinedClasses = classNames(usePrefixedClassNames('reveal', { 'is-cascade': cascade }), !cascade && itemAnimationClasses, bulmaHelperClasses, className);
106
+ const wrapperStyle = cascade
107
+ ? { ...style }
108
+ : {
109
+ ...style,
110
+ transitionDelay: `${delay}ms`,
111
+ transitionDuration: `${duration}ms`,
112
+ };
113
+ const content = cascade
114
+ ? Children.toArray(children).map((child, index) => {
115
+ const itemStyle = {
116
+ transitionDelay: `${delay + index * cascadeInterval}ms`,
117
+ transitionDuration: `${duration}ms`,
118
+ };
119
+ if (isValidElement(child)) {
120
+ return cloneElement(child, {
121
+ // Children.toArray always assigns a key, generating one from
122
+ // the position when the element doesn't already have one.
123
+ key: child.key,
124
+ className: classNames(itemAnimationClasses, child.props.className),
125
+ style: { ...itemStyle, ...child.props.style },
126
+ });
127
+ }
128
+ return (jsx("span", { className: itemAnimationClasses, style: itemStyle, children: child }, index));
129
+ })
130
+ : children;
131
+ // Scroll observation needs a DOM node this component OWNS — the observer and
132
+ // the animation classes both key off it. An intrinsic tag is that node, so
133
+ // the ref goes straight on it. A component passed via `as` is not: whatever
134
+ // it renders is its own business, and it may render several elements or
135
+ // none. So it gets wrapped in an observed `div`.
136
+ //
137
+ // Not a statement about ref forwarding. Several components in this library
138
+ // forward refs (#641 added four more), and that changes nothing here — a
139
+ // forwarded ref would still point at the target's node rather than at one
140
+ // this component controls.
141
+ if (typeof Component === 'string') {
142
+ // A plain createElement call sidesteps the combinatorial JSX prop types
143
+ // for `ref` across every possible intrinsic tag `as` could be.
144
+ return React.createElement(Component, {
145
+ ...rest,
146
+ ref: setNode,
147
+ className: combinedClasses,
148
+ style: wrapperStyle,
149
+ }, content);
150
+ }
151
+ return (jsx("div", { ref: setNode, className: combinedClasses, style: wrapperStyle, children: jsx(Component, { ...rest, children: content }) }));
152
+ }
153
+ const Reveal = RevealImpl;
154
+ Reveal.displayName = 'Reveal';
155
+
156
+ export { Reveal };
157
+ //# sourceMappingURL=Reveal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Reveal.js","sources":["../../../src/components/Reveal.tsx"],"sourcesContent":["import React, {\n Children,\n cloneElement,\n isValidElement,\n useEffect,\n useState,\n} from 'react';\nimport {\n classNames,\n prefixedClassNames,\n usePrefixedClassNames,\n} from '../helpers/classNames';\nimport { useClassPrefix } from '../helpers/Config';\nimport type { PolymorphicComponentWithoutRef } from '../helpers/polymorphic';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\n\n/**\n * Animation styles available for the Reveal component.\n */\nexport type RevealAnimation =\n | 'fade'\n | 'fade-up'\n | 'fade-down'\n | 'slide-left'\n | 'slide-right'\n | 'zoom'\n | 'flip';\n\n/**\n * The Reveal component's own props — everything it adds on top of the\n * attributes of whatever element `as` renders.\n */\nexport interface RevealOwnProps extends BulmaClassesProps {\n /** Animation style applied when the element enters the viewport. */\n animation?: RevealAnimation;\n /** Delay in milliseconds before the animation starts. Default: 0. */\n delay?: number;\n /** Animation duration in milliseconds. Default: 600. */\n duration?: number;\n /** Fraction (0-1) of the element that must be visible to trigger the reveal. Clamped to the 0-1 range; non-finite values fall back to `0.15`. */\n threshold?: number;\n /** Animate only the first time the element enters the viewport. If `false`, it re-animates on every entry/exit. */\n once?: boolean;\n /** Stagger direct children with an incrementing delay instead of animating this element as a single block. */\n cascade?: boolean;\n /** Milliseconds added to each successive child's delay when `cascade` is set. Default: 80. */\n cascadeInterval?: number;\n /** Content to reveal. */\n children?: React.ReactNode;\n /** Additional CSS classes. Applied to the observed element (the wrapper `div` when `as` is a component). */\n className?: string;\n /** Inline styles, merged after the animation's own. Applied to the observed element. */\n style?: React.CSSProperties;\n}\n\n/**\n * Props for the Reveal component. The DOM attributes follow `as`.\n *\n * Reveal forwards no `ref`: it owns the node it observes for scroll\n * intersection, and when `as` is a component that node is a wrapper `div`\n * rather than the element `as` names — so a ref derived from `as` would point\n * at the wrong thing.\n */\nexport type RevealProps<T extends React.ElementType = 'div'> = RevealOwnProps &\n Omit<React.ComponentPropsWithoutRef<T>, keyof RevealOwnProps | 'as'> & {\n /** Element or component to render as. Default: 'div'. When `as` is a plain intrinsic tag (e.g. `'section'`), your `className`, `style`, and Bulma helper classes plus everything in `...rest` all land on that single element. When `as` is a component (e.g. `Section`, `Card`), scroll detection needs a real DOM node with a ref, so `Reveal` wraps it in an observed `div`: `className`/`style`/helper classes go on that wrapper `div`, while `...rest` (`id`, `aria-*`, `data-*`, event handlers) is forwarded to the inner component. */\n as?: T;\n };\n\n/**\n * The shape the implementation destructures. The public contract is the generic\n * `RevealProps<T>` above — the body cannot see through `T`.\n */\ntype RevealImplProps = RevealOwnProps & { as?: React.ElementType };\n\n/**\n * Detects the user's `prefers-reduced-motion` preference. Always `false` on\n * the server and on the very first client render, so SSR output and the\n * initial hydration pass always agree.\n *\n * @function\n * @returns {boolean} Whether the user has requested reduced motion.\n */\nfunction usePrefersReducedMotion(): boolean {\n const [prefersReducedMotion, setPrefersReducedMotion] = useState(false);\n\n useEffect(() => {\n if (typeof window === 'undefined' || !window.matchMedia) return undefined;\n\n const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)');\n // eslint-disable-next-line react-hooks/set-state-in-effect -- reads the live media query on mount\n setPrefersReducedMotion(mediaQuery.matches);\n\n const handleChange = (event: MediaQueryListEvent) => {\n setPrefersReducedMotion(event.matches);\n };\n\n mediaQuery.addEventListener('change', handleChange);\n return () => mediaQuery.removeEventListener('change', handleChange);\n }, []);\n\n return prefersReducedMotion;\n}\n\n/**\n * The `Reveal` component animates its content into view as it scrolls into the viewport, backed by `IntersectionObserver`.\n *\n * @function\n * @param {RevealProps} props - Props for the Reveal component.\n * @returns {JSX.Element} The rendered reveal wrapper.\n *\n * @example\n * // Fade a section up into view\n * <Reveal animation=\"fade-up\" as={Section}>\n * <Title>Why Grass Doctor</Title>\n * </Reveal>\n *\n * @example\n * // Stagger a set of cards as they enter the viewport\n * <Reveal animation=\"fade-up\" cascade cascadeInterval={80}>\n * {services.map(service => (\n * <Card key={service.name}>{service.name}</Card>\n * ))}\n * </Reveal>\n */\nfunction RevealImpl(revealProps: RevealProps) {\n const {\n animation = 'fade-up',\n delay = 0,\n duration = 600,\n threshold = 0.15,\n once = true,\n as: Component = 'div',\n cascade = false,\n cascadeInterval = 80,\n className,\n style,\n children,\n ...props\n } = revealProps as RevealImplProps;\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const classPrefix = useClassPrefix();\n const prefersReducedMotion = usePrefersReducedMotion();\n const [node, setNode] = useState<HTMLElement | null>(null);\n const [isMounted, setIsMounted] = useState(false);\n const [isRevealed, setIsRevealed] = useState(false);\n\n // IntersectionObserver throws a RangeError for NaN or thresholds outside\n // 0-1, so clamp valid numbers and fall back to the default for anything else.\n const observerThreshold = Number.isFinite(threshold)\n ? Math.min(Math.max(threshold, 0), 1)\n : 0.15;\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- flips to true once mounted on the client so SSR/first-paint markup matches the server\n setIsMounted(true);\n }, []);\n\n useEffect(() => {\n if (prefersReducedMotion) {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- reduced motion skips straight to the revealed state\n setIsRevealed(true);\n return undefined;\n }\n\n if (typeof IntersectionObserver === 'undefined') {\n setIsRevealed(true);\n return undefined;\n }\n\n // The ref callback attaches after this effect's first pass; it re-runs\n // once `node` becomes available since it's a dependency.\n if (!node) return undefined;\n\n const observer = new IntersectionObserver(\n ([entry]) => {\n if (entry.isIntersecting) {\n setIsRevealed(true);\n if (once) observer.unobserve(node);\n } else if (!once) {\n setIsRevealed(false);\n }\n },\n { threshold: observerThreshold }\n );\n\n observer.observe(node);\n return () => observer.disconnect();\n }, [node, prefersReducedMotion, once, observerThreshold]);\n\n // Only apply the hidden/animating state once mounted on the client with\n // motion allowed; otherwise render the final, visible state (SSR-safe).\n const isAnimated = isMounted && !prefersReducedMotion;\n const revealed = !isAnimated || isRevealed;\n\n const itemAnimationClasses = prefixedClassNames(classPrefix, {\n [`reveal-${animation}`]: isAnimated,\n 'is-revealed': revealed,\n });\n\n const combinedClasses = classNames(\n usePrefixedClassNames('reveal', { 'is-cascade': cascade }),\n !cascade && itemAnimationClasses,\n bulmaHelperClasses,\n className\n );\n\n const wrapperStyle: React.CSSProperties = cascade\n ? { ...style }\n : {\n ...style,\n transitionDelay: `${delay}ms`,\n transitionDuration: `${duration}ms`,\n };\n\n const content = cascade\n ? Children.toArray(children).map((child, index) => {\n const itemStyle: React.CSSProperties = {\n transitionDelay: `${delay + index * cascadeInterval}ms`,\n transitionDuration: `${duration}ms`,\n };\n\n if (\n isValidElement<{ className?: string; style?: React.CSSProperties }>(\n child\n )\n ) {\n return cloneElement(child, {\n // Children.toArray always assigns a key, generating one from\n // the position when the element doesn't already have one.\n key: child.key,\n className: classNames(itemAnimationClasses, child.props.className),\n style: { ...itemStyle, ...child.props.style },\n });\n }\n\n return (\n <span key={index} className={itemAnimationClasses} style={itemStyle}>\n {child}\n </span>\n );\n })\n : children;\n\n // Scroll observation needs a DOM node this component OWNS — the observer and\n // the animation classes both key off it. An intrinsic tag is that node, so\n // the ref goes straight on it. A component passed via `as` is not: whatever\n // it renders is its own business, and it may render several elements or\n // none. So it gets wrapped in an observed `div`.\n //\n // Not a statement about ref forwarding. Several components in this library\n // forward refs (#641 added four more), and that changes nothing here — a\n // forwarded ref would still point at the target's node rather than at one\n // this component controls.\n if (typeof Component === 'string') {\n // A plain createElement call sidesteps the combinatorial JSX prop types\n // for `ref` across every possible intrinsic tag `as` could be.\n return React.createElement(\n Component,\n {\n ...rest,\n ref: setNode,\n className: combinedClasses,\n style: wrapperStyle,\n },\n content\n );\n }\n\n return (\n <div ref={setNode} className={combinedClasses} style={wrapperStyle}>\n <Component {...rest}>{content}</Component>\n </div>\n );\n}\n\nexport const Reveal = RevealImpl as PolymorphicComponentWithoutRef<\n RevealOwnProps,\n 'div'\n>;\n\nReveal.displayName = 'Reveal';\n\nexport default Reveal;\n"],"names":["_jsx"],"mappings":"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"}