@allxsmith/bestax-bulma 5.26.6 → 5.27.1

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 (342) 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 +89 -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 +87 -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 +76 -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 +87 -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 +153 -0
  154. package/dist/esm/form/Field.js.map +1 -0
  155. package/dist/esm/form/File.js +109 -0
  156. package/dist/esm/form/File.js.map +1 -0
  157. package/dist/esm/form/FormContext.js +170 -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 +199 -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 +91 -0
  168. package/dist/esm/form/Radios.js.map +1 -0
  169. package/dist/esm/form/Rate.js +279 -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 +459 -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 +352 -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 +83 -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 +54 -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 +821 -102
  294. package/dist/index.cjs.map +1 -1
  295. package/dist/index.esm.js +115 -16845
  296. package/dist/index.esm.js.map +1 -1
  297. package/dist/types/components/Tabs.d.ts +25 -3
  298. package/dist/types/elements/Icon.d.ts +10 -7
  299. package/dist/types/form/DateInputBase.d.ts +8 -6
  300. package/dist/types/form/DateRangeInput.d.ts +91 -0
  301. package/dist/types/form/DateRangeInputBase.d.ts +172 -0
  302. package/dist/types/form/DateTimeInputBase.d.ts +10 -6
  303. package/dist/types/form/File.d.ts +18 -5
  304. package/dist/types/form/FormContext.d.ts +11 -0
  305. package/dist/types/form/TimeInputBase.d.ts +1 -1
  306. package/dist/types/form/_pickerInternals/PickerPopover.d.ts +1 -0
  307. package/dist/types/form/_pickerInternals/dateUtils.d.ts +7 -0
  308. package/dist/types/form/_pickerInternals/formatters.d.ts +14 -0
  309. package/dist/types/form/_pickerInternals/pickerTypes.d.ts +13 -0
  310. package/dist/types/form/_pickerInternals/useSegmentedEntry.d.ts +12 -3
  311. package/dist/types/index.d.ts +4 -0
  312. package/dist/types-cjs/components/Tabs.d.ts +25 -3
  313. package/dist/types-cjs/elements/Icon.d.ts +10 -7
  314. package/dist/types-cjs/form/DateInputBase.d.ts +8 -6
  315. package/dist/types-cjs/form/DateRangeInput.d.ts +91 -0
  316. package/dist/types-cjs/form/DateRangeInputBase.d.ts +172 -0
  317. package/dist/types-cjs/form/DateTimeInputBase.d.ts +10 -6
  318. package/dist/types-cjs/form/File.d.ts +18 -5
  319. package/dist/types-cjs/form/FormContext.d.ts +11 -0
  320. package/dist/types-cjs/form/TimeInputBase.d.ts +1 -1
  321. package/dist/types-cjs/form/_pickerInternals/PickerPopover.d.ts +1 -0
  322. package/dist/types-cjs/form/_pickerInternals/dateUtils.d.ts +7 -0
  323. package/dist/types-cjs/form/_pickerInternals/formatters.d.ts +14 -0
  324. package/dist/types-cjs/form/_pickerInternals/pickerTypes.d.ts +13 -0
  325. package/dist/types-cjs/form/_pickerInternals/useSegmentedEntry.d.ts +12 -3
  326. package/dist/types-cjs/index.d.ts +4 -0
  327. package/dist/versions/bestax-no-dark-mode.css +1 -1
  328. package/dist/versions/bestax-no-dark-mode.css.map +1 -1
  329. package/dist/versions/bestax-no-helpers-prefixed.css +1 -1
  330. package/dist/versions/bestax-no-helpers-prefixed.css.map +1 -1
  331. package/dist/versions/bestax-no-helpers.css +1 -1
  332. package/dist/versions/bestax-no-helpers.css.map +1 -1
  333. package/dist/versions/bestax-prefixed.css +1 -1
  334. package/dist/versions/bestax-prefixed.css.map +1 -1
  335. package/package.json +1 -1
  336. package/src/scss/components/_tabs.scss +44 -0
  337. package/src/scss/form/_dateinput.scss +87 -8
  338. package/src/scss/form/_daterangeinput.scss +63 -0
  339. package/src/scss/form/_datetimeinput.scss +7 -2
  340. package/src/scss/form/_file.scss +37 -0
  341. package/src/scss/form/_index.scss +2 -0
  342. package/src/scss/form/_picker-popover.scss +1 -4
