@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
package/dist/index.cjs CHANGED
@@ -2447,7 +2447,9 @@ const DropdownComponent = React.forwardRef(function DropdownComponent({ label, c
2447
2447
  // Closing hides the item that has focus, and the browser drops focus
2448
2448
  // to the page when that happens. Hand it back to the trigger, as
2449
2449
  // Escape does. An item that moved focus somewhere else keeps it there.
2450
- if (e.currentTarget.contains(getActiveElementInTree(e.currentTarget))) {
2450
+ // The menu around this content is what a click between items focuses.
2451
+ const menu = e.currentTarget.parentElement;
2452
+ if (menu.contains(getActiveElementInTree(e.currentTarget))) {
2451
2453
  triggerRef.current?.focus();
2452
2454
  }
2453
2455
  }
@@ -2608,7 +2610,10 @@ const DropdownComponent = React.forwardRef(function DropdownComponent({ label, c
2608
2610
  }
2609
2611
  };
2610
2612
  const dropdownClasses = classNames(bulmaClasses, bulmaHelperClasses, className);
2611
- return (jsxRuntime.jsxs("div", { className: dropdownClasses, ref: setRefs, id: id, "data-testid": "dropdown-root", ...rest, children: [jsxRuntime.jsx("div", { className: usePrefixedClassNames('dropdown-trigger'), children: jsxRuntime.jsxs("button", { ref: triggerRef, className: buttonClass, "aria-haspopup": "true", "aria-controls": id ? `${id}-menu` : undefined, "aria-expanded": active, onClick: handleToggle, onKeyDown: handleTriggerKeyDown, disabled: disabled, type: "button", children: [jsxRuntime.jsx("span", { children: label }), jsxRuntime.jsx("span", { className: usePrefixedClassNames('icon', 'is-small'), "aria-hidden": "true", children: jsxRuntime.jsx("i", { className: "fas fa-angle-down" }) })] }) }), jsxRuntime.jsx("div", { className: classNames(usePrefixedClassNames('dropdown-menu'), menuClassName), id: id ? `${id}-menu` : undefined, role: "menu", "data-testid": "dropdown-menu", onKeyDown: handleMenuKeyDown, children: jsxRuntime.jsx("div", { className: usePrefixedClassNames('dropdown-content'), onClick: handleMenuClick, tabIndex: -1, children: children }) })] }));
2613
+ return (jsxRuntime.jsxs("div", { className: dropdownClasses, ref: setRefs, id: id, "data-testid": "dropdown-root", ...rest, children: [jsxRuntime.jsx("div", { className: usePrefixedClassNames('dropdown-trigger'), children: jsxRuntime.jsxs("button", { ref: triggerRef, className: buttonClass, "aria-haspopup": "true", "aria-controls": id ? `${id}-menu` : undefined, "aria-expanded": active, onClick: handleToggle, onKeyDown: handleTriggerKeyDown, disabled: disabled, type: "button", children: [jsxRuntime.jsx("span", { children: label }), jsxRuntime.jsx("span", { className: usePrefixedClassNames('icon', 'is-small'), "aria-hidden": "true", children: jsxRuntime.jsx("i", { className: "fas fa-angle-down" }) })] }) }), jsxRuntime.jsx("div", { className: classNames(usePrefixedClassNames('dropdown-menu'), menuClassName), id: id ? `${id}-menu` : undefined, role: "menu", "data-testid": "dropdown-menu", onKeyDown: handleMenuKeyDown,
2614
+ // The menu, not its content, takes focus from a click between items,
2615
+ // so the menu owns nothing focusable but its items.
2616
+ tabIndex: -1, children: jsxRuntime.jsx("div", { className: usePrefixedClassNames('dropdown-content'), onClick: handleMenuClick, children: children }) })] }));
2612
2617
  });
2613
2618
  /**
2614
2619
  * The anchor's attributes, minus the one a `<button>` legitimately takes.
@@ -3910,7 +3915,7 @@ function getIconClasses(library, name, variant, features) {
3910
3915
  * @see {@link https://bulma.io/documentation/elements/icon/ | Bulma Icon documentation}
3911
3916
  */
3912
3917
  const Icon = ({ className, textColor, bgColor, name, library, variant, features, libraryFeatures, // Deprecated but maintained for backward compatibility
3913
- size, ariaLabel = 'icon', style, icon, // Capture and exclude the deprecated 'icon' prop from DOM
3918
+ size, ariaLabel, style, icon, // Capture and exclude the deprecated 'icon' prop from DOM
3914
3919
  color: _color, // Exclude 'color' prop if passed directly
3915
3920
  containerClassName, children, ...restProps }) => {
3916
3921
  // Get the default icon library from context, fallback to 'fa' if not set
@@ -3934,10 +3939,22 @@ containerClassName, children, ...restProps }) => {
3934
3939
  ? containerClassName
3935
3940
  : defaultIconClasses;
3936
3941
  const iconContainerClasses = classNames(bulmaClasses, containerClassName && size ? sizeModifierClass : undefined, bulmaHelperClasses, className);
3942
+ // A named icon is an image, whose name is its label alone, so a ligature inside
3943
+ // never leaks into it. An unnamed one is decorative and hidden outright. Spread
3944
+ // before `rest`, so a caller's own `role` or `aria-hidden` still wins.
3945
+ const named = !!ariaLabel || !!restProps['aria-label'] || !!restProps['aria-labelledby'];
3946
+ // A caller's own `role` or `tabIndex` on an unnamed icon means it isn't decoration (an
3947
+ // icon made a button, say), so it isn't hidden either: `aria-hidden` on something
3948
+ // focusable is a failure of its own.
3949
+ const a11yProps = named
3950
+ ? { role: 'img', 'aria-label': ariaLabel || undefined }
3951
+ : restProps.role !== undefined || restProps.tabIndex !== undefined
3952
+ ? {}
3953
+ : { 'aria-hidden': true };
3937
3954
  if (children !== undefined) {
3938
3955
  // `IconChildrenProps`: render the caller's node (an inline SVG, a `react-icons`
3939
3956
  // component, …) in place of a class-based glyph. Library/variant/features don't apply.
3940
- return (jsxRuntime.jsx("span", { className: iconContainerClasses, "aria-label": ariaLabel, style: style, ...rest, children: children }));
3957
+ return (jsxRuntime.jsx("span", { className: iconContainerClasses, ...a11yProps, style: style, ...rest, children: children }));
3941
3958
  }
3942
3959
  // `name` is guaranteed once `children` is absent UNLESS the caller is on the deprecated
3943
3960
  // `icon` path, which `IconDeprecatedProps` declares with `name?: undefined`.
@@ -3971,7 +3988,7 @@ containerClassName, children, ...restProps }) => {
3971
3988
  // by a plain-JS caller (or one that casts). Building a class off an absent name produced
3972
3989
  // a bogus `fa-undefined` glyph; render the bare container instead, matching the
3973
3990
  // `children` branch.
3974
- return (jsxRuntime.jsx("span", { className: iconContainerClasses, "aria-label": ariaLabel, style: style, ...rest }));
3991
+ return (jsxRuntime.jsx("span", { className: iconContainerClasses, ...a11yProps, style: style, ...rest }));
3975
3992
  }
3976
3993
  // Backward compatibility: if libraryFeatures is provided, parse it for variant and features
3977
3994
  let finalVariant = variant;
@@ -4034,16 +4051,16 @@ containerClassName, children, ...restProps }) => {
4034
4051
  else if (finalVariant === 'sharp') {
4035
4052
  ionName = `${finalName}-sharp`;
4036
4053
  }
4037
- return (jsxRuntime.jsx("span", { className: iconContainerClasses, "aria-label": ariaLabel, style: style, ...rest, children: jsxRuntime.jsx("ion-icon", { name: ionName }) }));
4054
+ return (jsxRuntime.jsx("span", { className: iconContainerClasses, ...a11yProps, style: style, ...rest, children: jsxRuntime.jsx("ion-icon", { name: ionName }) }));
4038
4055
  }
4039
4056
  // Legacy CSS-based icons
4040
4057
  const iClasses = getIconClasses(finalLibrary, finalName, finalVariant, finalFeatures);
4041
4058
  // Material Icons and Material Symbols use text content, not CSS classes for the icon name
4042
4059
  if (finalLibrary === 'material-icons' ||
4043
4060
  finalLibrary === 'material-symbols') {
4044
- return (jsxRuntime.jsx("span", { className: iconContainerClasses, "aria-label": ariaLabel, style: style, ...rest, children: jsxRuntime.jsx("i", { className: iClasses, children: finalName }) }));
4061
+ return (jsxRuntime.jsx("span", { className: iconContainerClasses, ...a11yProps, style: style, ...rest, children: jsxRuntime.jsx("i", { className: iClasses, children: finalName }) }));
4045
4062
  }
4046
- return (jsxRuntime.jsx("span", { className: iconContainerClasses, "aria-label": ariaLabel, style: style, ...rest, children: jsxRuntime.jsx("i", { className: iClasses }) }));
4063
+ return (jsxRuntime.jsx("span", { className: iconContainerClasses, ...a11yProps, style: style, ...rest, children: jsxRuntime.jsx("i", { className: iClasses }) }));
4047
4064
  };
4048
4065
 
4049
4066
  /**
@@ -9051,12 +9068,36 @@ const FieldLabelIdContext = React.createContext(undefined);
9051
9068
  * The id a labeled Field wants its single composed control to adopt (#495).
9052
9069
  * `undefined` outside a Field, in unlabeled/grouped/addons Fields, or when the
9053
9070
  * user took over the association with an explicit `labelProps.htmlFor`.
9054
- * Consumed only by the single-control bases (InputBase, SelectBase,
9055
- * TextAreaBase). Internal; not part of the public API.
9071
+ * Consumed by the single-control bases (InputBase, SelectBase, TextAreaBase)
9072
+ * and, through `useAutoLabelId`, by the convenience inputs that render an
9073
+ * input of their own (#939). Internal; not part of the public API.
9056
9074
  */
9057
9075
  const useFieldLabelId = () => React.useContext(FieldLabelIdContext);
9058
9076
  /** Provider for the Field label-target id — used internally by Field. */
9059
9077
  const FieldLabelIdProvider = FieldLabelIdContext.Provider;
9078
+ const FieldLabelElementIdContext = React.createContext(undefined);
9079
+ /**
9080
+ * The id of a labeled Field's own `<label>`, for a group control (Radios,
9081
+ * Checkboxes, Rate, DateRangeInput) to point `aria-labelledby` at, since a group cannot take
9082
+ * the label's `htmlFor` (#939). Set under the same conditions as
9083
+ * {@link useFieldLabelId}. Consumed through `useAutoLabelledBy`.
9084
+ * Internal; not part of the public API.
9085
+ */
9086
+ const useFieldLabelElementId = () => React.useContext(FieldLabelElementIdContext);
9087
+ /** Provider for the Field label's own id, used internally by Field. */
9088
+ const FieldLabelElementIdProvider = FieldLabelElementIdContext.Provider;
9089
+ const FieldLabelForContext = React.createContext(undefined);
9090
+ /**
9091
+ * What the nearest labeled Field's `<label>` points `htmlFor` at: the id it
9092
+ * generated, or the caller's own `labelProps.htmlFor`. An unlabeled Field
9093
+ * passes it through, so a control in the inner Field of a horizontal layout
9094
+ * can tell the outer label names it. Only ever compared with a control's own
9095
+ * id, never adopted, so it hands out no id. Internal; not part of the public
9096
+ * API.
9097
+ */
9098
+ const useFieldLabelFor = () => React.useContext(FieldLabelForContext);
9099
+ /** Provider for the Field label's `htmlFor` target, used internally by Field. */
9100
+ const FieldLabelForProvider = FieldLabelForContext.Provider;
9060
9101
  const RadiosContext = React.createContext(undefined);
9061
9102
  const CheckboxesContext = React.createContext(undefined);
9062
9103
  /**
@@ -9357,13 +9398,27 @@ const FieldComponent = ({ horizontal, grouped, hasAddons, narrow, label, labelSi
9357
9398
  const targetId = label && !userWiredLabel && !grouped && !hasAddons
9358
9399
  ? generatedId
9359
9400
  : undefined;
9401
+ // A group control (Radios, Checkboxes, Rate, DateRangeInput) cannot take
9402
+ // that `for`, so it points `aria-labelledby` at the label itself (#939).
9403
+ // The label gets an id whenever the association is on, unless the caller
9404
+ // gave it one.
9405
+ const labelId = labelProps?.id ?? (targetId ? `${targetId}-label` : undefined);
9406
+ // What the rendered label's `for` points at, generated or the caller's, so
9407
+ // a control can tell when a label wired by hand names it. An unlabeled
9408
+ // Field passes on its parent's.
9409
+ const inheritedLabelFor = useFieldLabelFor();
9410
+ const labelFor = label
9411
+ ? userWiredLabel
9412
+ ? labelProps.htmlFor
9413
+ : targetId
9414
+ : inheritedLabelFor;
9360
9415
  let renderedLabel = null;
9361
9416
  if (label) {
9362
9417
  if (horizontal) {
9363
- renderedLabel = (jsxRuntime.jsx(FieldLabel, { size: effectiveLabelSize, children: jsxRuntime.jsx("label", { htmlFor: targetId, ...labelProps, className: classNames(labelClass, labelProps?.className), style: labelProps?.style, children: label }) }));
9418
+ renderedLabel = (jsxRuntime.jsx(FieldLabel, { size: effectiveLabelSize, children: jsxRuntime.jsx("label", { htmlFor: targetId, ...labelProps, id: labelId, className: classNames(labelClass, labelProps?.className), style: labelProps?.style, children: label }) }));
9364
9419
  }
9365
9420
  else {
9366
- renderedLabel = (jsxRuntime.jsx("label", { htmlFor: targetId, ...labelProps, className: classNames(labelClass, labelProps?.className), style: { display: 'block', ...(labelProps?.style || {}) }, children: label }));
9421
+ renderedLabel = (jsxRuntime.jsx("label", { htmlFor: targetId, ...labelProps, id: labelId, className: classNames(labelClass, labelProps?.className), style: { display: 'block', ...(labelProps?.style || {}) }, children: label }));
9367
9422
  }
9368
9423
  }
9369
9424
  // If horizontal, wrap children in FieldBody (unless the user already provided
@@ -9386,7 +9441,7 @@ const FieldComponent = ({ horizontal, grouped, hasAddons, narrow, label, labelSi
9386
9441
  content = jsxRuntime.jsx(FieldBody, { children: children });
9387
9442
  }
9388
9443
  }
9389
- return (jsxRuntime.jsx(FieldProvider, { value: true, children: jsxRuntime.jsx(FieldLabelIdProvider, { value: targetId, children: jsxRuntime.jsxs("div", { className: fieldClass, ...rest, children: [renderedLabel, content] }) }) }));
9444
+ return (jsxRuntime.jsx(FieldProvider, { value: true, children: jsxRuntime.jsx(FieldLabelIdProvider, { value: targetId, children: jsxRuntime.jsx(FieldLabelElementIdProvider, { value: targetId ? labelId : undefined, children: jsxRuntime.jsx(FieldLabelForProvider, { value: labelFor, children: jsxRuntime.jsxs("div", { className: fieldClass, ...rest, children: [renderedLabel, content] }) }) }) }) }));
9390
9445
  };
9391
9446
  FieldLabel.displayName = 'FieldLabel';
9392
9447
  FieldBody.displayName = 'FieldBody';
@@ -9402,27 +9457,42 @@ const Field = withSubComponents(FieldComponent, {
9402
9457
  * A user-supplied `id` is used as the target instead of the generated one, and
9403
9458
  * an explicit `htmlFor` key in labelProps — even set to `undefined` — disables
9404
9459
  * generation entirely: the user has taken over the association (#495 presence
9405
- * semantics). Internal; not part of the public API.
9460
+ * semantics). When the control renders no label of its own, it adopts the id
9461
+ * a labeled Field around it offers, the way the bases do, so that Field's
9462
+ * label names it (#939); a user `id` still wins there.
9463
+ * Internal; not part of the public API.
9406
9464
  */