@@ -0,0 +1,199 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { forwardRef, useState, useRef, useCallback } from 'react';
4
+ import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
5
+ import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
6
+ import { useInsideField, useInsideControl } from './FormContext.js';
7
+ import { Field } from './Field.js';
8
+ import { useAutoLabelId } from './useAutoLabelId.js';
9
+
10
+ const ArrowDropUp = () => (jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: jsx("path", { d: "M7 14.5l5-5 5 5" }) }));
11
+ const ArrowDropDown = () => (jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: jsx("path", { d: "M7 9.5l5 5 5-5" }) }));
12
+ /**
13
+ * The `Numberinput` component provides a number input with increment/decrement buttons.
14
+ *
15
+ * @function
16
+ * @param {NumberinputProps} props - Props for the Numberinput component.
17
+ * @returns {JSX.Element} The rendered numeric input element.
18
+ *
19
+ * @example
20
+ * // Basic number input
21
+ * <Numberinput defaultValue={5} min={0} max={100} />
22
+ *
23
+ * @example
24
+ * // Stepper variant with color
25
+ * <Numberinput variant="stepper" color="primary" step={10} />
26
+ */
27
+ const Numberinput = forwardRef(({
28
+ // Field props
29
+ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, value: controlledValue, defaultValue, min, max, step = 1, size, color, inputColor, controlsPosition = 'both', controlsRounded = false, compact = false, bare, variant = 'plusminus', disabled = false, editable = true, isLoading = false, exponential = false, onChange, className, ...props }, ref) => {
30
+ const insideField = useInsideField();
31
+ // Bare controls join their parent's row, which a `.control` does not lay
32
+ // out. `useInsideControl()` is true anywhere below a `Control`, even past
33
+ // a `Field` nested in it, so there they keep their own row as well.
34
+ const insideControl = useInsideControl();
35
+ const effectiveBare = bare ?? (insideField && !insideControl);
36
+ const { bulmaHelperClasses, rest } = useBulmaClasses(props);
37
+ const [internalValue, setInternalValue] = useState(defaultValue);
38
+ const inputRef = useRef(null);
39
+ // Determine if controlled
40
+ const isControlled = controlledValue !== undefined;
41
+ const currentValue = isControlled ? controlledValue : internalValue;
42
+ // Layout mode
43
+ const isStepper = variant === 'stepper';
44
+ const isAddons = compact || isStepper;
45
+ const effectiveControlsPosition = isStepper ? 'right' : controlsPosition;
46
+ // The plusminus bare branch renders no Field and no label at all.
47
+ const { controlId, fieldLabelProps } = useAutoLabelId({
48
+ label,
49
+ id: props.id,
50
+ labelProps,
51
+ rendersLabel: !insideField && (isStepper || !effectiveBare),
52
+ });
53
+ // Clamp value to min/max
54
+ const clampValue = useCallback((val) => {
55
+ let clamped = val;
56
+ if (min !== undefined && clamped < min)
57
+ clamped = min;
58
+ if (max !== undefined && clamped > max)
59
+ clamped = max;
60
+ return clamped;
61
+ }, [min, max]);
62
+ // Update value
63
+ const updateValue = useCallback((newValue) => {
64
+ const clampedValue = clampValue(newValue);
65
+ if (!isControlled) {
66
+ setInternalValue(clampedValue);
67
+ }
68
+ onChange?.(clampedValue);
69
+ }, [isControlled, clampValue, onChange]);
70
+ // Exponential step: step grows with value magnitude
71
+ const getEffectiveStep = useCallback(() => {
72
+ if (!exponential)
73
+ return step;
74
+ return step * Math.max(1, Math.floor(Math.abs(currentValue ?? 0)));
75
+ }, [exponential, step, currentValue]);
76
+ // Handle increment
77
+ const handleIncrement = useCallback(() => {
78
+ updateValue((currentValue ?? 0) + getEffectiveStep());
79
+ }, [currentValue, getEffectiveStep, updateValue]);
80
+ // Handle decrement
81
+ const handleDecrement = useCallback(() => {
82
+ updateValue((currentValue ?? 0) - getEffectiveStep());
83
+ }, [currentValue, getEffectiveStep, updateValue]);
84
+ // Handle input change
85
+ const handleInputChange = useCallback((e) => {
86
+ const newValue = parseFloat(e.target.value);
87
+ if (!isNaN(newValue)) {
88
+ updateValue(newValue);
89
+ }
90
+ }, [updateValue]);
91
+ // Handle keyboard
92
+ const handleKeyDown = useCallback((e) => {
93
+ if (e.key === 'ArrowUp') {
94
+ e.preventDefault();
95
+ handleIncrement();
96
+ }
97
+ else if (e.key === 'ArrowDown') {
98
+ e.preventDefault();
99
+ handleDecrement();
100
+ }
101
+ }, [handleIncrement, handleDecrement]);
102
+ // Check if at limits
103
+ const isAtMin = min !== undefined && currentValue !== undefined && currentValue <= min;
104
+ const isAtMax = max !== undefined && currentValue !== undefined && currentValue >= max;
105
+ // Generate classes
106
+ const fieldClasses = usePrefixedClassNames('field', {
107
+ 'is-grouped': !isAddons,
108
+ 'has-addons': isAddons,
109
+ });
110
+ const numberinputClasses = usePrefixedClassNames('numberinput', {
111
+ 'is-compact': isAddons,
112
+ 'is-stepper': isStepper,
113
+ [`is-${size}`]: !!size,
114
+ 'is-disabled': disabled,
115
+ [`controls-${effectiveControlsPosition}`]: effectiveControlsPosition !== 'both',
116
+ });
117
+ const controlClasses = usePrefixedClassNames('control');
118
+ const expandedControlClasses = usePrefixedClassNames('control', {
119
+ 'is-expanded': true,
120
+ 'is-loading': isLoading,
121
+ });
122
+ const buttonClasses = usePrefixedClassNames('button', {
123
+ [`is-${size}`]: !!size,
124
+ [`is-${color}`]: !!color,
125
+ 'is-rounded': controlsRounded,
126
+ });
127
+ const inputClasses = usePrefixedClassNames('input', {
128
+ [`is-${size}`]: !!size,
129
+ [`is-${inputColor}`]: !!inputColor,
130
+ });
131
+ const iconClasses = usePrefixedClassNames('icon', 'is-small');
132
+ const stepperClasses = usePrefixedClassNames('numberinput-stepper');
133
+ const stepperButtonClasses = usePrefixedClassNames('numberinput-stepper-button');
134
+ const combinedClasses = classNames(fieldClasses, numberinputClasses, bulmaHelperClasses, className);
135
+ const helpClass = usePrefixedClassNames('help', {
136
+ [`is-${messageColor}`]: !!messageColor,
137
+ });
138
+ const messageEl = message ? jsx("p", { className: helpClass, children: message }) : null;
139
+ // Use combined ref
140
+ const combinedRef = (node) => {
141
+ inputRef.current =
142
+ node;
143
+ if (typeof ref === 'function') {
144
+ ref(node);
145
+ }
146
+ else if (ref) {
147
+ ref.current = node;
148
+ }
149
+ };
150
+ // Shared input element
151
+ const inputControl = (jsx("div", { className: expandedControlClasses, children: jsx("input", { ref: combinedRef, type: "number", className: inputClasses, value: currentValue ?? '', min: min, max: max, step: step, disabled: disabled, readOnly: !editable, onChange: handleInputChange, onKeyDown: handleKeyDown, "aria-valuenow": currentValue ?? undefined, "aria-valuemin": min, "aria-valuemax": max, id: controlId, ...rest }) }));
152
+ // Stepper variant
153
+ if (isStepper) {
154
+ const stepperElement = (jsxs("div", { className: combinedClasses, children: [inputControl, jsx("div", { className: controlClasses, children: jsxs("div", { className: stepperClasses, children: [jsx("button", { type: "button", className: stepperButtonClasses, onClick: handleIncrement, disabled: disabled || isAtMax, tabIndex: -1, "aria-label": "Increase value", children: jsx(ArrowDropUp, {}) }), jsx("button", { type: "button", className: stepperButtonClasses, onClick: handleDecrement, disabled: disabled || isAtMin, tabIndex: -1, "aria-label": "Decrease value", children: jsx(ArrowDropDown, {}) })] }) })] }));
155
+ if (!insideField) {
156
+ return (jsxs(Field, { label: label, labelSize: labelSize, labelProps: fieldLabelProps, horizontal: horizontal, className: fieldClassName, children: [stepperElement, messageEl] }));
157
+ }
158
+ return (jsxs(Fragment, { children: [stepperElement, messageEl] }));
159
+ }
160
+ // Plusminus buttons
161
+ const decrementButton = (jsx("button", { type: "button", className: buttonClasses, onClick: handleDecrement, disabled: disabled || isAtMin, tabIndex: -1, "aria-label": "Decrease value", children: jsx("span", { className: iconClasses, children: jsx("span", { "aria-hidden": "true", children: "\u2212" }) }) }));
162
+ const incrementButton = (jsx("button", { type: "button", className: buttonClasses, onClick: handleIncrement, disabled: disabled || isAtMax, tabIndex: -1, "aria-label": "Increase value", children: jsx("span", { className: iconClasses, children: jsx("span", { "aria-hidden": "true", children: "+" }) }) }));
163
+ const decrementControl = (jsx("div", { className: controlClasses, children: decrementButton }));
164
+ const incrementControl = (jsx("div", { className: controlClasses, children: incrementButton }));
165
+ // Bare mode: no outer .field wrapper, for composing inside a parent Field
166
+ if (effectiveBare) {
167
+ const bareClasses = classNames(numberinputClasses, bulmaHelperClasses, className);
168
+ if (effectiveControlsPosition === 'left') {
169
+ return (jsxs("div", { className: bareClasses, style: { display: 'contents' }, children: [decrementControl, incrementControl, inputControl] }));
170
+ }
171
+ if (effectiveControlsPosition === 'right') {
172
+ return (jsxs("div", { className: bareClasses, style: { display: 'contents' }, children: [inputControl, decrementControl, incrementControl] }));
173
+ }
174
+ return (jsxs("div", { className: bareClasses, style: { display: 'contents' }, children: [decrementControl, inputControl, incrementControl] }));
175
+ }
176
+ // Controls left: [−] [+] [input]
177
+ let numberinputElement;
178
+ if (effectiveControlsPosition === 'left') {
179
+ numberinputElement = (jsxs("div", { className: combinedClasses, children: [decrementControl, incrementControl, inputControl] }));
180
+ }
181
+ else if (effectiveControlsPosition === 'right') {
182
+ // Controls right: [input] [−] [+]
183
+ numberinputElement = (jsxs("div", { className: combinedClasses, children: [inputControl, decrementControl, incrementControl] }));
184
+ }
185
+ else {
186
+ // Both sides (default): [−] [input] [+]
187
+ numberinputElement = (jsxs("div", { className: combinedClasses, children: [decrementControl, inputControl, incrementControl] }));
188
+ }
189
+ if (!insideField) {
190
+ return (jsxs(Field, { label: label, labelSize: labelSize, labelProps: fieldLabelProps, horizontal: horizontal, className: fieldClassName, children: [numberinputElement, messageEl] }));
191
+ }
192
+ return (jsxs(Fragment, { children: [numberinputElement, messageEl] }));
193
+ });
194
+ Numberinput.displayName = 'Numberinput';
195
+ /** @deprecated Use `Numberinput` — same component. */
196
+ const NumberInput = Numberinput;
197
+
198
+ export { NumberInput, Numberinput };
199
+ //# sourceMappingURL=Numberinput.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Numberinput.js","sources":["../../../src/form/Numberinput.tsx"],"sourcesContent":["import React, { forwardRef, useState, useCallback, useRef } from 'react';\nimport type { JSX } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useInsideField, useInsideControl } from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\n\n/** Valid sizes for the Numberinput component. */\nexport type NumberinputSize = 'small' | 'medium' | 'large';\n\n/** Valid colors for the Numberinput wrapper and control buttons. */\nexport type NumberinputColor =\n | 'primary'\n | 'link'\n | 'info'\n | 'success'\n | 'warning'\n | 'danger'\n | 'light'\n | 'dark';\n\n/** Valid colors for the Numberinput inner input element. */\nexport type NumberinputInputColor =\n 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n\n/** Position of the increment/decrement control buttons. */\nexport type NumberinputControlsPosition = 'left' | 'right' | 'both';\n\n/** Visual variant for the Numberinput controls. */\nexport type NumberinputVariant = 'plusminus' | 'stepper';\n\n/**\n * Props for the Numberinput component.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLElement>} [ref] - Ref forwarded to the input element.\n */\nexport interface NumberinputProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'color' | 'size' | 'onChange' | 'value' | 'defaultValue' | 'type'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'>,\n FormFieldProps {\n /** Field label. Automatically associated with the number input via `htmlFor` — uses your `id` when provided, otherwise a generated one. Not wired when no Field wrapper is rendered (inside a `Field`, or plusminus `bare`). */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (no id is generated then). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Controlled value. */\n value?: number;\n /** Default value for uncontrolled usage. */\n defaultValue?: number;\n /** Minimum allowed value. */\n min?: number;\n /** Maximum allowed value. */\n max?: number;\n /** Step increment (default: 1). */\n step?: number;\n /** Size variant. */\n size?: NumberinputSize;\n /** Color variant for buttons. */\n color?: NumberinputColor;\n /** Color of the input field itself. */\n inputColor?: NumberinputInputColor;\n /** Position of +/- buttons. */\n controlsPosition?: NumberinputControlsPosition;\n /** Use rounded buttons. */\n controlsRounded?: boolean;\n /** Uses compact button spacing. */\n compact?: boolean;\n /**\n * Renders the plusminus controls without a `.field` row of their own, so\n * they join the row of a `Field` with `hasAddons` or `grouped` they sit\n * in. On by default inside a `Field`, unless a `Control` is anywhere above\n * it: a `Control` stacks its children, so there the controls keep their\n * own row.\n * @defaultValue auto\n */\n bare?: boolean;\n /** Style variant for the control buttons. */\n variant?: NumberinputVariant;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /** Whether the input can be typed in. */\n editable?: boolean;\n /**\n * Shows a loading spinner on the input's control.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n * Use this rather than `isLoading` on a `Control` around the Numberinput:\n * that spinner sits at the `Control`'s right edge, on top of whichever\n * button is there, while this one stays inside the input.\n */\n isLoading?: boolean;\n /** Enables exponential step increments when holding buttons. */\n exponential?: boolean;\n /** Callback when value changes. */\n onChange?: (value: number) => void;\n}\n\nconst ArrowDropUp = () => (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M7 14.5l5-5 5 5\" />\n </svg>\n);\n\nconst ArrowDropDown = () => (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2.5\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M7 9.5l5 5 5-5\" />\n </svg>\n);\n\n/**\n * The `Numberinput` component provides a number input with increment/decrement buttons.\n *\n * @function\n * @param {NumberinputProps} props - Props for the Numberinput component.\n * @returns {JSX.Element} The rendered numeric input element.\n *\n * @example\n * // Basic number input\n * <Numberinput defaultValue={5} min={0} max={100} />\n *\n * @example\n * // Stepper variant with color\n * <Numberinput variant=\"stepper\" color=\"primary\" step={10} />\n */\nexport const Numberinput = forwardRef<HTMLInputElement, NumberinputProps>(\n (\n {\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n value: controlledValue,\n defaultValue,\n min,\n max,\n step = 1,\n size,\n color,\n inputColor,\n controlsPosition = 'both',\n controlsRounded = false,\n compact = false,\n bare,\n variant = 'plusminus',\n disabled = false,\n editable = true,\n isLoading = false,\n exponential = false,\n onChange,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n // Bare controls join their parent's row, which a `.control` does not lay\n // out. `useInsideControl()` is true anywhere below a `Control`, even past\n // a `Field` nested in it, so there they keep their own row as well.\n const insideControl = useInsideControl();\n const effectiveBare = bare ?? (insideField && !insideControl);\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const [internalValue, setInternalValue] = useState<number | undefined>(\n defaultValue\n );\n const inputRef = useRef<HTMLInputElement>(null);\n\n // Determine if controlled\n const isControlled = controlledValue !== undefined;\n const currentValue = isControlled ? controlledValue : internalValue;\n\n // Layout mode\n const isStepper = variant === 'stepper';\n const isAddons = compact || isStepper;\n const effectiveControlsPosition = isStepper ? 'right' : controlsPosition;\n\n // The plusminus bare branch renders no Field and no label at all.\n const { controlId, fieldLabelProps } = useAutoLabelId({\n label,\n id: props.id,\n labelProps,\n rendersLabel: !insideField && (isStepper || !effectiveBare),\n });\n\n // Clamp value to min/max\n const clampValue = useCallback(\n (val: number): number => {\n let clamped = val;\n if (min !== undefined && clamped < min) clamped = min;\n if (max !== undefined && clamped > max) clamped = max;\n return clamped;\n },\n [min, max]\n );\n\n // Update value\n const updateValue = useCallback(\n (newValue: number) => {\n const clampedValue = clampValue(newValue);\n if (!isControlled) {\n setInternalValue(clampedValue);\n }\n onChange?.(clampedValue);\n },\n [isControlled, clampValue, onChange]\n );\n\n // Exponential step: step grows with value magnitude\n const getEffectiveStep = useCallback(() => {\n if (!exponential) return step;\n return step * Math.max(1, Math.floor(Math.abs(currentValue ?? 0)));\n }, [exponential, step, currentValue]);\n\n // Handle increment\n const handleIncrement = useCallback(() => {\n updateValue((currentValue ?? 0) + getEffectiveStep());\n }, [currentValue, getEffectiveStep, updateValue]);\n\n // Handle decrement\n const handleDecrement = useCallback(() => {\n updateValue((currentValue ?? 0) - getEffectiveStep());\n }, [currentValue, getEffectiveStep, updateValue]);\n\n // Handle input change\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = parseFloat(e.target.value);\n if (!isNaN(newValue)) {\n updateValue(newValue);\n }\n },\n [updateValue]\n );\n\n // Handle keyboard\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'ArrowUp') {\n e.preventDefault();\n handleIncrement();\n } else if (e.key === 'ArrowDown') {\n e.preventDefault();\n handleDecrement();\n }\n },\n [handleIncrement, handleDecrement]\n );\n\n // Check if at limits\n const isAtMin =\n min !== undefined && currentValue !== undefined && currentValue <= min;\n const isAtMax =\n max !== undefined && currentValue !== undefined && currentValue >= max;\n\n // Generate classes\n const fieldClasses = usePrefixedClassNames('field', {\n 'is-grouped': !isAddons,\n 'has-addons': isAddons,\n });\n\n const numberinputClasses = usePrefixedClassNames('numberinput', {\n 'is-compact': isAddons,\n 'is-stepper': isStepper,\n [`is-${size}`]: !!size,\n 'is-disabled': disabled,\n [`controls-${effectiveControlsPosition}`]:\n effectiveControlsPosition !== 'both',\n });\n\n const controlClasses = usePrefixedClassNames('control');\n const expandedControlClasses = usePrefixedClassNames('control', {\n 'is-expanded': true,\n 'is-loading': isLoading,\n });\n\n const buttonClasses = usePrefixedClassNames('button', {\n [`is-${size}`]: !!size,\n [`is-${color}`]: !!color,\n 'is-rounded': controlsRounded,\n });\n\n const inputClasses = usePrefixedClassNames('input', {\n [`is-${size}`]: !!size,\n [`is-${inputColor}`]: !!inputColor,\n });\n\n const iconClasses = usePrefixedClassNames('icon', 'is-small');\n const stepperClasses = usePrefixedClassNames('numberinput-stepper');\n const stepperButtonClasses = usePrefixedClassNames(\n 'numberinput-stepper-button'\n );\n\n const combinedClasses = classNames(\n fieldClasses,\n numberinputClasses,\n bulmaHelperClasses,\n className\n );\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // Use combined ref\n const combinedRef = (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current = node;\n }\n };\n\n // Shared input element\n const inputControl = (\n <div className={expandedControlClasses}>\n <input\n ref={combinedRef}\n type=\"number\"\n className={inputClasses}\n value={currentValue ?? ''}\n min={min}\n max={max}\n step={step}\n disabled={disabled}\n readOnly={!editable}\n onChange={handleInputChange}\n onKeyDown={handleKeyDown}\n aria-valuenow={currentValue ?? undefined}\n aria-valuemin={min}\n aria-valuemax={max}\n id={controlId}\n {...rest}\n />\n </div>\n );\n\n // Stepper variant\n if (isStepper) {\n const stepperElement = (\n <div className={combinedClasses}>\n {inputControl}\n <div className={controlClasses}>\n <div className={stepperClasses}>\n <button\n type=\"button\"\n className={stepperButtonClasses}\n onClick={handleIncrement}\n disabled={disabled || isAtMax}\n tabIndex={-1}\n aria-label=\"Increase value\"\n >\n <ArrowDropUp />\n </button>\n <button\n type=\"button\"\n className={stepperButtonClasses}\n onClick={handleDecrement}\n disabled={disabled || isAtMin}\n tabIndex={-1}\n aria-label=\"Decrease value\"\n >\n <ArrowDropDown />\n </button>\n </div>\n </div>\n </div>\n );\n\n if (!insideField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {stepperElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {stepperElement}\n {messageEl}\n </>\n );\n }\n\n // Plusminus buttons\n const decrementButton = (\n <button\n type=\"button\"\n className={buttonClasses}\n onClick={handleDecrement}\n disabled={disabled || isAtMin}\n tabIndex={-1}\n aria-label=\"Decrease value\"\n >\n <span className={iconClasses}>\n <span aria-hidden=\"true\">&minus;</span>\n </span>\n </button>\n );\n\n const incrementButton = (\n <button\n type=\"button\"\n className={buttonClasses}\n onClick={handleIncrement}\n disabled={disabled || isAtMax}\n tabIndex={-1}\n aria-label=\"Increase value\"\n >\n <span className={iconClasses}>\n <span aria-hidden=\"true\">+</span>\n </span>\n </button>\n );\n\n const decrementControl = (\n <div className={controlClasses}>{decrementButton}</div>\n );\n const incrementControl = (\n <div className={controlClasses}>{incrementButton}</div>\n );\n\n // Bare mode: no outer .field wrapper, for composing inside a parent Field\n if (effectiveBare) {\n const bareClasses = classNames(\n numberinputClasses,\n bulmaHelperClasses,\n className\n );\n\n if (effectiveControlsPosition === 'left') {\n return (\n <div className={bareClasses} style={{ display: 'contents' }}>\n {decrementControl}\n {incrementControl}\n {inputControl}\n </div>\n );\n }\n\n if (effectiveControlsPosition === 'right') {\n return (\n <div className={bareClasses} style={{ display: 'contents' }}>\n {inputControl}\n {decrementControl}\n {incrementControl}\n </div>\n );\n }\n\n return (\n <div className={bareClasses} style={{ display: 'contents' }}>\n {decrementControl}\n {inputControl}\n {incrementControl}\n </div>\n );\n }\n\n // Controls left: [−] [+] [input]\n let numberinputElement: JSX.Element;\n if (effectiveControlsPosition === 'left') {\n numberinputElement = (\n <div className={combinedClasses}>\n {decrementControl}\n {incrementControl}\n {inputControl}\n </div>\n );\n } else if (effectiveControlsPosition === 'right') {\n // Controls right: [input] [−] [+]\n numberinputElement = (\n <div className={combinedClasses}>\n {inputControl}\n {decrementControl}\n {incrementControl}\n </div>\n );\n } else {\n // Both sides (default): [−] [input] [+]\n numberinputElement = (\n <div className={combinedClasses}>\n {decrementControl}\n {inputControl}\n {incrementControl}\n </div>\n );\n }\n\n if (!insideField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {numberinputElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {numberinputElement}\n {messageEl}\n </>\n );\n }\n);\n\nNumberinput.displayName = 'Numberinput';\n\n/** @deprecated Use `Numberinput` — same component. */\nexport const NumberInput = Numberinput;\n\n/** @deprecated Use `NumberinputProps`. */\nexport type NumberInputProps = NumberinputProps;\n\nexport default Numberinput;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
@@ -0,0 +1,108 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { forwardRef, useCallback } from 'react';
4
+ import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
5
+ import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
6
+ import { useRadiosGroup } from './FormContext.js';
7
+
8
+ /**
9
+ * The values the Radio `color` prop accepts, as a readonly tuple.
10
+ *
11
+ * `RadioProps['color']` is typed from it, so the two list the same values.
12
+ * Map over it to build a color picker, or check a value that arrives at
13
+ * runtime before passing it in: the component adds no color class for a value
14
+ * outside the tuple.
15
+ *
16
+ * @example
17
+ * import { Radio, Radios, radioColors } from '@allxsmith/bestax-bulma';
18
+ *
19
+ * <Radios name="accent" defaultValue="primary">
20
+ * {radioColors.map(color => (
21
+ * <Radio key={color} value={color} color={color}>
22
+ * {color}
23
+ * </Radio>
24
+ * ))}
25
+ * </Radios>;
26
+ */
27
+ const radioColors = [
28
+ 'primary',
29
+ 'link',
30
+ 'info',
31
+ 'success',
32
+ 'warning',
33
+ 'danger',
34
+ ];
35
+ /**
36
+ * The values the Radio `size` prop accepts, as a readonly tuple.
37
+ *
38
+ * `RadioProps['size']` is typed from it, so the two list the same values. Use
39
+ * it to offer a size choice or to check a value that arrives at runtime: the
40
+ * component adds no size class for a value outside the tuple. These are
41
+ * element sizes, not the spacing scale in `validSizes`.
42
+ *
43
+ * @example
44
+ * import { radioSizes } from '@allxsmith/bestax-bulma';
45
+ *
46
+ * type RadioSize = (typeof radioSizes)[number];
47
+ */
48
+ const radioSizes = ['small', 'normal', 'medium', 'large'];
49
+ /**
50
+ * The `Radio` component provides a Bulma-styled radio button input with flexible labels and helper classes.
51
+ *
52
+ * @function
53
+ * @param {RadioProps} props - Props for the Radio component.
54
+ * @returns {JSX.Element} The rendered radio element.
55
+ *
56
+ * @example
57
+ * // Basic radio
58
+ * <Radio name="option">Option A</Radio>
59
+ *
60
+ * @example
61
+ * // Inside a group
62
+ * <Radios name="color" defaultValue="red">
63
+ * <Radio value="red">Red</Radio>
64
+ * <Radio value="blue">Blue</Radio>
65
+ * </Radios>
66
+ */
67
+ const Radio = forwardRef(({ color, size, className, children, textColor, disabled, name, value, checked, defaultChecked, onChange, ...props }, ref) => {
68
+ const { bulmaHelperClasses, rest } = useBulmaClasses({
69
+ color: textColor,
70
+ ...props,
71
+ });
72
+ // Inherit name + selection state from a surrounding <Radios> group.
73
+ // Local props always win over the group (explicit > implicit).
74
+ const group = useRadiosGroup();
75
+ const effectiveName = name ?? group?.name;
76
+ // Group-managed checked state — only when the group is in
77
+ // controlled/uncontrolled mode (group.value is defined) AND this Radio
78
+ // has a value to compare against. Local `checked` always wins.
79
+ const groupManaged = group?.value !== undefined && value !== undefined;
80
+ const effectiveChecked = checked !== undefined
81
+ ? checked
82
+ : groupManaged
83
+ ? group.value === value
84
+ : undefined;
85
+ // When the group manages checked, suppress local defaultChecked to avoid
86
+ // the controlled/uncontrolled React warning.
87
+ const effectiveDefaultChecked = groupManaged ? undefined : defaultChecked;
88
+ const handleChange = useCallback((e) => {
89
+ // Local onChange always fires.
90
+ onChange?.(e);
91
+ // Dispatch to the group additionally — keeps group state in sync.
92
+ if (group?.onChange && value !== undefined) {
93
+ group.onChange(String(value));
94
+ }
95
+ }, [onChange, group, value]);
96
+ const mainClass = usePrefixedClassNames('styled-radio', 'radio', {
97
+ [`is-${color}`]: color && radioColors.includes(color),
98
+ [`is-${size}`]: size && radioSizes.includes(size),
99
+ });
100
+ const radioClass = classNames(mainClass, bulmaHelperClasses, className);
101
+ const checkClass = usePrefixedClassNames('check');
102
+ const controlLabelClass = usePrefixedClassNames('control-label');
103
+ return (jsxs("label", { className: radioClass, children: [jsx("input", { ref: ref, type: "radio", disabled: disabled, name: effectiveName, value: value, checked: effectiveChecked, defaultChecked: effectiveDefaultChecked, onChange: handleChange, ...rest }), jsx("span", { className: checkClass }), children && jsx("span", { className: controlLabelClass, children: children })] }));
104
+ });
105
+ Radio.displayName = 'Radio';
106
+
107
+ export { Radio, radioColors, radioSizes };
108
+ //# sourceMappingURL=Radio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Radio.js","sources":["../../../src/form/Radio.tsx"],"sourcesContent":["import React, { forwardRef, useCallback } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport {\n useBulmaClasses,\n BulmaClassesProps,\n validColors,\n} from '../helpers/useBulmaClasses';\nimport { useRadiosGroup } from './FormContext';\n\n/**\n * The values the Radio `color` prop accepts, as a readonly tuple.\n *\n * `RadioProps['color']` is typed from it, so the two list the same values.\n * Map over it to build a color picker, or check a value that arrives at\n * runtime before passing it in: the component adds no color class for a value\n * outside the tuple.\n *\n * @example\n * import { Radio, Radios, radioColors } from '@allxsmith/bestax-bulma';\n *\n * <Radios name=\"accent\" defaultValue=\"primary\">\n * {radioColors.map(color => (\n * <Radio key={color} value={color} color={color}>\n * {color}\n * </Radio>\n * ))}\n * </Radios>;\n */\nexport const radioColors = [\n 'primary',\n 'link',\n 'info',\n 'success',\n 'warning',\n 'danger',\n] as const;\n\n/**\n * The values the Radio `size` prop accepts, as a readonly tuple.\n *\n * `RadioProps['size']` is typed from it, so the two list the same values. Use\n * it to offer a size choice or to check a value that arrives at runtime: the\n * component adds no size class for a value outside the tuple. These are\n * element sizes, not the spacing scale in `validSizes`.\n *\n * @example\n * import { radioSizes } from '@allxsmith/bestax-bulma';\n *\n * type RadioSize = (typeof radioSizes)[number];\n */\nexport const radioSizes = ['small', 'normal', 'medium', 'large'] as const;\n\n/**\n * Props for the Radio component.\n */\nexport interface RadioProps\n extends\n Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n 'size' | 'type' | 'color'\n >,\n Omit<BulmaClassesProps, 'color' | 'backgroundColor' | 'size'> {\n /** Color of the radio button. */\n color?: (typeof radioColors)[number];\n /** Size of the radio button. */\n size?: (typeof radioSizes)[number];\n /** Text color helper. */\n textColor?: (typeof validColors)[number] | 'inherit' | 'current';\n /** Whether the radio is disabled. */\n disabled?: boolean;\n /** Additional CSS classes to apply. */\n className?: string;\n /** The label/content for the radio. */\n children?: React.ReactNode;\n}\n\n/**\n * The `Radio` component provides a Bulma-styled radio button input with flexible labels and helper classes.\n *\n * @function\n * @param {RadioProps} props - Props for the Radio component.\n * @returns {JSX.Element} The rendered radio element.\n *\n * @example\n * // Basic radio\n * <Radio name=\"option\">Option A</Radio>\n *\n * @example\n * // Inside a group\n * <Radios name=\"color\" defaultValue=\"red\">\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"blue\">Blue</Radio>\n * </Radios>\n */\nexport const Radio = forwardRef<HTMLInputElement, RadioProps>(\n (\n {\n color,\n size,\n className,\n children,\n textColor,\n disabled,\n name,\n value,\n checked,\n defaultChecked,\n onChange,\n ...props\n },\n ref\n ) => {\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n color: textColor,\n ...props,\n });\n\n // Inherit name + selection state from a surrounding <Radios> group.\n // Local props always win over the group (explicit > implicit).\n const group = useRadiosGroup();\n const effectiveName = name ?? group?.name;\n\n // Group-managed checked state — only when the group is in\n // controlled/uncontrolled mode (group.value is defined) AND this Radio\n // has a value to compare against. Local `checked` always wins.\n const groupManaged = group?.value !== undefined && value !== undefined;\n const effectiveChecked =\n checked !== undefined\n ? checked\n : groupManaged\n ? group!.value === value\n : undefined;\n // When the group manages checked, suppress local defaultChecked to avoid\n // the controlled/uncontrolled React warning.\n const effectiveDefaultChecked = groupManaged ? undefined : defaultChecked;\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n // Local onChange always fires.\n onChange?.(e);\n // Dispatch to the group additionally — keeps group state in sync.\n if (group?.onChange && value !== undefined) {\n group.onChange(String(value));\n }\n },\n [onChange, group, value]\n );\n\n const mainClass = usePrefixedClassNames('styled-radio', 'radio', {\n [`is-${color}`]: color && radioColors.includes(color),\n [`is-${size}`]: size && radioSizes.includes(size),\n });\n const radioClass = classNames(mainClass, bulmaHelperClasses, className);\n const checkClass = usePrefixedClassNames('check');\n const controlLabelClass = usePrefixedClassNames('control-label');\n\n return (\n <label className={radioClass}>\n <input\n ref={ref}\n type=\"radio\"\n disabled={disabled}\n name={effectiveName}\n value={value}\n checked={effectiveChecked}\n defaultChecked={effectiveDefaultChecked}\n onChange={handleChange}\n {...rest}\n />\n <span className={checkClass} />\n {children && <span className={controlLabelClass}>{children}</span>}\n </label>\n );\n }\n);\n\nRadio.displayName = 'Radio';\n\nexport default Radio;\n"],"names":["_jsxs","_jsx"],"mappings":";;;;;;;AASA;;;;;;;;;;;;;;;;;;AAkBG;AACI,MAAM,WAAW,GAAG;IACzB,SAAS;IACT,MAAM;IACN,MAAM;IACN,SAAS;IACT,SAAS;IACT,QAAQ;;AAGV;;;;;;;;;;;;AAYG;AACI,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO;AA0B/D;;;;;;;;;;;;;;;;;AAiBG;AACI,MAAM,KAAK,GAAG,UAAU,CAC7B,CACE,EACE,KAAK,EACL,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,OAAO,EACP,cAAc,EACd,QAAQ,EACR,GAAG,KAAK,EACT,EACD,GAAG,KACD;AACF,IAAA,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC;AACnD,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,GAAG,KAAK;AACT,KAAA,CAAC;;;AAIF,IAAA,MAAM,KAAK,GAAG,cAAc,EAAE;AAC9B,IAAA,MAAM,aAAa,GAAG,IAAI,IAAI,KAAK,EAAE,IAAI;;;;IAKzC,MAAM,YAAY,GAAG,KAAK,EAAE,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS;AACtE,IAAA,MAAM,gBAAgB,GACpB,OAAO,KAAK;AACV,UAAE;AACF,UAAE;AACA,cAAE,KAAM,CAAC,KAAK,KAAK;cACjB,SAAS;;;IAGjB,MAAM,uBAAuB,GAAG,YAAY,GAAG,SAAS,GAAG,cAAc;AAEzE,IAAA,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,CAAsC,KAAI;;AAEzC,QAAA,QAAQ,GAAG,CAAC,CAAC;;QAEb,IAAI,KAAK,EAAE,QAAQ,IAAI,KAAK,KAAK,SAAS,EAAE;YAC1C,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B;IACF,CAAC,EACD,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CACzB;AAED,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,cAAc,EAAE,OAAO,EAAE;AAC/D,QAAA,CAAC,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,KAAK,IAAI,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC;AACrD,QAAA,CAAC,CAAA,GAAA,EAAM,IAAI,CAAA,CAAE,GAAG,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC;AAClD,KAAA,CAAC;IACF,MAAM,UAAU,GAAG,UAAU,CAAC,SAAS,EAAE,kBAAkB,EAAE,SAAS,CAAC;AACvE,IAAA,MAAM,UAAU,GAAG,qBAAqB,CAAC,OAAO,CAAC;AACjD,IAAA,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,eAAe,CAAC;IAEhE,QACEA,IAAA,CAAA,OAAA,EAAA,EAAO,SAAS,EAAE,UAAU,EAAA,QAAA,EAAA,CAC1BC,GAAA,CAAA,OAAA,EAAA,EACE,GAAG,EAAE,GAAG,EACR,IAAI,EAAC,OAAO,EACZ,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,gBAAgB,EACzB,cAAc,EAAE,uBAAuB,EACvC,QAAQ,EAAE,YAAY,EAAA,GAClB,IAAI,EAAA,CACR,EACFA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,UAAU,EAAA,CAAI,EAC9B,QAAQ,IAAIA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,iBAAiB,EAAA,QAAA,EAAG,QAAQ,EAAA,CAAQ,CAAA,EAAA,CAC5D;AAEZ,CAAC;AAGH,KAAK,CAAC,WAAW,GAAG,OAAO;;"}
@@ -0,0 +1,91 @@
1
+ /* @allxsmith/bestax-bulma — AI agents: see AGENTS.md in the package root, or https://bestax.io/llms.txt */
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { useState, useCallback, useMemo } from 'react';
4
+ import { usePrefixedClassNames, classNames } from '../helpers/classNames.js';
5
+ import { withSubComponents } from '../helpers/withSubComponents.js';
6
+ import { useBulmaClasses } from '../helpers/useBulmaClasses.js';
7
+ import { useInsideField, useInsideControl, rendersOwnField, RadiosProvider, rendersOwnControl } from './FormContext.js';
8
+ import { Field } from './Field.js';
9
+ import { Control } from './Control.js';
10
+ import { useAutoLabelledBy } from './useAutoLabelId.js';
11
+ import { Radio } from './Radio.js';
12
+
13
+ /**
14
+ * The `Radios` component wraps multiple `Radio` components in a Bulma-styled group.
15
+ *
16
+ * @function
17
+ * @param {RadiosProps} props - Props for the Radios component.
18
+ * @returns {JSX.Element} The rendered radios group.
19
+ * @see {@link https://bulma.io/documentation/form/radio/#grouped-radios | Bulma Radios documentation}
20
+ *
21
+ * @example
22
+ * // Controlled
23
+ * const [color, setColor] = useState('red');
24
+ * <Radios name="color" value={color} onChange={setColor}>
25
+ * <Radio value="red">Red</Radio>
26
+ * <Radio value="green">Green</Radio>
27
+ * <Radio value="blue">Blue</Radio>
28
+ * </Radios>
29
+ *
30
+ * @example
31
+ * // Uncontrolled
32
+ * <Radios name="color" defaultValue="red" onChange={v => console.log(v)}>
33
+ * <Radio value="red">Red</Radio>
34
+ * <Radio value="green">Green</Radio>
35
+ * </Radios>
36
+ */
37
+ const RadiosComponent = ({ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, name, value, defaultValue, onChange, children, className, ...props }) => {
38
+ const insideField = useInsideField();
39
+ const insideControl = useInsideControl();
40
+ const ownField = rendersOwnField('Radios', {
41
+ insideField,
42
+ insideControl,
43
+ label,
44
+ message,
45
+ horizontal,
46
+ fieldClassName,
47
+ });
48
+ const { ariaLabelledBy, fieldLabelProps } = useAutoLabelledBy({
49
+ label,
50
+ labelProps,
51
+ rendersLabel: ownField,
52
+ });
53
+ const { bulmaHelperClasses, rest } = useBulmaClasses({
54
+ ...props,
55
+ });
56
+ const mainClass = usePrefixedClassNames('radios');
57
+ const wrapperClass = classNames(mainClass, bulmaHelperClasses, className);
58
+ const helpClass = usePrefixedClassNames('help', {
59
+ [`is-${messageColor}`]: !!messageColor,
60
+ });
61
+ const messageEl = message ? jsx("p", { className: helpClass, children: message }) : null;
62
+ // The group is "active" (manages child selection) when the user opted in by
63
+ // passing value, defaultValue, or onChange. Otherwise it's name-only and
64
+ // children manage their own checked state (Stage 1 behavior).
65
+ const groupActive = value !== undefined || defaultValue !== undefined || onChange !== undefined;
66
+ const [internalValue, setInternalValue] = useState(defaultValue);
67
+ const isControlled = value !== undefined;
68
+ const currentValue = isControlled ? value : internalValue;
69
+ const handleChange = useCallback((newValue) => {
70
+ if (!isControlled)
71
+ setInternalValue(newValue);
72
+ onChange?.(newValue);
73
+ }, [isControlled, onChange]);
74
+ const ctx = useMemo(() => ({
75
+ name,
76
+ ...(groupActive ? { value: currentValue, onChange: handleChange } : {}),
77
+ }), [name, groupActive, currentValue, handleChange]);
78
+ const radiosElement = (jsx("div", { className: wrapperClass, role: "radiogroup", "aria-labelledby": ariaLabelledBy, ...rest, children: jsx(RadiosProvider, { value: ctx, children: children }) }));
79
+ let content = radiosElement;
80
+ if (rendersOwnControl('Radios', { insideControl })) {
81
+ content = jsx(Control, { children: content });
82
+ }
83
+ if (ownField) {
84
+ return (jsxs(Field, { label: label, labelSize: labelSize, labelProps: fieldLabelProps, horizontal: horizontal, className: fieldClassName, children: [content, messageEl] }));
85
+ }
86
+ return (jsxs(Fragment, { children: [content, messageEl] }));
87
+ };
88
+ const Radios = withSubComponents(RadiosComponent, { Radio }, 'Radios');
89
+
90
+ export { Radios };
91
+ //# sourceMappingURL=Radios.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Radios.js","sources":["../../../src/form/Radios.tsx"],"sourcesContent":["import React, { useCallback, useMemo, useState } from 'react';\nimport { classNames, usePrefixedClassNames } from '../helpers/classNames';\nimport { withSubComponents } from '../helpers/withSubComponents';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport {\n useInsideField,\n useInsideControl,\n rendersOwnField,\n rendersOwnControl,\n RadiosProvider,\n RadiosGroupContextValue,\n} from './FormContext';\nimport { Field } from './Field';\nimport { Control } from './Control';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelledBy } from './useAutoLabelId';\nimport { Radio } from './Radio';\n\n/**\n * Props for the Radios component.\n * Inside an existing `Control` it renders no `Control` of its own. Inside an\n * outer `Field`, or a `Control` with no `Field` around it, it renders no\n * `Field` of its own either. The exception is `label`, `message`, `horizontal`\n * or `fieldClassName` in that bare `Control`: it keeps a `Field` for them,\n * nested in the `.control`, and warns in development. Wrap the `Control` in a\n * `Field` instead, and set the `label`, `horizontal` and class name on that\n * `Field`.\n */\nexport interface RadiosProps\n extends Omit<BulmaClassesProps, 'color'>, FormFieldProps {\n /** Field label naming the whole group. Automatically associated via `aria-labelledby` on the `role=\"radiogroup\"` wrapper — uses your `labelProps.id` when provided, otherwise a generated one. Dropped inside an outer `Field` (label that `Field` yourself). */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `id` here is used as the `aria-labelledby` target instead of a generated one; any `htmlFor` is ignored (a group label names the group, never a single control). */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Additional CSS classes to apply. */\n className?: string;\n /** Form field name shared by every Radio in the group (via context). */\n name?: string;\n /** Currently-selected value (controlled mode). */\n value?: string;\n /** Initial selected value (uncontrolled mode). */\n defaultValue?: string;\n /** Fires when the selection changes. */\n onChange?: (value: string) => void;\n /** Radio elements to render in the group. */\n children: React.ReactNode;\n}\n\n/**\n * The `Radios` component wraps multiple `Radio` components in a Bulma-styled group.\n *\n * @function\n * @param {RadiosProps} props - Props for the Radios component.\n * @returns {JSX.Element} The rendered radios group.\n * @see {@link https://bulma.io/documentation/form/radio/#grouped-radios | Bulma Radios documentation}\n *\n * @example\n * // Controlled\n * const [color, setColor] = useState('red');\n * <Radios name=\"color\" value={color} onChange={setColor}>\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"green\">Green</Radio>\n * <Radio value=\"blue\">Blue</Radio>\n * </Radios>\n *\n * @example\n * // Uncontrolled\n * <Radios name=\"color\" defaultValue=\"red\" onChange={v => console.log(v)}>\n * <Radio value=\"red\">Red</Radio>\n * <Radio value=\"green\">Green</Radio>\n * </Radios>\n */\nconst RadiosComponent: React.FC<RadiosProps> = ({\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n name,\n value,\n defaultValue,\n onChange,\n children,\n className,\n ...props\n}) => {\n const insideField = useInsideField();\n const insideControl = useInsideControl();\n const ownField = rendersOwnField('Radios', {\n insideField,\n insideControl,\n label,\n message,\n horizontal,\n fieldClassName,\n });\n const { ariaLabelledBy, fieldLabelProps } = useAutoLabelledBy({\n label,\n labelProps,\n rendersLabel: ownField,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses({\n ...props,\n });\n\n const mainClass = usePrefixedClassNames('radios');\n const wrapperClass = classNames(mainClass, bulmaHelperClasses, className);\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // The group is \"active\" (manages child selection) when the user opted in by\n // passing value, defaultValue, or onChange. Otherwise it's name-only and\n // children manage their own checked state (Stage 1 behavior).\n const groupActive =\n value !== undefined || defaultValue !== undefined || onChange !== undefined;\n\n const [internalValue, setInternalValue] = useState<string | undefined>(\n defaultValue\n );\n const isControlled = value !== undefined;\n const currentValue = isControlled ? value : internalValue;\n\n const handleChange = useCallback(\n (newValue: string) => {\n if (!isControlled) setInternalValue(newValue);\n onChange?.(newValue);\n },\n [isControlled, onChange]\n );\n\n const ctx = useMemo<RadiosGroupContextValue>(\n () => ({\n name,\n ...(groupActive ? { value: currentValue, onChange: handleChange } : {}),\n }),\n [name, groupActive, currentValue, handleChange]\n );\n\n const radiosElement = (\n <div\n className={wrapperClass}\n role=\"radiogroup\"\n aria-labelledby={ariaLabelledBy}\n {...rest}\n >\n <RadiosProvider value={ctx}>{children}</RadiosProvider>\n </div>\n );\n\n let content = radiosElement;\n\n if (rendersOwnControl('Radios', { insideControl })) {\n content = <Control>{content}</Control>;\n }\n\n if (ownField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {content}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {content}\n {messageEl}\n </>\n );\n};\n\nexport const Radios = withSubComponents(RadiosComponent, { Radio }, 'Radios');\n\nexport default Radios;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}