9407
- function useAutoLabelId({ label, id, labelProps, rendersLabel, }) {
9465
+ function useAutoLabelId({ label, id, labelProps, rendersLabel, hasInput = true, }) {
9408
9466
  // Called unconditionally per the rules of hooks; SSR-safe on React 18 and 19.
9409
9467
  const generatedId = React.useId();
9468
+ // Read outside the control's own Field, so it is set only when an outer
9469
+ // Field holds the control, which then renders no label of its own.
9470
+ const fieldLabelId = useFieldLabelId();
9471
+ // What an outer Field's label points at, even when wired by hand.
9472
+ const fieldLabelFor = useFieldLabelFor();
9410
9473
  // Truthiness mirrors Field's own `if (label)` render gate.
9411
9474
  const active = !!label && rendersLabel;
9412
9475
  // Presence, not truthiness: `htmlFor: undefined` is an explicit opt-out and
9413
9476
  // must not leave an orphan generated id on the control.
9414
9477
  const userWired = !!labelProps && 'htmlFor' in labelProps;
9415
- const controlId = id ?? (active && !userWired ? generatedId : undefined);
9478
+ const adopted = !active && hasInput ? fieldLabelId : undefined;
9479
+ const controlId = id ?? (active && !userWired ? generatedId : adopted);
9480
+ const ownLabelProps = { htmlFor: controlId, ...labelProps };
9416
9481
  // Inactive with a label still means an own Field may render it (pickers'
9417
9482
  // inline mode, Taginput at maxTags) — the explicit `htmlFor: undefined`
9418
9483
  // tells Field the association is owned here, so it must not generate one
9419
9484
  // that would dangle (#495 presence semantics).
9420
9485
  const fieldLabelProps = active
9421
- ? { htmlFor: controlId, ...labelProps }
9486
+ ? ownLabelProps
9422
9487
  : label
9423
9488
  ? { htmlFor: undefined, ...labelProps }
9424
9489
  : labelProps;
9425
- return { controlId, fieldLabelProps };
9490
+ const labelTarget = active ? ownLabelProps.htmlFor : fieldLabelFor;
9491
+ return {
9492
+ controlId,
9493
+ fieldLabelProps,
9494
+ labelled: !!controlId && labelTarget === controlId,
9495
+ };
9426
9496
  }
9427
9497
  /**
9428
9498
  * Group-input counterpart of {@link useAutoLabelId} (#494): a group of
@@ -9431,18 +9501,36 @@ function useAutoLabelId({ label, id, labelProps, rendersLabel, }) {
9431
9501
  * `aria-labelledby`. A user-supplied `labelProps.id` is used as the target
9432
9502
  * instead of generating one. Any caller `htmlFor` is stripped — a group label
9433
9503
  * names the group, never a single control — so the merged labelProps always
9434
- * carry an explicit `htmlFor: undefined`.
9504
+ * carry an explicit `htmlFor: undefined`. When the group renders no label of
9505
+ * its own, it points at the label of a labeled Field around it instead
9506
+ * (#939). A caller who named the group with `aria-label` or
9507
+ * `aria-labelledby` gets no `aria-labelledby` from either label, so their
9508
+ * name wins wherever the label sits.
9435
9509
  * Internal; not part of the public API.
9436
9510
  */
9437
- function useAutoLabelledBy({ label, labelProps, rendersLabel, }) {
9511
+ function useAutoLabelledBy({ label, labelProps, rendersLabel, callerProps, }) {
9438
9512
  // Called unconditionally per the rules of hooks; SSR-safe on React 18 and 19.
9439
9513
  const generatedId = React.useId();
9514
+ // Set only when an outer Field holds the group (see useAutoLabelId).
9515
+ const fieldLabelElementId = useFieldLabelElementId();
9440
9516
  const active = !!label && rendersLabel;
9441
9517
  const labelId = labelProps?.id ?? (active ? generatedId : undefined);
9442
9518
  const fieldLabelProps = active
9443
9519
  ? { ...labelProps, id: labelId, htmlFor: undefined }
9444
9520
  : labelProps;
9445
- return { ariaLabelledBy: active ? labelId : undefined, fieldLabelProps };
9521
+ const aria = callerProps;
9522
+ // Presence for aria-labelledby: the caller's key replaces the attribute
9523
+ // through the spread whatever its value, and pointing it at a label would
9524
+ // only take a Rate's fallback name away. Checked before either label, so
9525
+ // the caller's name wins over the group's own `label` as it does over a
9526
+ // Field's, the way an aria-label beats a `<label for>` on a single input.
9527
+ const callerNamed = !!aria['aria-label'] || 'aria-labelledby' in aria;
9528
+ const ariaLabelledBy = callerNamed
9529
+ ? undefined
9530
+ : active
9531
+ ? labelId
9532
+ : fieldLabelElementId;
9533
+ return { ariaLabelledBy, fieldLabelProps };
9446
9534
  }
9447
9535
 
9448
9536
  /**
@@ -9485,6 +9573,7 @@ const CheckboxesComponent = ({ label, labelSize, labelProps, horizontal, message
9485
9573
  label,
9486
9574
  labelProps,
9487
9575
  rendersLabel: ownField,
9576
+ callerProps: props,
9488
9577
  });
9489
9578
  const { bulmaHelperClasses, rest } = useBulmaClasses({
9490
9579
  ...props,
@@ -9581,9 +9670,12 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
9581
9670
  rendersLabel: ownField,
9582
9671
  });
9583
9672
  const { classPrefix } = useConfig();
9673
+ // The input takes `controlId`, so `id` stays out of the spread, where an
9674
+ // undefined `id` key would wipe the id the label points at.
9675
+ const { id: _id, ...inputProps } = props;
9584
9676
  const { bulmaHelperClasses, rest } = useBulmaClasses({
9585
9677
  color,
9586
- ...props,
9678
+ ...inputProps,
9587
9679
  });
9588
9680
  // Mutually exclusive alignment
9589
9681
  let alignmentClass;
@@ -9755,6 +9847,7 @@ const RadiosComponent = ({ label, labelSize, labelProps, horizontal, message, me
9755
9847
  label,
9756
9848
  labelProps,
9757
9849
  rendersLabel: ownField,
9850
+ callerProps: props,
9758
9851
  });
9759
9852
  const { bulmaHelperClasses, rest } = useBulmaClasses({
9760
9853
  ...props,
@@ -10247,7 +10340,9 @@ const Slider = React.forwardRef((props, ref) => {
10247
10340
  // --- Single slider ---
10248
10341
  const sliderElement = !range ? (jsxRuntime.jsxs("div", { ref: wrapperRef, className: combinedClasses, style: wrapperStyle, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "range", min: min, max: max, step: step, value: currentSingle, disabled: disabled, onChange: handleSingleChange, onKeyDown: handleKeyDown, onMouseEnter: () => setShowTooltip(true), onMouseLeave: () => setShowTooltip(false), onFocus: () => setShowTooltip(true), onBlur: () => setShowTooltip(false), className: prefixedClassNames(classPrefix, 'slider-input'), style: {
10249
10342
  '--slider-progress': `${progressSingle}%`,
10250
- }, "aria-valuenow": currentSingle, "aria-valuemin": min, "aria-valuemax": max, "aria-orientation": isVertical ? 'vertical' : undefined, "aria-label": ariaLabel, ...getAriaProps(currentSingle), id: controlId, ...rest }), tooltipMode !== 'hidden' && (jsxRuntime.jsx("output", { ref: outputRef, className: prefixedClassNames(classPrefix, 'slider-output', {
10343
+ }, "aria-valuenow": currentSingle, "aria-valuemin": min, "aria-valuemax": max, "aria-orientation": isVertical ? 'vertical' : undefined, "aria-label": ariaLabel, ...getAriaProps(currentSingle), ...rest,
10344
+ // After the spread: an undefined `id` key in rest would wipe it.
10345
+ id: controlId }), tooltipMode !== 'hidden' && (jsxRuntime.jsx("output", { ref: outputRef, className: prefixedClassNames(classPrefix, 'slider-output', {
10251
10346
  'is-visible': showTipLow,
10252
10347
  'is-flipped': flipped,
10253
10348
  'is-flipped-left': isVertical && verticalFlippedLeft,
@@ -10275,7 +10370,7 @@ const Slider = React.forwardRef((props, ref) => {
10275
10370
  : {
10276
10371
  '--slider-progress-low': `${progressLow}%`,
10277
10372
  '--slider-progress-high': `${progressHigh}%`,
10278
- } }), jsxRuntime.jsx("input", { ref: combinedRef, type: "range", min: min, max: max, step: step, value: currentRange[0], disabled: disabled, onChange: handleRangeLowChange, onKeyDown: handleKeyDown, onMouseEnter: () => setShowTooltip(true), onMouseLeave: () => setShowTooltip(false), onFocus: () => setShowTooltip(true), onBlur: () => setShowTooltip(false), className: prefixedClassNames(classPrefix, 'slider-input', 'slider-input-low'), "aria-valuenow": currentRange[0], "aria-valuemin": min, "aria-valuemax": max, "aria-orientation": isVertical ? 'vertical' : undefined, "aria-label": ariaLabel?.[0] ?? 'Minimum value', ...getAriaProps(currentRange[0]), id: controlId, ...rest, ...(nameLow !== undefined ? { name: nameLow } : {}) }), jsxRuntime.jsx("input", { ref: inputHighRef, type: "range", min: min, max: max, step: step, value: currentRange[1], disabled: disabled, onChange: handleRangeHighChange, onMouseEnter: () => setShowTooltipHigh(true), onMouseLeave: () => setShowTooltipHigh(false), onFocus: () => setShowTooltipHigh(true), onBlur: () => setShowTooltipHigh(false), className: prefixedClassNames(classPrefix, 'slider-input', 'slider-input-high'), "aria-valuenow": currentRange[1], "aria-valuemin": min, "aria-valuemax": max, "aria-orientation": isVertical ? 'vertical' : undefined, "aria-label": ariaLabel?.[1] ?? 'Maximum value', ...getAriaProps(currentRange[1]), name: nameHigh }), tooltipMode !== 'hidden' && (jsxRuntime.jsx("output", { ref: outputRef, className: prefixedClassNames(classPrefix, 'slider-output', 'slider-output-low', {
10373
+ } }), jsxRuntime.jsx("input", { ref: combinedRef, type: "range", min: min, max: max, step: step, value: currentRange[0], disabled: disabled, onChange: handleRangeLowChange, onKeyDown: handleKeyDown, onMouseEnter: () => setShowTooltip(true), onMouseLeave: () => setShowTooltip(false), onFocus: () => setShowTooltip(true), onBlur: () => setShowTooltip(false), className: prefixedClassNames(classPrefix, 'slider-input', 'slider-input-low'), "aria-valuenow": currentRange[0], "aria-valuemin": min, "aria-valuemax": max, "aria-orientation": isVertical ? 'vertical' : undefined, "aria-label": ariaLabel?.[0] ?? 'Minimum value', ...getAriaProps(currentRange[0]), ...rest, id: controlId, ...(nameLow !== undefined ? { name: nameLow } : {}) }), jsxRuntime.jsx("input", { ref: inputHighRef, type: "range", min: min, max: max, step: step, value: currentRange[1], disabled: disabled, onChange: handleRangeHighChange, onMouseEnter: () => setShowTooltipHigh(true), onMouseLeave: () => setShowTooltipHigh(false), onFocus: () => setShowTooltipHigh(true), onBlur: () => setShowTooltipHigh(false), className: prefixedClassNames(classPrefix, 'slider-input', 'slider-input-high'), "aria-valuenow": currentRange[1], "aria-valuemin": min, "aria-valuemax": max, "aria-orientation": isVertical ? 'vertical' : undefined, "aria-label": ariaLabel?.[1] ?? 'Maximum value', ...getAriaProps(currentRange[1]), name: nameHigh }), tooltipMode !== 'hidden' && (jsxRuntime.jsx("output", { ref: outputRef, className: prefixedClassNames(classPrefix, 'slider-output', 'slider-output-low', {
10279
10374
  'is-visible': showTipLow,
10280
10375
  'is-flipped': flipped,
10281
10376
  'is-flipped-left': isVertical && verticalFlippedLeft,
@@ -10468,7 +10563,9 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
10468
10563
  }
10469
10564
  };
10470
10565
  // Shared input element
10471
- const inputControl = (jsxRuntime.jsx("div", { className: expandedControlClasses, children: jsxRuntime.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 }) }));
10566
+ const inputControl = (jsxRuntime.jsx("div", { className: expandedControlClasses, children: jsxRuntime.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, ...rest,
10567
+ // After the spread: an undefined `id` key in rest would wipe it.
10568
+ id: controlId }) }));
10472
10569
  // Stepper variant
10473
10570
  if (isStepper) {
10474
10571
  const stepperElement = (jsxRuntime.jsxs("div", { className: combinedClasses, children: [inputControl, jsxRuntime.jsx("div", { className: controlClasses, children: jsxRuntime.jsxs("div", { className: stepperClasses, children: [jsxRuntime.jsx("button", { type: "button", className: stepperButtonClasses, onClick: handleIncrement, disabled: disabled || isAtMax, tabIndex: -1, "aria-label": "Increase value", children: jsxRuntime.jsx(ArrowDropUp, {}) }), jsxRuntime.jsx("button", { type: "button", className: stepperButtonClasses, onClick: handleDecrement, disabled: disabled || isAtMin, tabIndex: -1, "aria-label": "Decrease value", children: jsxRuntime.jsx(ArrowDropDown, {}) })] }) })] }));
@@ -10566,8 +10663,10 @@ const Rate = React.forwardRef(({ label, labelSize, labelProps, horizontal, messa
10566
10663
  label,
10567
10664
  labelProps,
10568
10665
  rendersLabel: ownField,
10666
+ callerProps: props,
10569
10667
  });
10570
10668
  const { bulmaHelperClasses, rest } = useBulmaClasses(props);
10669
+ const starBaseId = React.useId();
10571
10670
  const [internalValue, setInternalValue] = React.useState(defaultValue);
10572
10671
  const [hoverValue, setHoverValue] = React.useState(null);
10573
10672
  const defaultIconLibrary = useIconLibrary();
@@ -10729,6 +10828,14 @@ const Rate = React.forwardRef(({ label, labelSize, labelProps, horizontal, messa
10729
10828
  const clipId = `rate-clip-${iconIndex}`;
10730
10829
  return (jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", "aria-hidden": "true", children: [jsxRuntime.jsx("defs", { children: jsxRuntime.jsx("clipPath", { id: clipId, children: jsxRuntime.jsx("rect", { x: "0", y: "0", width: `${(fillPercent / 100) * 24}`, height: "24" }) }) }), jsxRuntime.jsx("path", { fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", d: "M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" }), jsxRuntime.jsx("path", { clipPath: `url(#${clipId})`, fill: "currentColor", d: "M11.049 2.927c.3-.921 1.603-.921 1.902 0l1.519 4.674a1 1 0 00.95.69h4.915c.969 0 1.371 1.24.588 1.81l-3.976 2.888a1 1 0 00-.363 1.118l1.518 4.674c.3.922-.755 1.688-1.538 1.118l-3.976-2.888a1 1 0 00-1.176 0l-3.976 2.888c-.783.57-1.838-.197-1.538-1.118l1.518-4.674a1 1 0 00-.363-1.118l-3.976-2.888c-.784-.57-.38-1.81.588-1.81h4.914a1 1 0 00.951-.69l1.519-4.674z" })] }));
10731
10830
  };
10831
+ // The star the value falls in is the checked radio, and it carries the
10832
+ // value: a radiogroup takes no aria-value* of its own. A fractional value
10833
+ // names that star by the value itself ("3.5 stars"). Both go by the value
10834
+ // as that name writes it, to hundredths, so a value a hair over a whole
10835
+ // number checks that number's star under its own name, and no two stars
10836
+ // share a name.
10837
+ const shownValue = Number(currentValue.toFixed(2));
10838
+ const checkedIndex = shownValue > 0 ? Math.min(Math.ceil(shownValue), max) - 1 : -1;
10732
10839
  // Render icons
10733
10840
  const renderIcons = () => {
10734
10841
  const icons = [];
@@ -10744,17 +10851,13 @@ const Rate = React.forwardRef(({ label, labelSize, labelProps, horizontal, messa
10744
10851
  icons.push(jsxRuntime.jsx("span", { className: prefixedClassNames(classPrefix, 'rate-item', {
10745
10852
  'is-active': isActive,
10746
10853
  'is-hovered': isHovered,
10747
- }), onClick: e => handleClick(iconIndex, e), onMouseEnter: () => handleMouseEnter(iconIndex), onMouseMove: e => handleMouseMove(iconIndex, e), onMouseLeave: handleMouseLeave, role: "radio", "aria-checked": currentValue === iconIndex + 1 ||
10748
- (precision < 1 &&
10749
- currentValue > iconIndex &&
10750
- currentValue <= iconIndex + 1), "aria-label": `${iconIndex + 1} star${iconIndex === 0 ? '' : 's'}`, tabIndex: -1, children: icon }, iconIndex));
10854
+ }), onClick: e => handleClick(iconIndex, e), onMouseEnter: () => handleMouseEnter(iconIndex), onMouseMove: e => handleMouseMove(iconIndex, e), onMouseLeave: handleMouseLeave, id: `${starBaseId}-${iconIndex}`, role: "radio", "aria-checked": iconIndex === checkedIndex, "aria-label": iconIndex === checkedIndex && shownValue % 1 !== 0
10855
+ ? `${shownValue} stars`
10856
+ : `${iconIndex + 1} star${iconIndex === 0 ? '' : 's'}`, tabIndex: -1, children: icon }, iconIndex));
10751
10857
  }
10752
10858
  return icons;
10753
10859
  };
10754
10860
  const text = getText();
10755
- const ariaValueText = precision < 1 && currentValue % 1 !== 0
10756
- ? `${currentValue.toFixed(1)} out of ${max} stars`
10757
- : undefined;
10758
10861
  const helpClass = usePrefixedClassNames('help', {
10759
10862
  [`is-${messageColor}`]: !!messageColor,
10760
10863
  });
@@ -10763,7 +10866,7 @@ const Rate = React.forwardRef(({ label, labelSize, labelProps, horizontal, messa
10763
10866
  const rateScoreClass = usePrefixedClassNames('rate-score');
10764
10867
  const rateTextClass = usePrefixedClassNames('rate-text');
10765
10868
  const rateCustomTextClass = usePrefixedClassNames('rate-custom-text');
10766
- const rateElement = (jsxRuntime.jsxs("div", { ref: ref, className: combinedClasses, role: "radiogroup", "aria-label": ariaLabelledBy ? undefined : 'Rating', "aria-labelledby": ariaLabelledBy, "aria-valuenow": currentValue, "aria-valuemin": 0, "aria-valuemax": max, "aria-valuetext": ariaValueText, tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown, ...rest, children: [jsxRuntime.jsx("div", { className: rateItemsClass, children: renderIcons() }), showScore && (jsxRuntime.jsx("span", { className: rateScoreClass, children: getScoreDisplay() })), text && jsxRuntime.jsx("span", { className: rateTextClass, children: text }), customText && (jsxRuntime.jsx("span", { className: rateCustomTextClass, children: customText })), name && (jsxRuntime.jsx("input", { type: "hidden", name: name, value: currentValue, form: form }))] }));
10869
+ const rateElement = (jsxRuntime.jsxs("div", { ref: ref, className: combinedClasses, role: "radiogroup", "aria-label": ariaLabelledBy ? undefined : 'Rating', "aria-labelledby": ariaLabelledBy, "aria-activedescendant": checkedIndex >= 0 ? `${starBaseId}-${checkedIndex}` : undefined, tabIndex: disabled ? -1 : 0, onKeyDown: handleKeyDown, ...rest, children: [jsxRuntime.jsx("div", { className: rateItemsClass, children: renderIcons() }), showScore && (jsxRuntime.jsx("span", { className: rateScoreClass, children: getScoreDisplay() })), text && jsxRuntime.jsx("span", { className: rateTextClass, children: text }), customText && (jsxRuntime.jsx("span", { className: rateCustomTextClass, children: customText })), name && (jsxRuntime.jsx("input", { type: "hidden", name: name, value: currentValue, form: form }))] }));
10767
10870
  let content = rateElement;
10768
10871
  if (rendersOwnControl('Rate', { insideControl })) {
10769
10872
  content = jsxRuntime.jsx(Control, { children: content });
@@ -10817,6 +10920,7 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
10817
10920
  const [internalValue, setInternalValue] = React.useState('');
10818
10921
  const [isActive, setIsActive] = React.useState(false);
10819
10922
  const [highlightedIndex, setHighlightedIndex] = React.useState(-1);
10923
+ const listboxId = `${React.useId()}-listbox`;
10820
10924
  // Use controlled or internal value
10821
10925
  const inputValue = controlledValue !== undefined ? controlledValue : internalValue;
10822
10926
  // Get display value from item
@@ -11008,19 +11112,33 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
11008
11112
  // or that of a loading Control this sits in.
11009
11113
  const controlLoading = useControlLoading();
11010
11114
  const showClear = clearable && !!inputValue && !disabled && !loading && !controlLoading;
11011
- const autocompleteElement = (jsxRuntime.jsxs("div", { ref: containerRef, className: combinedClasses, ...rest, children: [jsxRuntime.jsxs("div", { className: controlClasses, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "text", className: inputClasses, id: controlId, value: inputValue, placeholder: placeholder, disabled: disabled, name: name, form: form, required: required, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, role: "combobox", "aria-expanded": isActive, "aria-haspopup": "listbox", "aria-autocomplete": "list", autoComplete: "off" }), showClear && (jsxRuntime.jsx("button", { type: "button", className: iconRightClickableClass, onClick: handleClear, "aria-label": "Clear", children: jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", width: "16", height: "16", "aria-hidden": "true", children: [jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })), loading && (jsxRuntime.jsx("span", { className: iconRightClass, children: jsxRuntime.jsx("span", { className: loaderClass }) }))] }), isActive && (filteredData.length > 0 || empty) && (jsxRuntime.jsx("div", { className: dropdownMenuClasses, children: jsxRuntime.jsxs("div", { ref: dropdownRef, className: dropdownContentClass, style: { maxHeight: `${maxHeight}px`, overflowY: 'auto' }, role: "listbox", onScroll: handleDropdownScroll, children: [header && jsxRuntime.jsx("div", { className: dropdownHeaderClass, children: header }), filteredData.length > 0 ? (filteredData.map((item, index) => {
11115
+ // The combobox controls its listbox and points at the highlighted option.
11116
+ // The listbox takes its name from the label this renders, or a fallback
11117
+ // when it renders none.
11118
+ const listOpen = isActive && (filteredData.length > 0 || !!empty);
11119
+ const listLabelId = !insideField && label
11120
+ ? (fieldLabelProps?.id ?? `${listboxId}-label`)
11121
+ : undefined;
11122
+ const activeOptionId = listOpen &&
11123
+ highlightedIndex >= 0 &&
11124
+ highlightedIndex < filteredData.length
11125
+ ? `${listboxId}-${highlightedIndex}`
11126
+ : undefined;
11127
+ const autocompleteElement = (jsxRuntime.jsxs("div", { ref: containerRef, className: combinedClasses, ...rest, children: [jsxRuntime.jsxs("div", { className: controlClasses, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "text", className: inputClasses, id: controlId, value: inputValue, placeholder: placeholder, disabled: disabled, name: name, form: form, required: required, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, role: "combobox", "aria-expanded": listOpen, "aria-controls": listOpen ? listboxId : undefined, "aria-activedescendant": activeOptionId, "aria-haspopup": "listbox", "aria-autocomplete": "list", autoComplete: "off" }), showClear && (jsxRuntime.jsx("button", { type: "button", className: iconRightClickableClass, onClick: handleClear, "aria-label": "Clear", children: jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", width: "16", height: "16", "aria-hidden": "true", children: [jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })), loading && (jsxRuntime.jsx("span", { className: iconRightClass, children: jsxRuntime.jsx("span", { className: loaderClass }) }))] }), listOpen && (jsxRuntime.jsx("div", { className: dropdownMenuClasses, children: jsxRuntime.jsxs("div", { ref: dropdownRef, className: dropdownContentClass, style: { maxHeight: `${maxHeight}px`, overflowY: 'auto' }, id: listboxId, role: "listbox", "aria-labelledby": listLabelId, "aria-label": listLabelId ? undefined : 'Suggestions', onScroll: handleDropdownScroll, children: [header && jsxRuntime.jsx("div", { className: dropdownHeaderClass, children: header }), filteredData.length > 0 ? (filteredData.map((item, index) => {
11012
11128
  const isDisabled = typeof item !== 'string' && item.disabled;
11013
11129
  const isHighlighted = index === highlightedIndex;
11014
11130
  const itemClasses = prefixedClassNames(classPrefix, 'dropdown-item', {
11015
11131
  'is-active': isHighlighted,
11016
11132
  'is-disabled': isDisabled,
11017
11133
  });
11018
- return (jsxRuntime.jsx("a", { "data-index": index, className: itemClasses, onClick: () => !isDisabled && handleSelect(item), onMouseEnter: () => !isDisabled && setHighlightedIndex(index), role: "option", "aria-selected": isHighlighted, "aria-disabled": isDisabled, children: itemTemplate
11134
+ return (jsxRuntime.jsx("a", { id: `${listboxId}-${index}`, "data-index": index, className: itemClasses, onClick: () => !isDisabled && handleSelect(item), onMouseEnter: () => !isDisabled && setHighlightedIndex(index), role: "option", "aria-selected": isHighlighted, "aria-disabled": isDisabled, children: itemTemplate
11019
11135
  ? itemTemplate(item)
11020
11136
  : getDisplayValue(item) }, index));
11021
11137
  })) : (jsxRuntime.jsx("div", { className: emptyItemClasses, children: empty })), footer && jsxRuntime.jsx("div", { className: dropdownFooterClass, children: footer })] }) }))] }));
11022
11138
  if (!insideField) {
11023
- return (jsxRuntime.jsxs(Field, { label: label, labelSize: labelSize, labelProps: fieldLabelProps, horizontal: horizontal, className: fieldClassName, children: [autocompleteElement, messageEl] }));
11139
+ return (jsxRuntime.jsxs(Field, { label: label, labelSize: labelSize, labelProps: listLabelId
11140
+ ? { ...fieldLabelProps, id: listLabelId }
11141
+ : fieldLabelProps, horizontal: horizontal, className: fieldClassName, children: [autocompleteElement, messageEl] }));
11024
11142
  }
11025
11143
  return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [autocompleteElement, messageEl] }));
11026
11144
  });
@@ -11078,12 +11196,13 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
11078
11196
  const tags = controlledValue !== undefined ? controlledValue : internalTags;
11079
11197
  const isMaxReached = maxTags !== undefined && tags.length >= maxTags;
11080
11198
  // At the tag limit the text input is not rendered, so there is nothing to
11081
- // wire the label to.
11082
- const { controlId, fieldLabelProps } = useAutoLabelId({
11199
+ // wire a label to, its own or a surrounding Field's.
11200
+ const { controlId, fieldLabelProps, labelled } = useAutoLabelId({
11083
11201
  label,
11084
11202
  id,
11085
11203
  labelProps,
11086
11204
  rendersLabel: ownField && !isMaxReached,
11205
+ hasInput: !isMaxReached,
11087
11206
  });
11088
11207
  // Get display value from tag
11089
11208
  const getDisplayValue = (tag) => {
@@ -11349,9 +11468,7 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
11349
11468
  e.stopPropagation();
11350
11469
  removeTag(index);
11351
11470
  }, "aria-label": ariaCloseLabel || `Remove ${displayVal}` }))] }, index));
11352
- }), !isMaxReached && (jsxRuntime.jsx("input", { ref: combinedRef, type: "text", className: inputClasses, id: controlId, value: inputValue, placeholder: tags.length === 0 ? placeholder : undefined, disabled: disabled, readOnly: readonly, maxLength: maxlength, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, onPaste: handlePaste, "aria-label": controlId && fieldLabelProps?.htmlFor === controlId
11353
- ? undefined
11354
- : 'Add tag' }))] }), loading && (jsxRuntime.jsx("span", { className: iconRightClass, children: jsxRuntime.jsx("span", { className: loaderClass }) }))] }), isActive && filteredData.length > 0 && (jsxRuntime.jsx("div", { className: dropdownMenuClasses, children: jsxRuntime.jsx("div", { ref: dropdownRef, className: dropdownContentClasses, role: "listbox", children: filteredData.map((item, index) => (jsxRuntime.jsx("a", { className: pcn('dropdown-item', {
11471
+ }), !isMaxReached && (jsxRuntime.jsx("input", { ref: combinedRef, type: "text", className: inputClasses, id: controlId, value: inputValue, placeholder: tags.length === 0 ? placeholder : undefined, disabled: disabled, readOnly: readonly, maxLength: maxlength, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, onPaste: handlePaste, "aria-label": labelled ? undefined : 'Add tag' }))] }), loading && (jsxRuntime.jsx("span", { className: iconRightClass, children: jsxRuntime.jsx("span", { className: loaderClass }) }))] }), isActive && filteredData.length > 0 && (jsxRuntime.jsx("div", { className: dropdownMenuClasses, children: jsxRuntime.jsx("div", { ref: dropdownRef, className: dropdownContentClasses, role: "listbox", children: filteredData.map((item, index) => (jsxRuntime.jsx("a", { className: pcn('dropdown-item', {
11355
11472
  'is-active': index === highlightedIndex,
11356
11473
  }), onClick: () => addTag(item), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index === highlightedIndex, children: item }, index))) }) })), showCounter && jsxRuntime.jsx("small", { className: counterClasses, children: counterText }), name &&
11357
11474
  tags.map((tag, i) => (jsxRuntime.jsx("input", { type: "hidden", name: name, value: getDisplayValue(tag), form: form }, `tag-input-${i}`)))] }));
@@ -11540,7 +11657,7 @@ fieldClassName, controlClassName,
11540
11657
  const helpClass = usePrefixedClassNames('help', {
11541
11658
  [`is-${messageColor}`]: !!messageColor,
11542
11659
  });
11543
- let content = jsxRuntime.jsx(InputBase, { ref: ref, id: controlId, ...inputProps });
11660
+ let content = jsxRuntime.jsx(InputBase, { ref: ref, ...inputProps, id: controlId });
11544
11661
  if (ownControl) {
11545
11662
  content = (jsxRuntime.jsx(Control, { iconLeft: iconLeft, iconRight: iconRight, iconLeftName: iconLeftName, iconRightName: iconRightName, iconLeftSize: iconLeftSize, iconRightSize: iconRightSize, hasIconsLeft: hasIconsLeft, hasIconsRight: hasIconsRight, isLoading: isLoading, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
11546
11663
  }
@@ -11609,7 +11726,7 @@ fieldClassName, controlClassName,
11609
11726
  const helpClass = usePrefixedClassNames('help', {
11610
11727
  [`is-${messageColor}`]: !!messageColor,
11611
11728
  });
11612
- let content = jsxRuntime.jsx(SelectBase, { ref: ref, id: controlId, ...selectProps });
11729
+ let content = jsxRuntime.jsx(SelectBase, { ref: ref, ...selectProps, id: controlId });
11613
11730
  if (ownControl) {
11614
11731
  content = (jsxRuntime.jsx(Control, { iconLeft: iconLeft, iconLeftName: iconLeftName, iconLeftSize: iconLeftSize, hasIconsLeft: hasIconsLeft, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
11615
11732
  }
@@ -11674,7 +11791,7 @@ fieldClassName, controlClassName,
11674
11791
  const helpClass = usePrefixedClassNames('help', {
11675
11792
  [`is-${messageColor}`]: !!messageColor,
11676
11793
  });
11677
- let content = jsxRuntime.jsx(TextAreaBase, { ref: ref, id: controlId, ...textAreaProps });
11794
+ let content = jsxRuntime.jsx(TextAreaBase, { ref: ref, ...textAreaProps, id: controlId });
11678
11795
  if (ownControl) {
11679
11796
  content = (jsxRuntime.jsx(Control, { isLoading: controlIsLoading, size: controlSize, className: controlClassName, children: content }));
11680
11797
  }
@@ -14243,13 +14360,14 @@ const DateInput = React.forwardRef((props, ref) => {
14243
14360
  labelProps,
14244
14361
  // Inline mode renders a bare calendar with no input to label.
14245
14362
  rendersLabel: ownField && !baseProps.inline,
14363
+ hasInput: !baseProps.inline,
14246
14364
  });
14247
14365
  const helpClass = usePrefixedClassNames('help', {
14248
14366
  [`is-${messageColor}`]: !!messageColor,
14249
14367
  });
14250
14368
  // The base hides its launcher while the Control it sits in is loading,
14251
14369
  // whether that is the one rendered below or an enclosing one.
14252
- let content = (jsxRuntime.jsx(DateInputBase, { ref: ref, id: controlId, ...baseProps }));
14370
+ let content = (jsxRuntime.jsx(DateInputBase, { ref: ref, ...baseProps, id: controlId }));
14253
14371
  if (ownControl) {
14254
14372
  content = (jsxRuntime.jsx(Control, { iconLeft: iconLeft, iconRight: iconRight, iconLeftName: iconLeftName, iconRightName: iconRightName, iconLeftSize: iconLeftSize, iconRightSize: iconRightSize, hasIconsLeft: hasIconsLeft || !!iconLeftName, hasIconsRight: hasIconsRight, isLoading: isLoading, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
14255
14373
  }
@@ -14914,13 +15032,16 @@ const WheelInner = ({ values, index, onChange, formatLabel, formatAriaText, aria
14914
15032
  const top = centreTop + offCentreItems * itemHeight;
14915
15033
  const selected = vIdx === virtualIdx;
14916
15034
  const itemDisabled = disabled || (disabledFor ? disabledFor(values[aIdx]) : false);
14917
- return (jsxRuntime.jsx("button", { type: "button", role: "option", "aria-selected": selected, tabIndex: -1, className: itemClass(selected), style: {
15035
+ return (jsxRuntime.jsx("button", { type: "button", "aria-hidden": "true", tabIndex: -1, className: itemClass(selected), style: {
14918
15036
  position: 'absolute',
14919
15037
  left: 0,
14920
15038
  right: 0,
14921
15039
  height: itemHeight,
14922
15040
  top: `${top}px`,
14923
- }, disabled: itemDisabled, onClick: () => {
15041
+ }, disabled: itemDisabled,
15042
+ // Keep a press from focusing the item, which assistive technology
15043
+ // can't see; the click below hands focus to the wheel instead.
15044
+ onMouseDown: e => e.preventDefault(), onClick: () => {
14924
15045
  moveBy(vIdx - virtualIdx);
14925
15046
  // Click focuses the <button> child by default; pull focus back
14926
15047
  // to the wheel root so the column emphasis (:focus rules) match.
@@ -15104,7 +15225,7 @@ const TimeWheels = ({ value, onChange, hourFormat = '24', enableSeconds = false,
15104
15225
  });
15105
15226
  columnOrder[nearestIdx]?.current?.startDrag(e.pointerId, e.clientY);
15106
15227
  };
15107
- return (jsxRuntime.jsx("div", { id: id, className: classNames(rootClass, className), "aria-disabled": disabled, children: jsxRuntime.jsxs("div", { className: wheelsClass, ref: wheelsContainerRef, onPointerDown: onWheelsContainerPointerDown, children: [jsxRuntime.jsx(Wheel, { ref: hoursRef, values: hourValues, index: hourIndex, onChange: onHourIndex, formatLabel: pad2, ariaLabel: t.hours, visibleCount: visibleCount, itemHeight: itemHeight, disabled: disabled, size: size, color: color, wrap: true, onCommit: onCommit, onFocusPrev: focusPrevOf(hoursRef), onFocusNext: focusNextOf(hoursRef), disabledFor: hourDisabledFor, audioTick: audioTick }), jsxRuntime.jsx("div", { className: sepClass, "aria-hidden": "true", children: ":" }), jsxRuntime.jsx(Wheel, { ref: minutesRef, values: minuteValues, index: minuteIndex, onChange: onMinuteIndex, formatLabel: pad2, ariaLabel: t.minutes, visibleCount: visibleCount, itemHeight: itemHeight, disabled: disabled, size: size, color: color, wrap: true, onCommit: onCommit, onFocusPrev: focusPrevOf(minutesRef), onFocusNext: focusNextOf(minutesRef), disabledFor: minuteDisabledFor, audioTick: audioTick }), enableSeconds && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: sepClass, "aria-hidden": "true", children: ":" }), jsxRuntime.jsx(Wheel, { ref: secondsRef, values: secondValues, index: secondIndex, onChange: onSecondIndex, formatLabel: pad2, ariaLabel: t.seconds, visibleCount: visibleCount, itemHeight: itemHeight, disabled: disabled, size: size, color: color, wrap: true, onFocusPrev: focusPrevOf(secondsRef), onFocusNext: focusNextOf(secondsRef), disabledFor: secondDisabledFor, audioTick: audioTick })] })), hourFormat === '12' && (jsxRuntime.jsx(Wheel, { ref: ampmRef, values: ['AM', 'PM'], index: ampmIndex, onChange: onAmpmIndex, formatLabel: v => v, ariaLabel: t.ampm, visibleCount: visibleCount, itemHeight: itemHeight, disabled: disabled, size: size, color: color, onCommit: onCommit, onFocusPrev: focusPrevOf(ampmRef), onFocusNext: focusNextOf(ampmRef), audioTick: audioTick }))] }) }));
15228
+ return (jsxRuntime.jsx("div", { id: id, className: classNames(rootClass, className), "aria-disabled": disabled, children: jsxRuntime.jsxs("div", { className: wheelsClass, ref: wheelsContainerRef, onPointerDown: onWheelsContainerPointerDown, children: [jsxRuntime.jsx(Wheel, { ref: hoursRef, values: hourValues, index: hourIndex, onChange: onHourIndex, formatLabel: pad2, ariaLabel: t.hours, visibleCount: visibleCount, itemHeight: itemHeight, disabled: disabled, size: size, color: color, wrap: true, onCommit: onCommit, onFocusPrev: focusPrevOf(hoursRef), onFocusNext: focusNextOf(hoursRef), disabledFor: hourDisabledFor, audioTick: audioTick }), jsxRuntime.jsx("div", { className: sepClass, "aria-hidden": "true", children: ":" }), jsxRuntime.jsx(Wheel, { ref: minutesRef, values: minuteValues, index: minuteIndex, onChange: onMinuteIndex, formatLabel: pad2, ariaLabel: t.minutes, visibleCount: visibleCount, itemHeight: itemHeight, disabled: disabled, size: size, color: color, wrap: true, onCommit: onCommit, onFocusPrev: focusPrevOf(minutesRef), onFocusNext: focusNextOf(minutesRef), disabledFor: minuteDisabledFor, audioTick: audioTick }), enableSeconds && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { className: sepClass, "aria-hidden": "true", children: ":" }), jsxRuntime.jsx(Wheel, { ref: secondsRef, values: secondValues, index: secondIndex, onChange: onSecondIndex, formatLabel: pad2, ariaLabel: t.seconds, visibleCount: visibleCount, itemHeight: itemHeight, disabled: disabled, size: size, color: color, wrap: true, onCommit: onCommit, onFocusPrev: focusPrevOf(secondsRef), onFocusNext: focusNextOf(secondsRef), disabledFor: secondDisabledFor, audioTick: audioTick })] })), hourFormat === '12' && (jsxRuntime.jsx(Wheel, { ref: ampmRef, values: ['AM', 'PM'], index: ampmIndex, onChange: onAmpmIndex, formatLabel: v => v, ariaLabel: t.ampm, visibleCount: visibleCount, itemHeight: itemHeight, disabled: disabled, size: size, color: color, onCommit: onCommit, onFocusPrev: focusPrevOf(ampmRef), onFocusNext: focusNextOf(ampmRef), audioTick: audioTick }))] }) }));
15108
15229
  };
15109
15230
  TimeWheels.displayName = 'TimeWheels';
15110
15231
 
@@ -15307,7 +15428,11 @@ const TimeInputBase = React.forwardRef((props, ref) => {
15307
15428
  minutes: value?.getMinutes() ?? 0,
15308
15429
  seconds: enableSeconds ? (value?.getSeconds() ?? 0) : undefined,
15309
15430
  };
15310
- const panel = (jsxRuntime.jsxs("div", { className: panelClass, children: [jsxRuntime.jsx(TimeWheels, { value: spinnerValue, onChange: handleSpinnerChange, hourFormat: effectiveHourFormat, enableSeconds: enableSeconds, incrementHours: incrementHours, incrementMinutes: incrementMinutes, incrementSeconds: incrementSeconds, unselectableTimes: unselectableTimes, color: color, size: size, disabled: disabled, id: popoverId, labels: labels, itemHeight: wheelItemHeight, audioTick: effectiveAudioTick, onCommit: () => setOpen(false) }), !inline && !isSmallViewport && (jsxRuntime.jsxs(Buttons, { className: footerClass, hasAddons: true, children: [jsxRuntime.jsx("button", { type: "button", className: footerOkClass, onClick: () => setOpen(false), children: t.ok }), jsxRuntime.jsx("button", { type: "button", className: footerButton, onClick: () => {
15431
+ const panel = (jsxRuntime.jsxs("div", { className: panelClass, children: [jsxRuntime.jsx(TimeWheels, { value: spinnerValue, onChange: handleSpinnerChange, hourFormat: effectiveHourFormat, enableSeconds: enableSeconds, incrementHours: incrementHours, incrementMinutes: incrementMinutes, incrementSeconds: incrementSeconds, unselectableTimes: unselectableTimes, color: color, size: size, disabled: disabled,
15432
+ // The popover panel takes `popoverId`, so the wheels inside it take
15433
+ // one of their own. Inline there is no panel, and the wheels keep
15434
+ // the id they released with.
15435
+ id: inline ? popoverId : `${popoverId}-time`, labels: labels, itemHeight: wheelItemHeight, audioTick: effectiveAudioTick, onCommit: () => setOpen(false) }), !inline && !isSmallViewport && (jsxRuntime.jsxs(Buttons, { className: footerClass, hasAddons: true, children: [jsxRuntime.jsx("button", { type: "button", className: footerOkClass, onClick: () => setOpen(false), children: t.ok }), jsxRuntime.jsx("button", { type: "button", className: footerButton, onClick: () => {
15311
15436
  commitValue(snapTimeToIncrement(new Date(), {
15312
15437
  incrementHours,
15313
15438
  incrementMinutes,
@@ -15385,13 +15510,14 @@ const TimeInput = React.forwardRef((props, ref) => {
15385
15510
  labelProps,
15386
15511
  // Inline mode renders a bare panel with no input to label.
15387
15512
  rendersLabel: ownField && !baseProps.inline,
15513
+ hasInput: !baseProps.inline,
15388
15514
  });
15389
15515
  const helpClass = usePrefixedClassNames('help', {
15390
15516
  [`is-${messageColor}`]: !!messageColor,
15391
15517
  });
15392
15518
  // The base hides its launcher while the Control it sits in is loading,
15393
15519
  // whether that is the one rendered below or an enclosing one.
15394
- let content = (jsxRuntime.jsx(TimeInputBase, { ref: ref, id: controlId, ...baseProps }));
15520
+ let content = (jsxRuntime.jsx(TimeInputBase, { ref: ref, ...baseProps, id: controlId }));
15395
15521
  if (ownControl) {
15396
15522
  content = (jsxRuntime.jsx(Control, { iconLeft: iconLeft, iconRight: iconRight, iconLeftName: iconLeftName, iconRightName: iconRightName, iconLeftSize: iconLeftSize, iconRightSize: iconRightSize, hasIconsLeft: hasIconsLeft || !!iconLeftName, hasIconsRight: hasIconsRight, isLoading: isLoading, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
15397
15523
  }
@@ -15489,6 +15615,7 @@ const DateTimeInputBase = React.forwardRef((props, ref) => {
15489
15615
  const valueAtOpenRef = React.useRef(null);
15490
15616
  const reactId = React.useId();
15491
15617
  const popoverId = id ? `${id}-popover` : `picker-${reactId}`;
15618
+ const timeWheelsId = `${popoverId}-time`;
15492
15619
  const { bulmaHelperClasses, rest: cleanRest } = useBulmaClasses(rest);
15493
15620
  const { shouldUseNative, isSmallViewport } = useNativeMobilePicker({
15494
15621
  force: mobileNative === 'auto' ? undefined : mobileNative,
@@ -15549,17 +15676,14 @@ const DateTimeInputBase = React.forwardRef((props, ref) => {
15549
15676
  // The footer's Time button opens the wheels, and the hours wheel takes
15550
15677
  // focus so the keys turn it straight away. The calendar they cover is
15551
15678
  // inert meanwhile, so no tab stop, pointer or screen reader reaches a day
15552
- // behind them; the attribute is set on the element, as React 18 has no
15553
- // `inert` prop. Closing the wheels hands focus back to the button: focus
15679
+ // behind them. Closing the wheels hands focus back to the button: focus
15554
15680
  // in them would fall to the page as they unmount, and a pointer press
15555
15681
  // outside them has already dropped it on the panel or the page. Focus the
15556
15682
  // keys moved on to the footer, such as Reset, stays there.
15557
15683
  const panelRef = React.useRef(null);
15558
- const calendarRef = React.useRef(null);
15559
15684
  const timeButtonRef = React.useRef(null);
15560
15685
  const timeOverlayRef = React.useRef(null);
15561
15686
  React.useEffect(() => {
15562
- calendarRef.current?.toggleAttribute('inert', timeOpen);
15563
15687
  if (!timeOpen)
15564
15688
  return;
15565
15689
  timeOverlayRef.current
@@ -15697,13 +15821,17 @@ const DateTimeInputBase = React.forwardRef((props, ref) => {
15697
15821
  e.stopPropagation();
15698
15822
  closeTime();
15699
15823
  }
15700
- }, children: [jsxRuntime.jsxs("div", { className: calendarWrapClass, children: [jsxRuntime.jsx("div", { ref: calendarRef, children: jsxRuntime.jsx(Calendar, { value: value, focusedDate: focusedDate, onSelect: handleDateSelect, onFocusedDateChange: setFocusedDate, min: min, max: max, shouldDisableDate: shouldDisableDate, unselectableDates: unselectableDates, firstDayOfWeek: firstDayOfWeek, locale: locale, dayNames: dayNames, monthNames: monthNames, nearbyMonthDays: nearbyMonthDays, color: color, size: size, id: `${popoverId}-cal`, autoFocusCell: open, labels: labels }) }), timeOpen && (jsxRuntime.jsx("div", { ref: timeOverlayRef, className: timeOverlayClass, onClick: e => {
15824
+ }, children: [jsxRuntime.jsxs("div", { className: calendarWrapClass, children: [jsxRuntime.jsx("div", { ...inertProps(timeOpen), children: jsxRuntime.jsx(Calendar, { value: value, focusedDate: focusedDate, onSelect: handleDateSelect, onFocusedDateChange: setFocusedDate, min: min, max: max, shouldDisableDate: shouldDisableDate, unselectableDates: unselectableDates, firstDayOfWeek: firstDayOfWeek, locale: locale, dayNames: dayNames, monthNames: monthNames, nearbyMonthDays: nearbyMonthDays, color: color, size: size, id: `${popoverId}-cal`, autoFocusCell: open, labels: labels }) }), timeOpen && (jsxRuntime.jsx("div", { ref: timeOverlayRef, className: timeOverlayClass, onClick: e => {
15701
15825
  // Tap outside the wheel card (on the covered calendar area)
15702
15826
  // collapses the wheels without selecting a date, matching the
15703
15827
  // native behavior.
15704
15828
  if (e.target === e.currentTarget)
15705
15829
  closeTime();
15706
- }, children: jsxRuntime.jsx("div", { className: timeCardClass, children: jsxRuntime.jsx(TimeWheels, { value: spinnerValue, onChange: handleTimeChange, hourFormat: effectiveHourFormat, enableSeconds: enableSeconds, incrementHours: incrementHours, incrementMinutes: incrementMinutes, incrementSeconds: incrementSeconds, unselectableTimes: unselectableTimes, color: color, size: size, disabled: disabled, id: `${popoverId}-time`, labels: labels, itemHeight: wheelItemHeight, audioTick: effectiveAudioTick, onCommit: () => setOpen(false) }) }) }))] }), jsxRuntime.jsxs("div", { className: footerClass, children: [jsxRuntime.jsxs("button", { ref: timeButtonRef, type: "button", className: footerTimeClass, onClick: () => (timeOpen ? closeTime() : setTimeOpen(true)), "aria-expanded": timeOpen, disabled: disabled, children: [jsxRuntime.jsx("span", { children: t.time }), jsxRuntime.jsx("span", { className: footerTimePillClass, children: value ? formatTime(value, timeDisplayFormat, locale) : '—' })] }), jsxRuntime.jsxs("div", { className: footerActionsClass, children: [jsxRuntime.jsx("button", { type: "button", className: footerResetClass, onClick: () => commitValue(valueAtOpenRef.current), children: t.reset }), jsxRuntime.jsx("button", { type: "button", className: footerDoneClass, "aria-label": t.done, onClick: () => setOpen(false), children: jsxRuntime.jsx("svg", { width: "22", height: "22", viewBox: "0 0 22 22", "aria-hidden": "true", children: jsxRuntime.jsx("path", { d: "M5 11l4 4 8-8", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] })] }));
15830
+ }, children: jsxRuntime.jsx("div", { className: timeCardClass, children: jsxRuntime.jsx(TimeWheels, { value: spinnerValue, onChange: handleTimeChange, hourFormat: effectiveHourFormat, enableSeconds: enableSeconds, incrementHours: incrementHours, incrementMinutes: incrementMinutes, incrementSeconds: incrementSeconds, unselectableTimes: unselectableTimes, color: color, size: size, disabled: disabled, id: timeWheelsId, labels: labels, itemHeight: wheelItemHeight, audioTick: effectiveAudioTick,
15831
+ // Enter on a wheel commits the time, which the wheels already
15832
+ // did live, and closes: the popover, or inline, where there
15833
+ // is no popover, the wheels, as Escape does.
15834
+ onCommit: () => (inline ? closeTime() : setOpen(false)) }) }) }))] }), jsxRuntime.jsxs("div", { className: footerClass, children: [jsxRuntime.jsxs("button", { ref: timeButtonRef, type: "button", className: footerTimeClass, onClick: () => (timeOpen ? closeTime() : setTimeOpen(true)), "aria-expanded": timeOpen, "aria-controls": timeOpen ? timeWheelsId : undefined, disabled: disabled, children: [jsxRuntime.jsx("span", { children: t.time }), jsxRuntime.jsx("span", { className: footerTimePillClass, children: value ? formatTime(value, timeDisplayFormat, locale) : '—' })] }), jsxRuntime.jsxs("div", { className: footerActionsClass, children: [jsxRuntime.jsx("button", { type: "button", className: footerResetClass, onClick: () => commitValue(valueAtOpenRef.current), children: t.reset }), jsxRuntime.jsx("button", { type: "button", className: footerDoneClass, "aria-label": t.done, onClick: () => setOpen(false), children: jsxRuntime.jsx("svg", { width: "22", height: "22", viewBox: "0 0 22 22", "aria-hidden": "true", children: jsxRuntime.jsx("path", { d: "M5 11l4 4 8-8", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round" }) }) })] })] })] }));
15707
15835
  if (inline) {
15708
15836
  return (jsxRuntime.jsxs("div", { ...cleanRest, ref: containerRef, className: classNames(containerClass, bulmaHelperClasses, className), children: [panel, name && (jsxRuntime.jsx("input", { type: "hidden", name: name, form: form, value: value ? toIsoDateTime(value, enableSeconds) : '', required: required }))] }));
15709
15837
  }
@@ -15771,13 +15899,14 @@ const DateTimeInput = React.forwardRef((props, ref) => {
15771
15899
  labelProps,
15772
15900
  // Inline mode renders a bare picker with no input to label.
15773
15901
  rendersLabel: ownField && !baseProps.inline,
15902
+ hasInput: !baseProps.inline,
15774
15903
  });
15775
15904
  const helpClass = usePrefixedClassNames('help', {
15776
15905
  [`is-${messageColor}`]: !!messageColor,
15777
15906
  });
15778
15907
  // The base hides its launcher while the Control it sits in is loading,
15779
15908
  // whether that is the one rendered below or an enclosing one.
15780
- let content = (jsxRuntime.jsx(DateTimeInputBase, { ref: ref, id: controlId, ...baseProps }));
15909
+ let content = (jsxRuntime.jsx(DateTimeInputBase, { ref: ref, ...baseProps, id: controlId }));
15781
15910
  if (ownControl) {
15782
15911
  content = (jsxRuntime.jsx(Control, { iconLeft: iconLeft, iconRight: iconRight, iconLeftName: iconLeftName, iconRightName: iconRightName, iconLeftSize: iconLeftSize, iconRightSize: iconRightSize, hasIconsLeft: hasIconsLeft || !!iconLeftName, hasIconsRight: hasIconsRight, isLoading: isLoading, isExpanded: isExpanded, size: controlSize, className: controlClassName, children: content }));
15783
15912
  }
@@ -16121,6 +16250,7 @@ const DateRangeInput = React.forwardRef((props, ref) => {
16121
16250
  label,
16122
16251
  labelProps,
16123
16252
  rendersLabel: ownField,
16253
+ callerProps: baseProps,
16124
16254
  });
16125
16255
  const helpClass = usePrefixedClassNames('help', {
16126
16256
  [`is-${messageColor}`]: !!messageColor,