@ahrowe/ui 0.33.0 → 0.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (566) hide show
  1. package/README.md +101 -40
  2. package/dist/esm/common/accordion/accordion.mjs +1 -1
  3. package/dist/esm/common/accordion/accordion.mjs.map +1 -1
  4. package/dist/esm/common/accordion/accordion.module.mjs +1 -1
  5. package/dist/esm/common/accordion/accordion.module.mjs.map +1 -1
  6. package/dist/esm/common/accordion/accordion.plain.module.mjs +1 -1
  7. package/dist/esm/common/accordion/accordion.plain.module.mjs.map +1 -1
  8. package/dist/esm/common/accordion/accordion.primary.module.mjs +1 -1
  9. package/dist/esm/common/accordion/accordion.primary.module.mjs.map +1 -1
  10. package/dist/esm/common/accordion/accordion.types.mjs +1 -1
  11. package/dist/esm/common/accordion/accordion.types.mjs.map +1 -1
  12. package/dist/esm/common/actionButtons/actionButtons.mjs +1 -1
  13. package/dist/esm/common/actionButtons/actionButtons.mjs.map +1 -1
  14. package/dist/esm/common/actionButtons/actionButtons.module.mjs +1 -1
  15. package/dist/esm/common/actionIcon/actionIcon.mjs +1 -1
  16. package/dist/esm/common/actionIcon/actionIcon.mjs.map +1 -1
  17. package/dist/esm/common/actionIcon/actionIcon.module.mjs +1 -1
  18. package/dist/esm/common/actionIcon/actionIcon.module.mjs.map +1 -1
  19. package/dist/esm/common/alert/alert.mjs +1 -1
  20. package/dist/esm/common/alert/alert.mjs.map +1 -1
  21. package/dist/esm/common/alert/alert.module.mjs +1 -1
  22. package/dist/esm/common/alert/alert.types.mjs +1 -1
  23. package/dist/esm/common/alert/alert.types.mjs.map +1 -1
  24. package/dist/esm/common/animatedIcon/animatedIcon.mjs +1 -1
  25. package/dist/esm/common/animatedIcon/animatedIcon.mjs.map +1 -1
  26. package/dist/esm/common/animatedIcon/animatedIcon.module.mjs +1 -1
  27. package/dist/esm/common/animatedLogo/animatedLogo.mjs +1 -1
  28. package/dist/esm/common/animatedLogo/animatedLogo.mjs.map +1 -1
  29. package/dist/esm/common/animatedLogo/animatedLogo.module.mjs +1 -1
  30. package/dist/esm/common/animatedText/animatedText.mjs +1 -1
  31. package/dist/esm/common/animatedText/animatedText.mjs.map +1 -1
  32. package/dist/esm/common/animatedText/animatedText.module.mjs +1 -1
  33. package/dist/esm/common/animatedText/animatedText.types.mjs +1 -1
  34. package/dist/esm/common/animatedText/animatedText.types.mjs.map +1 -1
  35. package/dist/esm/common/avatar/avatar.mjs +1 -1
  36. package/dist/esm/common/avatar/avatar.mjs.map +1 -1
  37. package/dist/esm/common/avatar/avatar.module.mjs +1 -1
  38. package/dist/esm/common/avatar/avatarGroup.mjs +1 -1
  39. package/dist/esm/common/avatar/avatarGroup.mjs.map +1 -1
  40. package/dist/esm/common/badge/badge.mjs +1 -1
  41. package/dist/esm/common/badge/badge.mjs.map +1 -1
  42. package/dist/esm/common/badge/badge.module.mjs +1 -1
  43. package/dist/esm/common/badge/badge.types.mjs +1 -1
  44. package/dist/esm/common/badge/badge.types.mjs.map +1 -1
  45. package/dist/esm/common/bodyEnd/bodyEnd.mjs +1 -1
  46. package/dist/esm/common/bodyEnd/bodyEnd.mjs.map +1 -1
  47. package/dist/esm/common/breadcrumb/breadcrumb.mjs +1 -1
  48. package/dist/esm/common/breadcrumb/breadcrumb.mjs.map +1 -1
  49. package/dist/esm/common/breadcrumb/breadcrumb.module.mjs +1 -1
  50. package/dist/esm/common/breadcrumb/breadcrumb.module.mjs.map +1 -1
  51. package/dist/esm/common/button/button.mjs +1 -1
  52. package/dist/esm/common/button/button.mjs.map +1 -1
  53. package/dist/esm/common/button/button.module.mjs +1 -1
  54. package/dist/esm/common/button/button.types.mjs +1 -1
  55. package/dist/esm/common/button/button.types.mjs.map +1 -1
  56. package/dist/esm/common/buttonGroup/buttonGroup.mjs +1 -1
  57. package/dist/esm/common/buttonGroup/buttonGroup.mjs.map +1 -1
  58. package/dist/esm/common/buttonGroup/buttonGroup.module.mjs +1 -1
  59. package/dist/esm/common/buttonGroup/buttonGroup.types.mjs +1 -1
  60. package/dist/esm/common/buttonGroup/buttonGroup.types.mjs.map +1 -1
  61. package/dist/esm/common/card/Card.mjs +1 -1
  62. package/dist/esm/common/card/Card.mjs.map +1 -1
  63. package/dist/esm/common/card/CardActions.mjs +1 -1
  64. package/dist/esm/common/card/CardActions.mjs.map +1 -1
  65. package/dist/esm/common/card/CardContent.mjs +1 -1
  66. package/dist/esm/common/card/CardContent.mjs.map +1 -1
  67. package/dist/esm/common/card/CardHeader.mjs +1 -1
  68. package/dist/esm/common/card/CardHeader.mjs.map +1 -1
  69. package/dist/esm/common/card/CardMedia.mjs +1 -1
  70. package/dist/esm/common/card/CardMedia.mjs.map +1 -1
  71. package/dist/esm/common/card/card.module.mjs +1 -1
  72. package/dist/esm/common/card/card.module.mjs.map +1 -1
  73. package/dist/esm/common/card/card.types.mjs +1 -1
  74. package/dist/esm/common/card/card.types.mjs.map +1 -1
  75. package/dist/esm/common/carousel/carousel.mjs +1 -1
  76. package/dist/esm/common/carousel/carousel.mjs.map +1 -1
  77. package/dist/esm/common/carousel/carousel.module.mjs +1 -1
  78. package/dist/esm/common/checkbox/checkbox.mjs +1 -1
  79. package/dist/esm/common/checkbox/checkbox.mjs.map +1 -1
  80. package/dist/esm/common/checkbox/checkbox.module.mjs +1 -1
  81. package/dist/esm/common/checkbox/checkbox.module.mjs.map +1 -1
  82. package/dist/esm/common/chip/chip.mjs +1 -1
  83. package/dist/esm/common/chip/chip.mjs.map +1 -1
  84. package/dist/esm/common/chip/chip.module.mjs +1 -1
  85. package/dist/esm/common/chip/chip.types.mjs +1 -1
  86. package/dist/esm/common/chip/chip.types.mjs.map +1 -1
  87. package/dist/esm/common/chip/chipContainer.mjs +1 -1
  88. package/dist/esm/common/chip/chipContainer.mjs.map +1 -1
  89. package/dist/esm/common/colorPicker/colorPicker.mjs +1 -1
  90. package/dist/esm/common/colorPicker/colorPicker.mjs.map +1 -1
  91. package/dist/esm/common/colorPicker/colorPicker.module.mjs +1 -1
  92. package/dist/esm/common/colorPicker/colorPicker.module.mjs.map +1 -1
  93. package/dist/esm/common/colorPicker/toHex.mjs +1 -1
  94. package/dist/esm/common/colorPicker/toHex.mjs.map +1 -1
  95. package/dist/esm/common/configProvider/configProvider.mjs +1 -1
  96. package/dist/esm/common/configProvider/configProvider.mjs.map +1 -1
  97. package/dist/esm/common/configProvider/presentation.types.mjs +2 -0
  98. package/dist/esm/common/configProvider/presentation.types.mjs.map +1 -0
  99. package/dist/esm/common/configProvider/useComponentDefaults.mjs +1 -1
  100. package/dist/esm/common/configProvider/useComponentDefaults.mjs.map +1 -1
  101. package/dist/esm/common/configProvider/useLabels.mjs +1 -1
  102. package/dist/esm/common/configProvider/useLabels.mjs.map +1 -1
  103. package/dist/esm/common/configProvider/usePresentationDefault.mjs +1 -1
  104. package/dist/esm/common/configProvider/usePresentationDefault.mjs.map +1 -1
  105. package/dist/esm/common/confirmModal/confirmModal.mjs +1 -1
  106. package/dist/esm/common/confirmModal/confirmModal.mjs.map +1 -1
  107. package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.mjs +1 -1
  108. package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.mjs.map +1 -1
  109. package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.module.mjs +1 -1
  110. package/dist/esm/common/datePicker/components/datePickerMonth/datePickerMonth.module.mjs.map +1 -1
  111. package/dist/esm/common/datePicker/dateFunctions.mjs +1 -1
  112. package/dist/esm/common/datePicker/dateFunctions.mjs.map +1 -1
  113. package/dist/esm/common/datePicker/datePicker.mjs +1 -1
  114. package/dist/esm/common/datePicker/datePicker.mjs.map +1 -1
  115. package/dist/esm/common/datePicker/datePicker.module.mjs +1 -1
  116. package/dist/esm/common/divider/divider.mjs +1 -1
  117. package/dist/esm/common/divider/divider.mjs.map +1 -1
  118. package/dist/esm/common/divider/divider.module.mjs +1 -1
  119. package/dist/esm/common/divider/divider.types.mjs +1 -1
  120. package/dist/esm/common/divider/divider.types.mjs.map +1 -1
  121. package/dist/esm/common/drawer/drawer.mjs +1 -1
  122. package/dist/esm/common/drawer/drawer.mjs.map +1 -1
  123. package/dist/esm/common/drawer/drawer.module.mjs +1 -1
  124. package/dist/esm/common/dropZone/dropZone.mjs +1 -1
  125. package/dist/esm/common/dropZone/dropZone.mjs.map +1 -1
  126. package/dist/esm/common/dropZone/dropZone.module.mjs +1 -1
  127. package/dist/esm/common/dropZone/dropZone.types.mjs +1 -1
  128. package/dist/esm/common/dropZone/dropZone.types.mjs.map +1 -1
  129. package/dist/esm/common/dropdown/dropdown.mjs +1 -1
  130. package/dist/esm/common/dropdown/dropdown.mjs.map +1 -1
  131. package/dist/esm/common/dropdown/dropdown.module.mjs +1 -1
  132. package/dist/esm/common/dropdown/dropdown.module.mjs.map +1 -1
  133. package/dist/esm/common/emptyState/emptyState.mjs +1 -1
  134. package/dist/esm/common/emptyState/emptyState.mjs.map +1 -1
  135. package/dist/esm/common/emptyState/emptyState.module.mjs +1 -1
  136. package/dist/esm/common/errorBoundary/errorBoundary.mjs +1 -1
  137. package/dist/esm/common/errorBoundary/errorBoundary.mjs.map +1 -1
  138. package/dist/esm/common/errorBoundary/errorBoundary.module.mjs +1 -1
  139. package/dist/esm/common/fab/components/fabBase/fabBase.mjs +1 -1
  140. package/dist/esm/common/fab/components/fabBase/fabBase.mjs.map +1 -1
  141. package/dist/esm/common/fab/components/fabBase/fabBase.module.mjs +1 -1
  142. package/dist/esm/common/fab/fab.mjs +1 -1
  143. package/dist/esm/common/fab/fab.mjs.map +1 -1
  144. package/dist/esm/common/fab/fab.module.mjs +1 -1
  145. package/dist/esm/common/fab/fab.module.mjs.map +1 -1
  146. package/dist/esm/common/flip/flip.mjs +1 -1
  147. package/dist/esm/common/flip/flip.mjs.map +1 -1
  148. package/dist/esm/common/flip/flip.module.mjs +1 -1
  149. package/dist/esm/common/floorPlan/floorPlan.faces.mjs +1 -1
  150. package/dist/esm/common/floorPlan/floorPlan.faces.mjs.map +1 -1
  151. package/dist/esm/common/floorPlan/floorPlan.geometry.mjs +1 -1
  152. package/dist/esm/common/floorPlan/floorPlan.geometry.mjs.map +1 -1
  153. package/dist/esm/common/floorPlan/floorPlan.graph.mjs +1 -1
  154. package/dist/esm/common/floorPlan/floorPlan.graph.mjs.map +1 -1
  155. package/dist/esm/common/floorPlan/floorPlan.hit.mjs +1 -1
  156. package/dist/esm/common/floorPlan/floorPlan.hit.mjs.map +1 -1
  157. package/dist/esm/common/floorPlan/floorPlan.json.mjs +1 -1
  158. package/dist/esm/common/floorPlan/floorPlan.json.mjs.map +1 -1
  159. package/dist/esm/common/floorPlan/floorPlan.mesh.mjs +1 -1
  160. package/dist/esm/common/floorPlan/floorPlan.mesh.mjs.map +1 -1
  161. package/dist/esm/common/floorPlan/floorPlan.path.mjs +1 -1
  162. package/dist/esm/common/floorPlan/floorPlan.path.mjs.map +1 -1
  163. package/dist/esm/common/floorPlan/floorPlan.plan.mjs +1 -1
  164. package/dist/esm/common/floorPlan/floorPlan.plan.mjs.map +1 -1
  165. package/dist/esm/common/floorPlan/floorPlan.rooms.mjs +1 -1
  166. package/dist/esm/common/floorPlan/floorPlan.rooms.mjs.map +1 -1
  167. package/dist/esm/common/floorPlan/floorPlan.snap.mjs +1 -1
  168. package/dist/esm/common/floorPlan/floorPlan.snap.mjs.map +1 -1
  169. package/dist/esm/common/floorPlan/floorPlan.triangulate.mjs +1 -1
  170. package/dist/esm/common/floorPlan/floorPlan.triangulate.mjs.map +1 -1
  171. package/dist/esm/common/floorPlan/floorPlan.types.mjs +1 -1
  172. package/dist/esm/common/floorPlan/floorPlan.types.mjs.map +1 -1
  173. package/dist/esm/common/floorPlan/legacySvg.mjs +1 -1
  174. package/dist/esm/common/floorPlan/legacySvg.mjs.map +1 -1
  175. package/dist/esm/common/hooks/useAnchorTracking.mjs +1 -1
  176. package/dist/esm/common/hooks/useAnchorTracking.mjs.map +1 -1
  177. package/dist/esm/common/hooks/useCoarsePointer.mjs +1 -1
  178. package/dist/esm/common/hooks/useCoarsePointer.mjs.map +1 -1
  179. package/dist/esm/common/hooks/useFocusBoundary.mjs +1 -1
  180. package/dist/esm/common/hooks/useFocusBoundary.mjs.map +1 -1
  181. package/dist/esm/common/hooks/useMediaQuery.mjs +1 -1
  182. package/dist/esm/common/hooks/useMediaQuery.mjs.map +1 -1
  183. package/dist/esm/common/hooks/useOverlay.mjs +1 -1
  184. package/dist/esm/common/hooks/useOverlay.mjs.map +1 -1
  185. package/dist/esm/common/hooks/useSheet.mjs +1 -1
  186. package/dist/esm/common/hooks/useSheet.mjs.map +1 -1
  187. package/dist/esm/common/hooks/useSwipeDismiss.mjs +1 -1
  188. package/dist/esm/common/hooks/useSwipeDismiss.mjs.map +1 -1
  189. package/dist/esm/common/hooks/useVisualViewportSize.mjs +1 -1
  190. package/dist/esm/common/hooks/useVisualViewportSize.mjs.map +1 -1
  191. package/dist/esm/common/iconPicker/iconPicker.mjs +1 -1
  192. package/dist/esm/common/iconPicker/iconPicker.mjs.map +1 -1
  193. package/dist/esm/common/iconPicker/iconPicker.module.mjs +1 -1
  194. package/dist/esm/common/idleManager/idleManager.mjs +1 -1
  195. package/dist/esm/common/idleManager/idleManager.mjs.map +1 -1
  196. package/dist/esm/common/infiniteBlock/infiniteBlock.mjs +1 -1
  197. package/dist/esm/common/infiniteBlock/infiniteBlock.mjs.map +1 -1
  198. package/dist/esm/common/infiniteBlock/infiniteBlock.module.mjs +1 -1
  199. package/dist/esm/common/input/input.mjs +1 -1
  200. package/dist/esm/common/input/input.mjs.map +1 -1
  201. package/dist/esm/common/input/input.module.mjs +1 -1
  202. package/dist/esm/common/input/input.module.mjs.map +1 -1
  203. package/dist/esm/common/input/input.types.mjs +1 -1
  204. package/dist/esm/common/input/input.types.mjs.map +1 -1
  205. package/dist/esm/common/inputDropdown/inputDropdown.mjs +1 -1
  206. package/dist/esm/common/inputDropdown/inputDropdown.mjs.map +1 -1
  207. package/dist/esm/common/inputDropdown/inputDropdown.module.mjs +1 -1
  208. package/dist/esm/common/inputDropdown/inputDropdown.module.mjs.map +1 -1
  209. package/dist/esm/common/interactableDiv/index.mjs +1 -1
  210. package/dist/esm/common/interactableDiv/index.mjs.map +1 -1
  211. package/dist/esm/common/interactableDiv/interactableDiv.mjs +1 -1
  212. package/dist/esm/common/interactableDiv/interactableDiv.mjs.map +1 -1
  213. package/dist/esm/common/interactableDiv/interactableDiv.module.mjs +1 -1
  214. package/dist/esm/common/kanbanBoard/KanbanBoard.mjs +1 -1
  215. package/dist/esm/common/kanbanBoard/KanbanBoard.mjs.map +1 -1
  216. package/dist/esm/common/kanbanBoard/KanbanColumn.mjs +1 -1
  217. package/dist/esm/common/kanbanBoard/KanbanColumn.mjs.map +1 -1
  218. package/dist/esm/common/kanbanBoard/KanbanItem.mjs +1 -1
  219. package/dist/esm/common/kanbanBoard/KanbanItem.mjs.map +1 -1
  220. package/dist/esm/common/kanbanBoard/kanbanBoard.module.mjs +1 -1
  221. package/dist/esm/common/kanbanBoard/kanbanBoard.utils.mjs +1 -1
  222. package/dist/esm/common/kanbanBoard/kanbanBoard.utils.mjs.map +1 -1
  223. package/dist/esm/common/klipyPicker/components/gifPreview/gifPreview.mjs +1 -1
  224. package/dist/esm/common/klipyPicker/components/gifPreview/gifPreview.mjs.map +1 -1
  225. package/dist/esm/common/klipyPicker/components/gifPreview/gifPreview.module.mjs +1 -1
  226. package/dist/esm/common/klipyPicker/components/gifView/gifView.mjs +1 -1
  227. package/dist/esm/common/klipyPicker/components/gifView/gifView.mjs.map +1 -1
  228. package/dist/esm/common/klipyPicker/components/gifView/gifView.module.mjs +1 -1
  229. package/dist/esm/common/klipyPicker/klipyPicker.mjs +1 -1
  230. package/dist/esm/common/klipyPicker/klipyPicker.mjs.map +1 -1
  231. package/dist/esm/common/klipyPicker/klipyPicker.module.mjs +1 -1
  232. package/dist/esm/common/loading/iconLoading/iconLoading.mjs +1 -1
  233. package/dist/esm/common/loading/iconLoading/iconLoading.mjs.map +1 -1
  234. package/dist/esm/common/loading/iconLoading/iconLoading.module.mjs +1 -1
  235. package/dist/esm/common/loading/iconLoading/index.mjs +1 -1
  236. package/dist/esm/common/loading/iconLoading/index.mjs.map +1 -1
  237. package/dist/esm/common/loading/spinnerLoading/index.mjs +1 -1
  238. package/dist/esm/common/loading/spinnerLoading/index.mjs.map +1 -1
  239. package/dist/esm/common/loading/spinnerLoading/spinnerLoading.mjs +1 -1
  240. package/dist/esm/common/loading/spinnerLoading/spinnerLoading.mjs.map +1 -1
  241. package/dist/esm/common/loading/spinnerLoading/spinnerLoading.module.mjs +1 -1
  242. package/dist/esm/common/menu/menu.mjs +2 -0
  243. package/dist/esm/common/menu/menu.mjs.map +1 -0
  244. package/dist/esm/common/menu/menu.module.mjs +2 -0
  245. package/dist/esm/common/menu/menu.module.mjs.map +1 -0
  246. package/dist/esm/common/menu/menu.types.mjs +2 -0
  247. package/dist/esm/common/menu/menu.types.mjs.map +1 -0
  248. package/dist/esm/common/modal/modal.mjs +1 -1
  249. package/dist/esm/common/modal/modal.mjs.map +1 -1
  250. package/dist/esm/common/modal/modal.module.mjs +1 -1
  251. package/dist/esm/common/modal/modal.module.mjs.map +1 -1
  252. package/dist/esm/common/multiSelect/multiSelect.mjs +1 -1
  253. package/dist/esm/common/multiSelect/multiSelect.mjs.map +1 -1
  254. package/dist/esm/common/multiSelect/multiSelect.module.mjs +1 -1
  255. package/dist/esm/common/multiSelect/multiSelect.module.mjs.map +1 -1
  256. package/dist/esm/common/numberInput/index.mjs +1 -1
  257. package/dist/esm/common/numberInput/index.mjs.map +1 -1
  258. package/dist/esm/common/numberInput/numberInput.mjs +1 -1
  259. package/dist/esm/common/numberInput/numberInput.mjs.map +1 -1
  260. package/dist/esm/common/numberInput/numberInput.module.mjs +1 -1
  261. package/dist/esm/common/numberInput/useStepRepeat.mjs +1 -1
  262. package/dist/esm/common/numberInput/useStepRepeat.mjs.map +1 -1
  263. package/dist/esm/common/optionPicker/optionPicker.mjs +1 -1
  264. package/dist/esm/common/optionPicker/optionPicker.mjs.map +1 -1
  265. package/dist/esm/common/optionPicker/optionPicker.module.mjs +1 -1
  266. package/dist/esm/common/otpInput/otpInput.mjs +1 -1
  267. package/dist/esm/common/otpInput/otpInput.mjs.map +1 -1
  268. package/dist/esm/common/otpInput/otpInput.module.mjs +1 -1
  269. package/dist/esm/common/otpInput/otpInput.types.mjs +1 -1
  270. package/dist/esm/common/otpInput/otpInput.types.mjs.map +1 -1
  271. package/dist/esm/common/overscroll/overscroll.mjs +1 -1
  272. package/dist/esm/common/overscroll/overscroll.mjs.map +1 -1
  273. package/dist/esm/common/overscroll/overscroll.module.mjs +1 -1
  274. package/dist/esm/common/pagination/pagination.mjs +1 -1
  275. package/dist/esm/common/pagination/pagination.mjs.map +1 -1
  276. package/dist/esm/common/pagination/pagination.module.mjs +1 -1
  277. package/dist/esm/common/planCanvas/planCanvas.mjs +1 -1
  278. package/dist/esm/common/planCanvas/planCanvas.mjs.map +1 -1
  279. package/dist/esm/common/planCanvas/planCanvas.module.mjs +1 -1
  280. package/dist/esm/common/popover/popover.mjs +1 -1
  281. package/dist/esm/common/popover/popover.mjs.map +1 -1
  282. package/dist/esm/common/popover/popover.module.mjs +1 -1
  283. package/dist/esm/common/popover/popover.module.mjs.map +1 -1
  284. package/dist/esm/common/popover/popover.types.mjs +1 -1
  285. package/dist/esm/common/popover/popover.types.mjs.map +1 -1
  286. package/dist/esm/common/popover/usePopoverPosition.mjs +1 -1
  287. package/dist/esm/common/popover/usePopoverPosition.mjs.map +1 -1
  288. package/dist/esm/common/progressBar/progressBar.mjs +1 -1
  289. package/dist/esm/common/progressBar/progressBar.mjs.map +1 -1
  290. package/dist/esm/common/progressBar/progressBar.module.mjs +1 -1
  291. package/dist/esm/common/progressBar/progressBar.module.mjs.map +1 -1
  292. package/dist/esm/common/radioGroup/radioGroup.mjs +1 -1
  293. package/dist/esm/common/radioGroup/radioGroup.mjs.map +1 -1
  294. package/dist/esm/common/radioGroup/radioGroup.module.mjs +1 -1
  295. package/dist/esm/common/radioGroup/radioGroup.module.mjs.map +1 -1
  296. package/dist/esm/common/radioGroup/radioGroup.types.mjs +1 -1
  297. package/dist/esm/common/radioGroup/radioGroup.types.mjs.map +1 -1
  298. package/dist/esm/common/rating/rating.mjs +1 -1
  299. package/dist/esm/common/rating/rating.mjs.map +1 -1
  300. package/dist/esm/common/rating/rating.module.mjs +1 -1
  301. package/dist/esm/common/revealLens/revealLens.mjs +1 -1
  302. package/dist/esm/common/revealLens/revealLens.mjs.map +1 -1
  303. package/dist/esm/common/revealLens/revealLens.module.mjs +1 -1
  304. package/dist/esm/common/ripple/ripple.mjs +1 -1
  305. package/dist/esm/common/ripple/ripple.mjs.map +1 -1
  306. package/dist/esm/common/ripple/ripple.module.mjs +1 -1
  307. package/dist/esm/common/ripple/ripple.module.mjs.map +1 -1
  308. package/dist/esm/common/roomDrawer/roomDrawer.mjs +1 -1
  309. package/dist/esm/common/roomDrawer/roomDrawer.mjs.map +1 -1
  310. package/dist/esm/common/roomDrawer/roomDrawer.module.mjs +1 -1
  311. package/dist/esm/common/roomDrawer/usePlanHistory.mjs +1 -1
  312. package/dist/esm/common/roomDrawer/usePlanHistory.mjs.map +1 -1
  313. package/dist/esm/common/roomViewer/roomViewer.mjs +1 -1
  314. package/dist/esm/common/roomViewer/roomViewer.mjs.map +1 -1
  315. package/dist/esm/common/roomViewer/roomViewer.module.mjs +1 -1
  316. package/dist/esm/common/scrollbarProvider/index.mjs +1 -1
  317. package/dist/esm/common/scrollbarProvider/index.mjs.map +1 -1
  318. package/dist/esm/common/scrollbarProvider/scrollbarProvider.mjs +1 -1
  319. package/dist/esm/common/scrollbarProvider/scrollbarProvider.mjs.map +1 -1
  320. package/dist/esm/common/scrollbarProvider/scrollbarProvider.module.mjs +1 -1
  321. package/dist/esm/common/searchInput/searchInput.mjs +1 -1
  322. package/dist/esm/common/searchInput/searchInput.mjs.map +1 -1
  323. package/dist/esm/common/searchInput/searchInput.module.mjs +1 -1
  324. package/dist/esm/common/sectionHeader/sectionHeader.mjs +1 -1
  325. package/dist/esm/common/sectionHeader/sectionHeader.mjs.map +1 -1
  326. package/dist/esm/common/sectionHeader/sectionHeader.module.mjs +1 -1
  327. package/dist/esm/common/sectionHeader/sectionHeader.types.mjs +1 -1
  328. package/dist/esm/common/sectionHeader/sectionHeader.types.mjs.map +1 -1
  329. package/dist/esm/common/sheetBackdrop/sheetBackdrop.mjs +1 -1
  330. package/dist/esm/common/sheetBackdrop/sheetBackdrop.mjs.map +1 -1
  331. package/dist/esm/common/skeleton/skeleton.mjs +1 -1
  332. package/dist/esm/common/skeleton/skeleton.mjs.map +1 -1
  333. package/dist/esm/common/skeleton/skeleton.module.mjs +1 -1
  334. package/dist/esm/common/skeleton/skeleton.types.mjs +1 -1
  335. package/dist/esm/common/skeleton/skeleton.types.mjs.map +1 -1
  336. package/dist/esm/common/slider/slider.mjs +1 -1
  337. package/dist/esm/common/slider/slider.mjs.map +1 -1
  338. package/dist/esm/common/slider/slider.module.mjs +1 -1
  339. package/dist/esm/common/splitButton/splitButton.mjs +1 -1
  340. package/dist/esm/common/splitButton/splitButton.mjs.map +1 -1
  341. package/dist/esm/common/splitButton/splitButton.module.mjs +1 -1
  342. package/dist/esm/common/splitButton/splitButton.module.mjs.map +1 -1
  343. package/dist/esm/common/stepper/stepper.mjs +1 -1
  344. package/dist/esm/common/stepper/stepper.mjs.map +1 -1
  345. package/dist/esm/common/stepper/stepper.module.mjs +1 -1
  346. package/dist/esm/common/stepper/stepper.types.mjs +1 -1
  347. package/dist/esm/common/stepper/stepper.types.mjs.map +1 -1
  348. package/dist/esm/common/sticky/sticky.mjs +1 -1
  349. package/dist/esm/common/sticky/sticky.mjs.map +1 -1
  350. package/dist/esm/common/sticky/sticky.module.mjs +1 -1
  351. package/dist/esm/common/sticky/stickyStack.mjs +1 -1
  352. package/dist/esm/common/sticky/stickyStack.mjs.map +1 -1
  353. package/dist/esm/common/styles/sheet.module.mjs +1 -1
  354. package/dist/esm/common/styles/sheet.module.mjs.map +1 -1
  355. package/dist/esm/common/switch/switch.mjs +1 -1
  356. package/dist/esm/common/switch/switch.mjs.map +1 -1
  357. package/dist/esm/common/switch/switch.module.mjs +1 -1
  358. package/dist/esm/common/switch/switch.module.mjs.map +1 -1
  359. package/dist/esm/common/tabHeader/tabHeader.mjs +1 -1
  360. package/dist/esm/common/tabHeader/tabHeader.mjs.map +1 -1
  361. package/dist/esm/common/tabHeader/tabHeader.module.mjs +1 -1
  362. package/dist/esm/common/textarea/textarea.mjs +1 -1
  363. package/dist/esm/common/textarea/textarea.mjs.map +1 -1
  364. package/dist/esm/common/themeProvider/defaultTheme.mjs +1 -1
  365. package/dist/esm/common/themeProvider/defaultTheme.mjs.map +1 -1
  366. package/dist/esm/common/themeProvider/lightTheme.mjs +2 -0
  367. package/dist/esm/common/themeProvider/lightTheme.mjs.map +1 -0
  368. package/dist/esm/common/themeProvider/theme.module.mjs +1 -1
  369. package/dist/esm/common/themeProvider/themeProvider.mjs +1 -1
  370. package/dist/esm/common/themeProvider/themeProvider.mjs.map +1 -1
  371. package/dist/esm/common/themeProvider/themeVariablesContext.mjs +1 -1
  372. package/dist/esm/common/themeProvider/themeVariablesContext.mjs.map +1 -1
  373. package/dist/esm/common/themeProvider/useTheme.mjs +1 -1
  374. package/dist/esm/common/themeProvider/useTheme.mjs.map +1 -1
  375. package/dist/esm/common/tilt/tilt.mjs +1 -1
  376. package/dist/esm/common/tilt/tilt.mjs.map +1 -1
  377. package/dist/esm/common/tilt/tilt.module.mjs +1 -1
  378. package/dist/esm/common/tilt/tiltMath.mjs +1 -1
  379. package/dist/esm/common/tilt/tiltMath.mjs.map +1 -1
  380. package/dist/esm/common/tiltGroup/tiltGroup.mjs +1 -1
  381. package/dist/esm/common/tiltGroup/tiltGroup.mjs.map +1 -1
  382. package/dist/esm/common/timeInput/components/clockDial/clockDial.mjs +1 -1
  383. package/dist/esm/common/timeInput/components/clockDial/clockDial.mjs.map +1 -1
  384. package/dist/esm/common/timeInput/components/clockDial/clockDial.module.mjs +1 -1
  385. package/dist/esm/common/timeInput/timeFunctions.mjs +1 -1
  386. package/dist/esm/common/timeInput/timeFunctions.mjs.map +1 -1
  387. package/dist/esm/common/timeInput/timeInput.mjs +1 -1
  388. package/dist/esm/common/timeInput/timeInput.mjs.map +1 -1
  389. package/dist/esm/common/timeInput/timeInput.module.mjs +1 -1
  390. package/dist/esm/common/timeline/timeline.mjs +1 -1
  391. package/dist/esm/common/timeline/timeline.mjs.map +1 -1
  392. package/dist/esm/common/timeline/timeline.module.mjs +1 -1
  393. package/dist/esm/common/timeline/timeline.types.mjs +1 -1
  394. package/dist/esm/common/timeline/timeline.types.mjs.map +1 -1
  395. package/dist/esm/common/timer/timer.chime.mjs +1 -1
  396. package/dist/esm/common/timer/timer.chime.mjs.map +1 -1
  397. package/dist/esm/common/timer/timer.mjs +1 -1
  398. package/dist/esm/common/timer/timer.mjs.map +1 -1
  399. package/dist/esm/common/timer/timer.module.mjs +1 -1
  400. package/dist/esm/common/toast/toast.mjs +1 -1
  401. package/dist/esm/common/toast/toast.mjs.map +1 -1
  402. package/dist/esm/common/toast/toast.module.mjs +1 -1
  403. package/dist/esm/common/toast/toast.module.mjs.map +1 -1
  404. package/dist/esm/common/toast/toastProvider.mjs +1 -1
  405. package/dist/esm/common/toast/toastProvider.mjs.map +1 -1
  406. package/dist/esm/common/toast/toastService.mjs +1 -1
  407. package/dist/esm/common/toast/toastService.mjs.map +1 -1
  408. package/dist/esm/common/tooltip/tooltip.mjs +1 -1
  409. package/dist/esm/common/tooltip/tooltip.mjs.map +1 -1
  410. package/dist/esm/common/tooltip/tooltip.module.mjs +1 -1
  411. package/dist/esm/common/tooltip/tooltip.module.mjs.map +1 -1
  412. package/dist/esm/common/tree/flattenTree.mjs +1 -1
  413. package/dist/esm/common/tree/flattenTree.mjs.map +1 -1
  414. package/dist/esm/common/tree/tree.mjs +1 -1
  415. package/dist/esm/common/tree/tree.mjs.map +1 -1
  416. package/dist/esm/common/tree/tree.module.mjs +1 -1
  417. package/dist/esm/common/tree/tree.module.mjs.map +1 -1
  418. package/dist/esm/common/utils/activationKey.mjs +1 -1
  419. package/dist/esm/common/utils/activationKey.mjs.map +1 -1
  420. package/dist/esm/common/utils/mergeRefs.mjs +2 -0
  421. package/dist/esm/common/utils/mergeRefs.mjs.map +1 -0
  422. package/dist/esm/common/utils/renderIcon.mjs +1 -1
  423. package/dist/esm/common/utils/renderIcon.mjs.map +1 -1
  424. package/dist/esm/common/utils/scrollAncestors.mjs +1 -1
  425. package/dist/esm/common/utils/scrollAncestors.mjs.map +1 -1
  426. package/dist/esm/common/utils/visualViewport.mjs +1 -1
  427. package/dist/esm/common/utils/visualViewport.mjs.map +1 -1
  428. package/dist/esm/common/virtualList/useColumnResize.mjs +1 -1
  429. package/dist/esm/common/virtualList/useColumnResize.mjs.map +1 -1
  430. package/dist/esm/common/virtualList/useColumns.mjs +1 -1
  431. package/dist/esm/common/virtualList/useColumns.mjs.map +1 -1
  432. package/dist/esm/common/virtualList/useHeaderNavigation.mjs +1 -1
  433. package/dist/esm/common/virtualList/useHeaderNavigation.mjs.map +1 -1
  434. package/dist/esm/common/virtualList/useRowDrag.mjs +1 -1
  435. package/dist/esm/common/virtualList/useRowDrag.mjs.map +1 -1
  436. package/dist/esm/common/virtualList/useRowNavigation.mjs +1 -1
  437. package/dist/esm/common/virtualList/useRowNavigation.mjs.map +1 -1
  438. package/dist/esm/common/virtualList/useSelection.mjs +1 -1
  439. package/dist/esm/common/virtualList/useSelection.mjs.map +1 -1
  440. package/dist/esm/common/virtualList/useSorting.mjs +1 -1
  441. package/dist/esm/common/virtualList/useSorting.mjs.map +1 -1
  442. package/dist/esm/common/virtualList/useVirtualWindow.mjs +1 -1
  443. package/dist/esm/common/virtualList/useVirtualWindow.mjs.map +1 -1
  444. package/dist/esm/common/virtualList/virtualList.mjs +1 -1
  445. package/dist/esm/common/virtualList/virtualList.mjs.map +1 -1
  446. package/dist/esm/common/virtualList/virtualList.module.mjs +1 -1
  447. package/dist/esm/common/virtualList/virtualList.module.mjs.map +1 -1
  448. package/dist/esm/common/virtualList/virtualList.utils.mjs +1 -1
  449. package/dist/esm/common/virtualList/virtualList.utils.mjs.map +1 -1
  450. package/dist/esm/common/virtualList/virtualListHeader.mjs +1 -1
  451. package/dist/esm/common/virtualList/virtualListHeader.mjs.map +1 -1
  452. package/dist/esm/common/virtualList/virtualRow.mjs +1 -1
  453. package/dist/esm/common/virtualList/virtualRow.mjs.map +1 -1
  454. package/dist/esm/common/wizard/wizard.mjs +1 -1
  455. package/dist/esm/common/wizard/wizard.mjs.map +1 -1
  456. package/dist/esm/common/wizard/wizard.module.mjs +1 -1
  457. package/dist/esm/hooks/useWindowSize.mjs +1 -1
  458. package/dist/esm/hooks/useWindowSize.mjs.map +1 -1
  459. package/dist/esm/index.mjs +1 -1
  460. package/dist/esm/services/formValidation/FormValidatorGroupWithForm.mjs +1 -1
  461. package/dist/esm/services/formValidation/FormValidatorGroupWithForm.mjs.map +1 -1
  462. package/dist/esm/services/formValidation/index.mjs +1 -1
  463. package/dist/esm/services/formValidation/useFormValidatorGroup.mjs +1 -1
  464. package/dist/esm/services/formValidation/useFormValidatorGroup.mjs.map +1 -1
  465. package/dist/esm/services/formValidation/validatableComponent.mjs +1 -1
  466. package/dist/esm/services/formValidation/validatableComponent.mjs.map +1 -1
  467. package/dist/esm/services/klipy.mjs +1 -1
  468. package/dist/esm/services/klipy.mjs.map +1 -1
  469. package/dist/esm/services/localization.mjs +1 -1
  470. package/dist/esm/services/localization.mjs.map +1 -1
  471. package/dist/index.cjs +3 -3
  472. package/dist/index.cjs.map +1 -1
  473. package/dist/mcp.js +21096 -5
  474. package/dist/style.css +1 -1
  475. package/dist/types/common/actionIcon/actionIcon.types.d.ts +3 -1
  476. package/dist/types/common/card/card.types.d.ts +3 -1
  477. package/dist/types/common/checkbox/checkbox.types.d.ts +3 -1
  478. package/dist/types/common/colorPicker/colorPicker.types.d.ts +4 -0
  479. package/dist/types/common/configProvider/configProvider.d.ts +1 -1
  480. package/dist/types/common/configProvider/configProvider.types.d.ts +6 -3
  481. package/dist/types/common/configProvider/index.d.ts +1 -0
  482. package/dist/types/common/configProvider/presentation.types.d.ts +14 -0
  483. package/dist/types/common/configProvider/usePresentationDefault.d.ts +1 -1
  484. package/dist/types/common/dropdown/dropdown.types.d.ts +1 -1
  485. package/dist/types/common/flip/flip.d.ts +2 -2
  486. package/dist/types/common/flip/flip.types.d.ts +3 -1
  487. package/dist/types/common/hooks/useAnchorTracking.d.ts +1 -1
  488. package/dist/types/common/hooks/useFocusBoundary.d.ts +3 -3
  489. package/dist/types/common/hooks/useSheet.d.ts +1 -1
  490. package/dist/types/common/input/input.types.d.ts +5 -0
  491. package/dist/types/common/interactableDiv/interactableDiv.d.ts +3 -2
  492. package/dist/types/common/loading/spinnerLoading/spinnerLoading.d.ts +0 -5
  493. package/dist/types/common/menu/index.d.ts +2 -0
  494. package/dist/types/common/menu/menu.d.ts +14 -0
  495. package/dist/types/common/menu/menu.types.d.ts +55 -0
  496. package/dist/types/common/modal/modal.types.d.ts +1 -1
  497. package/dist/types/common/multiSelect/multiSelect.types.d.ts +1 -1
  498. package/dist/types/common/numberInput/numberInput.types.d.ts +2 -0
  499. package/dist/types/common/otpInput/otpInput.types.d.ts +2 -0
  500. package/dist/types/common/planCanvas/planCanvas.d.ts +1 -1
  501. package/dist/types/common/planCanvas/planCanvas.types.d.ts +3 -1
  502. package/dist/types/common/popover/popover.types.d.ts +34 -3
  503. package/dist/types/common/popover/usePopoverPosition.d.ts +20 -1
  504. package/dist/types/common/ripple/ripple.d.ts +1 -1
  505. package/dist/types/common/ripple/ripple.types.d.ts +1 -0
  506. package/dist/types/common/roomDrawer/roomDrawer.d.ts +2 -2
  507. package/dist/types/common/roomDrawer/roomDrawer.types.d.ts +3 -1
  508. package/dist/types/common/roomViewer/roomViewer.d.ts +2 -2
  509. package/dist/types/common/roomViewer/roomViewer.types.d.ts +3 -1
  510. package/dist/types/common/searchInput/searchInput.d.ts +1 -1
  511. package/dist/types/common/searchInput/searchInput.types.d.ts +3 -0
  512. package/dist/types/common/splitButton/splitButton.types.d.ts +3 -3
  513. package/dist/types/common/switch/switch.types.d.ts +3 -1
  514. package/dist/types/common/themeProvider/index.d.ts +1 -0
  515. package/dist/types/common/themeProvider/lightTheme.d.ts +13 -0
  516. package/dist/types/common/tilt/tilt.d.ts +2 -2
  517. package/dist/types/common/tilt/tilt.types.d.ts +3 -1
  518. package/dist/types/common/timer/timer.d.ts +2 -2
  519. package/dist/types/common/timer/timer.types.d.ts +3 -1
  520. package/dist/types/common/tooltip/tooltip.d.ts +1 -1
  521. package/dist/types/common/tooltip/tooltip.types.d.ts +7 -0
  522. package/dist/types/common/types/baseProps.types.d.ts +6 -0
  523. package/dist/types/common/utils/mergeRefs.d.ts +12 -0
  524. package/dist/types/common/virtualList/virtualList.d.ts +2 -4
  525. package/dist/types/common/virtualList/virtualList.types.d.ts +3 -1
  526. package/dist/types/index.d.ts +2 -2
  527. package/docs/Accordion.md +9 -0
  528. package/docs/ActionIcon.md +1 -0
  529. package/docs/Breadcrumb.md +2 -2
  530. package/docs/ButtonGroup.md +1 -1
  531. package/docs/CLAUDE.md +38 -1
  532. package/docs/Card.md +2 -1
  533. package/docs/Checkbox.md +1 -0
  534. package/docs/ColorPicker.md +13 -1
  535. package/docs/ConfigProvider.md +2 -2
  536. package/docs/Dropdown.md +1 -1
  537. package/docs/Input.md +1 -0
  538. package/docs/InputDropdown.md +1 -1
  539. package/docs/InteractableDiv.md +2 -0
  540. package/docs/KlipyPicker.md +1 -1
  541. package/docs/Menu.md +107 -0
  542. package/docs/Modal.md +1 -1
  543. package/docs/NumberInput.md +1 -0
  544. package/docs/OtpInput.md +1 -0
  545. package/docs/Popover.md +11 -5
  546. package/docs/SearchInput.md +1 -0
  547. package/docs/SplitButton.md +8 -4
  548. package/docs/Switch.md +1 -0
  549. package/docs/Textarea.md +1 -0
  550. package/docs/ThemeProvider.md +31 -2
  551. package/docs/Tooltip.md +23 -1
  552. package/docs/VirtualList.md +2 -2
  553. package/package.json +8 -7
  554. package/dist/esm/common/floatingMenu/floatingMenu.mjs +0 -2
  555. package/dist/esm/common/floatingMenu/floatingMenu.mjs.map +0 -1
  556. package/dist/esm/common/floatingMenu/floatingMenu.module.mjs +0 -2
  557. package/dist/esm/common/floatingMenu/floatingMenu.module.mjs.map +0 -1
  558. package/dist/esm/common/floatingMenu/floatingMenu.types.mjs +0 -2
  559. package/dist/esm/common/floatingMenu/floatingMenu.types.mjs.map +0 -1
  560. package/dist/esm/common/floatingMenu/useFloatingPosition.mjs +0 -2
  561. package/dist/esm/common/floatingMenu/useFloatingPosition.mjs.map +0 -1
  562. package/dist/types/common/floatingMenu/floatingMenu.d.ts +0 -3
  563. package/dist/types/common/floatingMenu/floatingMenu.types.d.ts +0 -32
  564. package/dist/types/common/floatingMenu/index.d.ts +0 -2
  565. package/dist/types/common/floatingMenu/useFloatingPosition.d.ts +0 -27
  566. package/docs/FloatingMenu.md +0 -90
package/docs/Switch.md CHANGED
@@ -46,6 +46,7 @@ const notifyValidator = new FormValidator(false);
46
46
  | `disabled` | `boolean` | |
47
47
  | `children` | `ReactNode` | Custom label content (overrides `label`) |
48
48
  | `tabIndex` | `number` | |
49
+ | `ref` | `Ref<HTMLDivElement>` | Ref to the root element |
49
50
 
50
51
  **Sizing:** the track and thumb are dimensioned in `em`, so the whole switch scales with the inherited `font-size` — no dedicated size prop. Use `style={{ fontSize: ... }}` to scale everything together, or the `track`/`thumb` slots (`classNames`/`styles`) to resize just those parts.
51
52
 
package/docs/Textarea.md CHANGED
@@ -40,5 +40,6 @@ const descValidator = new FormValidator('', [Validators.required(), Validators.m
40
40
  | `formValidator` | `FormValidator` | Connects to validation |
41
41
  | `placeholder` | `string` | |
42
42
  | `readOnly` | `boolean` | |
43
+ | `ref` | `Ref<HTMLTextAreaElement>` | Ref to the inner `<textarea>` |
43
44
 
44
45
  **Slots:** Same as `Input` — `label` `container` `input` `suffix` `upperRightLabel` `fieldset`
@@ -5,7 +5,8 @@
5
5
  **Keywords:** theming, dark mode, gradient
6
6
 
7
7
  **Import:** `import { ThemeProvider } from '@ahrowe/ui'`
8
- **Types:** `import type { Theme, ThemeVariables } from '@ahrowe/ui'`
8
+ **Types:** `import type { Theme, ThemeVariables } from '@ahrowe/ui'`
9
+ **Built-in themes:** `import { defaultTheme, lightTheme } from '@ahrowe/ui'`
9
10
 
10
11
  ```tsx
11
12
  import { ThemeProvider } from '@ahrowe/ui';
@@ -50,6 +51,34 @@ const darkTheme: Theme = {
50
51
  </ThemeProvider>
51
52
  ```
52
53
 
54
+ ## The two built-in themes
55
+
56
+ The package ships a pair. `defaultTheme` is dark and is what `ThemeProvider` applies when you pass
57
+ no `themes` at all. `lightTheme` is its light sibling: same brand colour, inverted surfaces. Pass
58
+ both to let the user choose.
59
+
60
+ ```tsx
61
+ import { ThemeProvider, defaultTheme, lightTheme, useTheme } from '@ahrowe/ui';
62
+
63
+ function App() {
64
+ const { currentThemeId, setCurrentThemeId } = useTheme(defaultTheme.id);
65
+
66
+ return (
67
+ <ThemeProvider themes={[defaultTheme, lightTheme]} currentThemeId={currentThemeId}>
68
+ <button onClick={() => setCurrentThemeId(currentThemeId === 'light' ? 'default' : 'light')}>
69
+ Toggle theme
70
+ </button>
71
+ <App />
72
+ </ThemeProvider>
73
+ );
74
+ }
75
+ ```
76
+
77
+ `lightTheme` declares only the twenty-odd variables that have to flip and inherits the rest through
78
+ `baseThemeId: 'default'`. That is the shape to copy for your own theme: override what your brand
79
+ changes, inherit everything else, so a new variable added to the library reaches your theme without
80
+ you touching it.
81
+
53
82
  **Theme type:**
54
83
 
55
84
  ```ts
@@ -175,5 +204,5 @@ through its own variable (`--slider-range-color`, `--pagination-active-backgroun
175
204
 
176
205
  Providers nest: an inner one overrides the variables it declares and inherits the rest, so a differently-themed panel inside a themed app works without restating the whole theme.
177
206
 
178
- A portal breaks that by default, because theme variables travel by CSS inheritance and a portal escapes the subtree. Anything rendered through `BodyEnd` — `Tooltip`, `Dropdown`, `InputDropdown`, `ColorPicker`, `FloatingMenu`, `Popover`, `Modal`, `Toast` — therefore carries the nearest provider's variables with it, so an open panel matches the panel that opened it rather than whatever wraps `#bodyEnd`.
207
+ A portal breaks that by default, because theme variables travel by CSS inheritance and a portal escapes the subtree. Anything rendered through `BodyEnd` — `Tooltip`, `Dropdown`, `InputDropdown`, `ColorPicker`, `Menu`, `Popover`, `Modal`, `Toast` — therefore carries the nearest provider's variables with it, so an open panel matches the panel that opened it rather than whatever wraps `#bodyEnd`.
179
208
 
package/docs/Tooltip.md CHANGED
@@ -4,7 +4,8 @@
4
4
 
5
5
  **Keywords:** hint, help text, info bubble
6
6
 
7
- **Import:** `import { Tooltip } from '@ahrowe/ui'`
7
+ **Import:** `import { Tooltip } from '@ahrowe/ui'`
8
+ **Types:** `import type { TooltipProps, TooltipVariant, TooltipLabels } from '@ahrowe/ui'`
8
9
 
9
10
  ```tsx
10
11
  import { Tooltip } from '@ahrowe/ui';
@@ -39,6 +40,27 @@ import { Tooltip } from '@ahrowe/ui';
39
40
  | `iconPosition` | `string` | CSS positioning for the icon |
40
41
  | `tooltipPosition` | `string` | CSS positioning for the bubble |
41
42
  | `onClick` | `() => void` | Click handler on the icon |
43
+ | `labels` | `TooltipLabels` | Overrides the text Tooltip renders of its own. Merged per key |
44
+
45
+ **Labels:** `details` (accessible name of the `details` variant's `?` badge, default `More information`).
46
+
47
+ ## Accessibility
48
+
49
+ The bubble carries `role="tooltip"`, and while it is shown the element it sits inside gains an
50
+ `aria-describedby` pointing at it, so a screen reader reads the tooltip as the description of the
51
+ field or control it explains. The attribute is removed again when the bubble goes.
52
+
53
+ The `error` variant is `role="alert"` instead: it appears in answer to something the user just
54
+ did, and a description is only read out when its trigger is focused, which a field the user has
55
+ already left is not.
56
+
57
+ The `details` badge is a real control. It takes focus, opens on focus as well as hover, toggles on
58
+ Enter and Space, and reports its state through `aria-expanded`. Give it a translated name through
59
+ `labels.details`.
60
+
61
+ ```tsx
62
+ <Tooltip variant="details" message="Last updated: 2 hours ago" labels={{ details: 'Mehr Informationen' }} />
63
+ ```
42
64
 
43
65
  The bubble is rendered through a portal and tracks its trigger's position directly, so it always escapes clipping ancestors (cards, scroll containers, virtualized lists) — no `position: relative` wrapper is required. It flips to the opposite side automatically when there's no room in its preferred direction, and hides (without losing state) if the trigger itself scrolls behind a clipping ancestor, reappearing once it's back in view.
44
66
 
@@ -7,7 +7,7 @@
7
7
  **Import:** `import { VirtualList } from '@ahrowe/ui'`
8
8
  **Types:** `import type { VirtualListProps, VirtualListColumn, VirtualListHandle, VirtualListSort } from '@ahrowe/ui'`
9
9
 
10
- **Requires:** `<div id="bodyEnd"></div>` in your app **only if** you use the column-visibility toggle (the gear menu) — its popover is a `FloatingMenu` that renders via portal. Lists without columns, or with `showColumnToggle={false}`, don't need it.
10
+ **Requires:** `<div id="bodyEnd"></div>` in your app **only if** you use the column-visibility toggle (the gear menu) — its popover is a `Popover` that renders via portal. Lists without columns, or with `showColumnToggle={false}`, don't need it.
11
11
 
12
12
  ```tsx
13
13
  import { VirtualList } from '@ahrowe/ui';
@@ -367,4 +367,4 @@ This needs the list to have a **bounded height** (the default `height="100%"` in
367
367
 
368
368
  **Labels:** `selectRow` `selectAllRows` `toggleColumns` `columnsHidden(count)` `resetColumnWidths` — the text this component renders of its own. Pass `labels` to override any of them, on the component or app-wide through `ConfigProvider`; they merge per key. Type: `VirtualListLabels`.
369
369
 
370
- **In-row popovers:** Rows support inline popover content that overflows the row's bottom edge — e.g. a `Dropdown`, `InputDropdown`, `Tooltip`, or `FloatingMenu` whose list opens below its trigger. All four render their popover through a `BodyEnd` portal and track their trigger's position directly, so they always escape row/cell clipping and paint above the rows below, regardless of focus — no special CSS is needed on the row or cell for this. Cells still clip their own content by default (ellipsis / neighbour-spill guard); that's unaffected. This works in both list mode (`renderRow`) and table mode (`columns`). Stop the row's click handler from firing when interacting with the control (`onClick={(e) => e.stopPropagation()}` on the cell) if the row is also selectable.
370
+ **In-row popovers:** Rows support inline popover content that overflows the row's bottom edge — e.g. a `Dropdown`, `InputDropdown`, `Tooltip`, or `Popover` whose list opens below its trigger. All four render their popover through a `BodyEnd` portal and track their trigger's position directly, so they always escape row/cell clipping and paint above the rows below, regardless of focus — no special CSS is needed on the row or cell for this. Cells still clip their own content by default (ellipsis / neighbour-spill guard); that's unaffected. This works in both list mode (`renderRow`) and table mode (`columns`). Stop the row's click handler from firing when interacting with the control (`onClick={(e) => e.stopPropagation()}` on the cell) if the row is also selectable.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ahrowe/ui",
3
- "version": "0.33.0",
3
+ "version": "0.35.0",
4
4
  "description": "A React UI component library with theming, CSS Modules, and TypeScript support",
5
5
  "keywords": [
6
6
  "components",
@@ -59,6 +59,7 @@
59
59
  "lint": "run-p run-tsc run-oxlint run-stylelint run-oxfmt",
60
60
  "gen-barrel": "tsx scripts/gen-barrel.ts",
61
61
  "gen-theme-map": "tsx scripts/gen-theme-map.ts",
62
+ "gen-readme-table": "tsx scripts/gen-readme-table.ts",
62
63
  "gc": "tsx scripts/generate-component.ts",
63
64
  "changeset": "changeset",
64
65
  "release": "bash src/scripts/release.sh",
@@ -74,18 +75,17 @@
74
75
  "@dnd-kit/core": "^6.3.1",
75
76
  "@dnd-kit/sortable": "^10.0.0",
76
77
  "@dnd-kit/utilities": "^3.2.2",
77
- "@modelcontextprotocol/sdk": "^1.30.0",
78
78
  "@mona-health/react-input-mask": "^3.0.3",
79
79
  "classnames": "^2.5.1",
80
80
  "downshift": "^9.4.0",
81
- "react-number-format": "^5.4.5",
82
- "zod": "^4.6.5"
81
+ "react-number-format": "^5.4.5"
83
82
  },
84
83
  "devDependencies": {
85
84
  "@changesets/cli": "^3.0.3",
86
85
  "@fortawesome/fontawesome-svg-core": "^7.3.1",
87
86
  "@fortawesome/free-solid-svg-icons": "^7.3.1",
88
87
  "@fortawesome/react-fontawesome": "^3.5.0",
88
+ "@modelcontextprotocol/sdk": "^1.30.0",
89
89
  "@testing-library/dom": "^10.4.2",
90
90
  "@testing-library/jest-dom": "^7.0.1",
91
91
  "@testing-library/react": "^16.3.3",
@@ -120,14 +120,15 @@
120
120
  "typescript": "^6.0.3",
121
121
  "vite": "^8.3.0",
122
122
  "vite-plugin-dts": "^5.1.0",
123
- "vitest": "^5.0.1"
123
+ "vitest": "^5.0.1",
124
+ "zod": "^4.6.5"
124
125
  },
125
126
  "peerDependencies": {
126
127
  "@fortawesome/fontawesome-svg-core": ">=6.0.0",
127
128
  "@fortawesome/free-solid-svg-icons": ">=6.0.0",
128
129
  "@fortawesome/react-fontawesome": ">=0.2.0",
129
- "react": ">=18.0.0",
130
- "react-dom": ">=18.0.0"
130
+ "react": ">=19.0.0",
131
+ "react-dom": ">=19.0.0"
131
132
  },
132
133
  "lint-staged": {
133
134
  "*.{ts,tsx}": "vitest related --run"
@@ -1,2 +0,0 @@
1
- import{useComponentDefaults as e}from"../configProvider/useComponentDefaults.mjs";import{usePresentationDefault as t}from"../configProvider/usePresentationDefault.mjs";import n from"../bodyEnd/bodyEnd.mjs";import r from"./floatingMenu.module.mjs";import i from"../styles/sheet.module.mjs";import a from"../sheetBackdrop/sheetBackdrop.mjs";import{useFloatingPosition as o}from"./useFloatingPosition.mjs";import{tabbablesIn as s,useFocusBoundary as c}from"../hooks/useFocusBoundary.mjs";import{Align as l,Presentation as u}from"./floatingMenu.types.mjs";import d from"../hooks/useSheet.mjs";import{useOverlay as f}from"../hooks/useOverlay.mjs";import{useEffect as p,useRef as m,useState as h}from"react";import g from"classnames";import{jsx as _,jsxs as v}from"react/jsx-runtime";function y(e){return e.charAt(0).toUpperCase()+e.slice(1)}function b(b){let{align:x=l.Left,children:S=null,content:C=null,isOpen:w=!1,onOpenChange:T=()=>{},dontCloseOnChildClick:E=!1,presentation:D,className:O,style:k,classNames:A,styles:j,...M}=e(`FloatingMenu`,b),N=m(null),P=m(null),F=m(null),I=m(T),[L,R]=h(10),z=m(!1);function B(){z.current=!0}p(()=>{I.current=T});function V(){if(w){E||T(!1);return}let e=F.current?.getBoundingClientRect();R(e?.width??10),T(!0)}let H=t(),U=D??H??u.Default,{isSheet:W,sheetStyle:G}=d(U);o({isOpen:w&&!W,triggerRef:F,anchorRef:P,panelRef:N,flipClassName:r.floatingMenuAnimFlip}),p(()=>{if(!w)return;function e(e){let t=N.current,n=F.current;if(!t||!n)return;let r=e.target;if(n===r||n.contains(r))return;let i=z.current;z.current=!1,(!(i||t===r||t.contains(r))||!E)&&I.current(!1)}return window.addEventListener(`mouseup`,e),()=>window.removeEventListener(`mouseup`,e)},[w,E]);let{restoreFocusToTrigger:K,focusAfterTrigger:q}=c({triggerRef:F,contentRef:N});f({isActive:w,containerRef:N,onEscape:()=>{N.current?.contains(document.activeElement)&&K(),I.current(!1)},trapFocus:!1,lockScroll:W});function J(e){if(e.key!==`Tab`)return;let t=s(N.current);if(t.length===0)return;let n=document.activeElement;!e.shiftKey&&n===t[t.length-1]?(e.preventDefault(),q(),I.current(!1)):e.shiftKey&&n===t[0]&&(e.preventDefault(),K(),I.current(!1))}return v(`div`,{...M,className:g(r.floatingMenu,O,A?.root),style:{...k,...j?.root},children:[_(`div`,{className:g(r.floatingMenuContent,A?.trigger),style:j?.trigger,ref:F,onClick:V,children:S}),w&&v(n,{children:[W&&_(a,{onClose:()=>I.current(!1),className:A?.backdrop,style:j?.backdrop}),v(`div`,{ref:P,className:g(W?i.sheet:r.floatingMenuAnim,A?.menu),style:{...W?G:{width:`${L}px`},...j?.menu},children:[!W&&_(`div`,{className:g(r.floatingMenuContainerFlag,r[`floatingMenuContainerFlagAlign${y(x)}`])}),_(`div`,{ref:N,className:g(r.floatingMenuContainer,W?i.sheetPanel:[r.floatingMenuContainerAnchored,r[`floatingMenuContainerAlign${y(x)}`]],A?.menuContainer),style:j?.menuContainer,onMouseUpCapture:B,onKeyDown:J,children:C})]})]})]})}export{b as default};
2
- //# sourceMappingURL=floatingMenu.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"floatingMenu.mjs","names":[],"sources":["../../../../package/common/floatingMenu/floatingMenu.tsx"],"sourcesContent":["import { useRef, useEffect, useState } from 'react';\nimport cx from 'classnames';\nimport BodyEnd from 'components/common/bodyEnd';\n\nimport styles from './floatingMenu.module.pcss';\nimport sheetStyles from '../styles/sheet.module.pcss';\nimport SheetBackdrop from '../sheetBackdrop';\nimport { useFloatingPosition } from './useFloatingPosition';\nimport { useFocusBoundary, tabbablesIn } from '../hooks/useFocusBoundary';\nimport { useSheet } from '../hooks/useSheet';\nimport { useOverlay } from '../hooks/useOverlay';\nimport { useComponentDefaults, usePresentationDefault } from '../configProvider';\nimport { Align, Presentation, FloatingMenuProps } from './floatingMenu.types';\n\nfunction capitalize(s: string) {\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n\nfunction FloatingMenu(props: FloatingMenuProps) {\n const {\n align = Align.Left,\n children = null,\n content = null,\n isOpen = false,\n onOpenChange = () => {},\n dontCloseOnChildClick = false,\n presentation: presentationProp,\n className,\n style,\n classNames,\n styles: slotStyles,\n ...rest\n } = useComponentDefaults('FloatingMenu', props);\n const menuContainerRef = useRef<HTMLDivElement>(null);\n const menuAnimRef = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n const onOpenChangeRef = useRef(onOpenChange);\n const [triggerWidth, setTriggerWidth] = useState(10);\n\n const contentInteractedRef = useRef(false);\n function handleContentMouseUp() {\n contentInteractedRef.current = true;\n }\n\n useEffect(() => {\n onOpenChangeRef.current = onOpenChange;\n });\n\n function handleTriggerClick() {\n if (isOpen) {\n if (!dontCloseOnChildClick) onOpenChange(false);\n return;\n }\n const rect = triggerRef.current?.getBoundingClientRect();\n setTriggerWidth(rect?.width ?? 10);\n onOpenChange(true);\n }\n\n // Explicit prop → this component's global default → the app-wide one → anchored.\n const appPresentation = usePresentationDefault();\n const presentation = presentationProp ?? appPresentation ?? Presentation.Default;\n const { isSheet, sheetStyle } = useSheet(presentation);\n\n // A sheet isn't anchored to anything, so there's nothing to track, flip or clamp.\n useFloatingPosition({\n isOpen: isOpen && !isSheet,\n triggerRef,\n anchorRef: menuAnimRef,\n panelRef: menuContainerRef,\n flipClassName: styles.floatingMenuAnimFlip,\n });\n\n useEffect(() => {\n if (!isOpen) return;\n\n function onMouseUp(event: MouseEvent) {\n const menuElem = menuContainerRef.current;\n const triggerElem = triggerRef.current;\n if (!menuElem || !triggerElem) return;\n\n const target = event.target as Node;\n if (triggerElem === target || triggerElem.contains(target)) return;\n\n const contentInteracted = contentInteractedRef.current;\n contentInteractedRef.current = false;\n const clickedInMenu = contentInteracted || menuElem === target || menuElem.contains(target);\n\n if (!clickedInMenu || !dontCloseOnChildClick) {\n onOpenChangeRef.current(false);\n }\n }\n\n window.addEventListener('mouseup', onMouseUp);\n return () => window.removeEventListener('mouseup', onMouseUp);\n }, [isOpen, dontCloseOnChildClick]);\n\n const { restoreFocusToTrigger, focusAfterTrigger } = useFocusBoundary({\n triggerRef,\n contentRef: menuContainerRef,\n });\n\n // Registered for as long as the menu is open, not just as a sheet: this is what puts it on the\n // overlay stack, so an enclosing Modal knows something sits above it. Without that, the modal\n // stays topmost and its focus trap drags focus out of this menu — which lives outside the\n // modal's panel, in the portal — and Escape closes the modal instead of just this menu.\n // Focus is deliberately not trapped: the menu doesn't take focus on open (see\n // `handleMenuKeyDown`), so there'd be nothing inside to trap.\n useOverlay({\n isActive: isOpen,\n containerRef: menuContainerRef,\n onEscape: () => {\n if (menuContainerRef.current?.contains(document.activeElement)) restoreFocusToTrigger();\n onOpenChangeRef.current(false);\n },\n trapFocus: false,\n lockScroll: isSheet,\n });\n\n // The menu is portaled to the end of the DOM, so Tab never flows into it naturally. When\n // `content` has real focusable elements, close on Tab out of either end and continue focus as\n // if the menu sat right after the trigger. Escape is handled by `useOverlay` above instead, so\n // that it works from the trigger too and closes only the innermost open layer.\n // Unlike Popover, this doesn't also auto-focus the\n // first element on open, content here ranges from menus to live controls like ColorPicker's\n // hue slider, where grabbing focus on open would let a stray arrow-key press nudge a value the\n // user never interacted with. Auto-focus-on-open is still worth doing per-consumer (e.g.\n // SplitButton focuses its first enabled action), just not assumed generically here.\n function handleMenuKeyDown(event: React.KeyboardEvent) {\n if (event.key !== 'Tab') return;\n const focusables = tabbablesIn(menuContainerRef.current);\n if (focusables.length === 0) return;\n const active = document.activeElement;\n if (!event.shiftKey && active === focusables[focusables.length - 1]) {\n event.preventDefault();\n focusAfterTrigger();\n onOpenChangeRef.current(false);\n } else if (event.shiftKey && active === focusables[0]) {\n event.preventDefault();\n restoreFocusToTrigger();\n onOpenChangeRef.current(false);\n }\n }\n\n return (\n <div\n {...rest}\n className={cx(styles.floatingMenu, className, classNames?.root)}\n style={{ ...style, ...slotStyles?.root }}\n >\n <div\n className={cx(styles.floatingMenuContent, classNames?.trigger)}\n style={slotStyles?.trigger}\n ref={triggerRef}\n onClick={handleTriggerClick}\n >\n {children}\n </div>\n {isOpen && (\n <BodyEnd>\n {isSheet && (\n <SheetBackdrop\n onClose={() => onOpenChangeRef.current(false)}\n className={classNames?.backdrop}\n style={slotStyles?.backdrop}\n />\n )}\n <div\n ref={menuAnimRef}\n className={cx(isSheet ? sheetStyles.sheet : styles.floatingMenuAnim, classNames?.menu)}\n style={{\n // A sheet spans the screen; only an anchored menu takes the trigger's width.\n ...(isSheet ? sheetStyle : { width: `${triggerWidth}px` }),\n ...slotStyles?.menu,\n }}\n >\n {!isSheet && (\n <div\n className={cx(\n styles.floatingMenuContainerFlag,\n styles[`floatingMenuContainerFlagAlign${capitalize(align)}`],\n )}\n />\n )}\n <div\n ref={menuContainerRef}\n className={cx(\n styles.floatingMenuContainer,\n isSheet\n ? sheetStyles.sheetPanel\n : [styles.floatingMenuContainerAnchored, styles[`floatingMenuContainerAlign${capitalize(align)}`]],\n classNames?.menuContainer,\n )}\n style={slotStyles?.menuContainer}\n onMouseUpCapture={handleContentMouseUp}\n onKeyDown={handleMenuKeyDown}\n >\n {content}\n </div>\n </div>\n </BodyEnd>\n )}\n </div>\n );\n}\n\nexport default FloatingMenu;\n"],"mappings":"0wBAcA,SAAS,EAAW,EAAW,CAC7B,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,EAAI,EAAE,MAAM,CAAC,CAC9C,CAEA,SAAS,EAAa,EAA0B,CAC9C,GAAM,CACJ,QAAQ,EAAM,KACd,WAAW,KACX,UAAU,KACV,SAAS,GACT,mBAAqB,CAAC,EACtB,wBAAwB,GACxB,aAAc,EACd,YACA,QACA,aACA,OAAQ,EACR,GAAG,GACD,EAAqB,eAAgB,CAAK,EACxC,EAAmB,EAAuB,IAAI,EAC9C,EAAc,EAAuB,IAAI,EACzC,EAAa,EAAuB,IAAI,EACxC,EAAkB,EAAO,CAAY,EACrC,CAAC,EAAc,GAAmB,EAAS,EAAE,EAE7C,EAAuB,EAAO,EAAK,EACzC,SAAS,GAAuB,CAC9B,EAAqB,QAAU,EACjC,CAEA,MAAgB,CACd,EAAgB,QAAU,CAC5B,CAAC,EAED,SAAS,GAAqB,CAC5B,GAAI,EAAQ,CACL,GAAuB,EAAa,EAAK,EAC9C,MACF,CACA,IAAM,EAAO,EAAW,SAAS,sBAAsB,EACvD,EAAgB,GAAM,OAAS,EAAE,EACjC,EAAa,EAAI,CACnB,CAGA,IAAM,EAAkB,EAAuB,EACzC,EAAe,GAAoB,GAAmB,EAAa,QACnE,CAAE,UAAS,cAAe,EAAS,CAAY,EAGrD,EAAoB,CAClB,OAAQ,GAAU,CAAC,EACnB,aACA,UAAW,EACX,SAAU,EACV,cAAe,EAAO,oBACxB,CAAC,EAED,MAAgB,CACd,GAAI,CAAC,EAAQ,OAEb,SAAS,EAAU,EAAmB,CACpC,IAAM,EAAW,EAAiB,QAC5B,EAAc,EAAW,QAC/B,GAAI,CAAC,GAAY,CAAC,EAAa,OAE/B,IAAM,EAAS,EAAM,OACrB,GAAI,IAAgB,GAAU,EAAY,SAAS,CAAM,EAAG,OAE5D,IAAM,EAAoB,EAAqB,QAC/C,EAAqB,QAAU,IAG3B,EAFkB,GAAqB,IAAa,GAAU,EAAS,SAAS,CAAM,IAEpE,CAAC,IACrB,EAAgB,QAAQ,EAAK,CAEjC,CAGA,OADA,OAAO,iBAAiB,UAAW,CAAS,MAC/B,OAAO,oBAAoB,UAAW,CAAS,CAC9D,EAAG,CAAC,EAAQ,CAAqB,CAAC,EAElC,GAAM,CAAE,wBAAuB,qBAAsB,EAAiB,CACpE,aACA,WAAY,CACd,CAAC,EAQD,EAAW,CACT,SAAU,EACV,aAAc,EACd,aAAgB,CACV,EAAiB,SAAS,SAAS,SAAS,aAAa,GAAG,EAAsB,EACtF,EAAgB,QAAQ,EAAK,CAC/B,EACA,UAAW,GACX,WAAY,CACd,CAAC,EAWD,SAAS,EAAkB,EAA4B,CACrD,GAAI,EAAM,MAAQ,MAAO,OACzB,IAAM,EAAa,EAAY,EAAiB,OAAO,EACvD,GAAI,EAAW,SAAW,EAAG,OAC7B,IAAM,EAAS,SAAS,cACpB,CAAC,EAAM,UAAY,IAAW,EAAW,EAAW,OAAS,IAC/D,EAAM,eAAe,EACrB,EAAkB,EAClB,EAAgB,QAAQ,EAAK,GACpB,EAAM,UAAY,IAAW,EAAW,KACjD,EAAM,eAAe,EACrB,EAAsB,EACtB,EAAgB,QAAQ,EAAK,EAEjC,CAEA,OACE,EAAC,MAAD,CACE,GAAI,EACJ,UAAW,EAAG,EAAO,aAAc,EAAW,GAAY,IAAI,EAC9D,MAAO,CAAE,GAAG,EAAO,GAAG,GAAY,IAAK,EAHzC,SAAA,CAKE,EAAC,MAAD,CACE,UAAW,EAAG,EAAO,oBAAqB,GAAY,OAAO,EAC7D,MAAO,GAAY,QACnB,IAAK,EACL,QAAS,EAER,UACE,CAAA,EACJ,GACC,EAAC,EAAD,CAAA,SAAA,CACG,GACC,EAAC,EAAD,CACE,YAAe,EAAgB,QAAQ,EAAK,EAC5C,UAAW,GAAY,SACvB,MAAO,GAAY,QACpB,CAAA,EAEH,EAAC,MAAD,CACE,IAAK,EACL,UAAW,EAAG,EAAU,EAAY,MAAQ,EAAO,iBAAkB,GAAY,IAAI,EACrF,MAAO,CAEL,GAAI,EAAU,EAAa,CAAE,MAAO,GAAG,EAAa,GAAI,EACxD,GAAG,GAAY,IACjB,EAPF,SAAA,CASG,CAAC,GACA,EAAC,MAAD,CACE,UAAW,EACT,EAAO,0BACP,EAAO,iCAAiC,EAAW,CAAK,IAC1D,CACD,CAAA,EAEH,EAAC,MAAD,CACE,IAAK,EACL,UAAW,EACT,EAAO,sBACP,EACI,EAAY,WACZ,CAAC,EAAO,8BAA+B,EAAO,6BAA6B,EAAW,CAAK,IAAI,EACnG,GAAY,aACd,EACA,MAAO,GAAY,cACnB,iBAAkB,EAClB,UAAW,EAEV,SAAA,CACE,CAAA,CACF,CACE,CAAA,CAAA,CAAA,CAAA,CAER,GAET"}
@@ -1,2 +0,0 @@
1
- var e=`floatingMenu_E1XCy`,t=`floatingMenu-content_AmxkA`,n=`floatingMenu-container_w7k-Y`,r=`floatingMenu-container-anchored_-8CHY`,i=`floatingMenu-anim-flip_a4-Ri`,a=`floatingMenu-container-align-left_InKnZ`,o=`floatingMenu-container-align-right_a9OoS`,s=`floatingMenu-container-align-center_-8bGT`,c=`floatingMenu-container-flag_VdKHr`,l=`floatingMenu-container-flag-align-right_vxrRN`,u=`floatingMenu-container-flag-align-left_a2Vv-`,d=`floatingMenu-container-flag-align-center_SmaaY`,f=`floatingMenu-anim_5KB-f`,p=`showMenu_AprCh`,m={floatingMenu:e,"floatingMenu-content":`floatingMenu-content_AmxkA`,floatingMenuContent:t,"floatingMenu-container":`floatingMenu-container_w7k-Y`,floatingMenuContainer:n,"floatingMenu-container-anchored":`floatingMenu-container-anchored_-8CHY`,floatingMenuContainerAnchored:r,"floatingMenu-anim-flip":`floatingMenu-anim-flip_a4-Ri`,floatingMenuAnimFlip:i,"floatingMenu-container-align-left":`floatingMenu-container-align-left_InKnZ`,floatingMenuContainerAlignLeft:a,"floatingMenu-container-align-right":`floatingMenu-container-align-right_a9OoS`,floatingMenuContainerAlignRight:o,"floatingMenu-container-align-center":`floatingMenu-container-align-center_-8bGT`,floatingMenuContainerAlignCenter:s,"floatingMenu-container-flag":`floatingMenu-container-flag_VdKHr`,floatingMenuContainerFlag:c,"floatingMenu-container-flag-align-right":`floatingMenu-container-flag-align-right_vxrRN`,floatingMenuContainerFlagAlignRight:l,"floatingMenu-container-flag-align-left":`floatingMenu-container-flag-align-left_a2Vv-`,floatingMenuContainerFlagAlignLeft:u,"floatingMenu-container-flag-align-center":`floatingMenu-container-flag-align-center_SmaaY`,floatingMenuContainerFlagAlignCenter:d,"floatingMenu-anim":`floatingMenu-anim_5KB-f`,floatingMenuAnim:f,showMenu:p};export{m as default,e as floatingMenu,f as floatingMenuAnim,i as floatingMenuAnimFlip,n as floatingMenuContainer,s as floatingMenuContainerAlignCenter,a as floatingMenuContainerAlignLeft,o as floatingMenuContainerAlignRight,r as floatingMenuContainerAnchored,c as floatingMenuContainerFlag,d as floatingMenuContainerFlagAlignCenter,u as floatingMenuContainerFlagAlignLeft,l as floatingMenuContainerFlagAlignRight,t as floatingMenuContent,p as showMenu};
2
- //# sourceMappingURL=floatingMenu.module.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"floatingMenu.module.mjs","names":[],"sources":["../../../../package/common/floatingMenu/floatingMenu.module.pcss"],"sourcesContent":[".floatingMenu {\n position: relative;\n\n &-content {\n display: flex;\n align-items: stretch;\n height: 100%;\n cursor: pointer;\n -webkit-tap-highlight-color: transparent;\n }\n\n &-container {\n color: var(--text-color);\n font-family: var(--default-font);\n font-size: var(--default-font-size);\n box-shadow: var(--card-shadow);\n background: var(--background-modal);\n padding: 8px;\n border-radius: calc(var(--default-border-radius) + 4px);\n\n /* Positioning lives here rather than on `&-container` itself, so that sheet presentation\n can leave it off instead of having to override it. */\n &-anchored {\n position: absolute;\n margin-top: 10px;\n\n .floatingMenu-anim-flip & {\n top: auto;\n bottom: 0;\n margin-top: 0;\n margin-bottom: 10px;\n }\n }\n\n &-align {\n &-left {\n left: 0;\n }\n\n &-right {\n right: 0;\n }\n\n &-center {\n left: 50%;\n transform: translateX(-50%);\n }\n }\n\n &-flag {\n box-shadow: var(--card-shadow);\n background: var(--background-modal);\n height: 10px;\n width: 10px;\n position: absolute;\n margin-top: 5px;\n transform: rotate(45deg);\n\n .floatingMenu-anim-flip & {\n top: auto;\n bottom: 0;\n margin-top: 0;\n margin-bottom: 5px;\n }\n\n &-align-right {\n right: 8px;\n }\n\n &-align-left {\n left: 8px;\n }\n\n &-align-center {\n left: 50%;\n transform: translateX(-50%) rotate(45deg);\n }\n }\n }\n\n &-anim {\n transform: scale(0.7);\n opacity: 0.7;\n animation: showMenu 0.1s forwards;\n position: fixed;\n z-index: 1;\n }\n\n @keyframes showMenu {\n to {\n transform: scale(1);\n opacity: 1;\n }\n }\n}\n"],"mappings":""}
@@ -1,2 +0,0 @@
1
- var e=function(e){return e.Default=`default`,e.Sheet=`sheet`,e.Auto=`auto`,e}({}),t=function(e){return e.Left=`left`,e.Right=`right`,e.Center=`center`,e}({});export{t as Align,e as Presentation};
2
- //# sourceMappingURL=floatingMenu.types.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"floatingMenu.types.mjs","names":[],"sources":["../../../../package/common/floatingMenu/floatingMenu.types.ts"],"sourcesContent":["import type { CSSProperties, ReactNode } from 'react';\nimport type { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types';\n\n/** How a surface is presented on screen. */\nexport enum Presentation {\n /** Wherever the component normally puts it: anchored to its trigger, or centred for a Modal. */\n Default = 'default',\n /** Pinned to the bottom of the screen, full width up to a maximum. */\n Sheet = 'sheet',\n /** A sheet on touch devices with a small screen, anchored everywhere else. */\n Auto = 'auto',\n}\n\nexport enum Align {\n Left = 'left',\n Right = 'right',\n Center = 'center',\n}\n\nexport type FloatingMenuSlots = 'root' | 'trigger' | 'menu' | 'menuContainer' | 'backdrop';\n\nexport interface FloatingMenuProps extends Omit<HtmlProps, 'content'> {\n align?: Align;\n children?: ReactNode;\n content?: ReactNode;\n isOpen?: boolean;\n onOpenChange?: (isOpen: boolean) => void;\n dontCloseOnChildClick?: boolean;\n /** Where the menu opens: anchored to the trigger (`Default`), pinned to the bottom of the\n * screen, or the latter only on a small touch screen. */\n presentation?: Presentation;\n className?: string;\n style?: CSSProperties;\n classNames?: SlotClassNames<FloatingMenuSlots>;\n styles?: SlotStyles<FloatingMenuSlots>;\n}\n"],"mappings":"AAIA,IAAY,EAAL,SAAA,EAAA,OAEL,GAAA,QAAA,UAEA,EAAA,MAAA,QAEA,EAAA,KAAA,QACF,EAAA,CAAA,CAAA,EAEY,EAAL,SAAA,EAAA,OACL,GAAA,KAAA,OACA,EAAA,MAAA,QACA,EAAA,OAAA,UACF,EAAA,CAAA,CAAA"}
@@ -1,2 +0,0 @@
1
- import{isHiddenByAnyAncestor as e}from"../utils/scrollAncestors.mjs";import{getVisualViewportRect as t}from"../utils/visualViewport.mjs";import{useAnchorTracking as n}from"../hooks/useAnchorTracking.mjs";var r=8;function i({isOpen:i,triggerRef:a,anchorRef:o,panelRef:s,flipClassName:c,placement:l=`bottom`}){n({isOpen:i,triggerRef:a,elementRefs:[o],resizeRefs:[o,s],deps:[o,s,c,l],update:(n,i)=>{let a=o.current;if(!a)return;let u=n.getBoundingClientRect(),d=s.current?.offsetHeight??0,f=t(),p=f.top+f.height-u.bottom,m=u.top-f.top,h=l===`top`?m:p,g=h<d&&(l===`top`?p:m)>h,_=l===`top`?!g:g;a.classList.toggle(c,g),a.style.top=`${_?u.top-a.offsetHeight:u.bottom}px`,a.style.left=`${u.left}px`;let v=s.current;if(v){let e=v===a?0:v.offsetLeft,t=u.left+e,n=t+v.offsetWidth-(f.left+f.width-r),i=f.left+r-t;n>0?a.style.left=`${u.left-n}px`:i>0&&(a.style.left=`${u.left+i}px`)}a.style.visibility=e(u,i)?`hidden`:``},teardown:()=>{let e=o.current;e&&(e.style.top=``,e.style.left=``,e.style.visibility=``,e.classList.remove(c))}})}export{i as useFloatingPosition};
2
- //# sourceMappingURL=useFloatingPosition.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useFloatingPosition.mjs","names":[],"sources":["../../../../package/common/floatingMenu/useFloatingPosition.ts"],"sourcesContent":["import { type RefObject } from 'react';\nimport { isHiddenByAnyAncestor } from 'components/common/utils/scrollAncestors';\nimport { getVisualViewportRect } from 'components/common/utils/visualViewport';\nimport { useAnchorTracking } from '../hooks/useAnchorTracking';\n\nexport interface UseFloatingPositionArgs {\n isOpen: boolean;\n /** The element the popup is anchored to. */\n triggerRef: RefObject<HTMLElement | null>;\n /** The `position: fixed` element that gets `top`/`left`/`visibility` written to it directly. */\n anchorRef: RefObject<HTMLElement | null>;\n /** The visible panel whose height decides whether there's room to render on the preferred side. */\n panelRef: RefObject<HTMLElement | null>;\n /** Class toggled on `anchorRef` when flipped to the non-preferred side. */\n flipClassName: string;\n /** Preferred side relative to the trigger (default `'bottom'`) — flips to the other side when there's no room. */\n placement?: 'top' | 'bottom';\n}\n\n/** Minimum gap kept between the panel and the viewport edge when horizontally clamped. */\nconst EDGE_MARGIN = 8;\n\n/**\n * Keeps a portaled, `position: fixed` popup anchored to a trigger element: flips above the\n * trigger when there's no room below, and hides (not closes) the popup when the trigger itself\n * scrolls behind a clipping ancestor — matching Floating UI's autoUpdate + hide middleware.\n * It also shifts the popup horizontally to stay within the viewport: `align`/RTL-style CSS\n * only positions the panel relative to the anchor's own box and has no awareness of where\n * that box actually sits on screen, so a trigger near a screen edge would otherwise let the\n * panel overflow it with no correction.\n *\n * `useAnchorTracking` supplies the lifecycle around this: mount wait, ancestor resolution, and\n * re-running on scroll, viewport resize and panel size changes.\n */\nexport function useFloatingPosition({\n isOpen,\n triggerRef,\n anchorRef,\n panelRef,\n flipClassName,\n placement = 'bottom',\n}: UseFloatingPositionArgs) {\n useAnchorTracking({\n isOpen,\n triggerRef,\n elementRefs: [anchorRef],\n // Both, since they're the same element for a panel-as-anchor consumer (Dropdown) but not for\n // a zero-height wrapper whose content sits inside it (FloatingMenu).\n resizeRefs: [anchorRef, panelRef],\n deps: [anchorRef, panelRef, flipClassName, placement],\n\n update: (trigger, ancestors) => {\n const anchor = anchorRef.current;\n if (!anchor) return;\n\n const rect = trigger.getBoundingClientRect();\n const panelHeight = panelRef.current?.offsetHeight ?? 0;\n // The visible area, not the full layout viewport — shrinks on mobile when a keyboard is\n // open, so flip/clamp react to what's actually on screen instead of the keyboard hiding\n // a panel that \"fit\" against the unshrunk layout viewport.\n const vv = getVisualViewportRect();\n const spaceBelow = vv.top + vv.height - rect.bottom;\n const spaceAbove = rect.top - vv.top;\n const preferredSpace = placement === 'top' ? spaceAbove : spaceBelow;\n const alternateSpace = placement === 'top' ? spaceBelow : spaceAbove;\n const flip = preferredSpace < panelHeight && alternateSpace > preferredSpace;\n const renderAbove = placement === 'top' ? !flip : flip;\n anchor.classList.toggle(flipClassName, flip);\n // Shift up by the anchor's own height when rendering above, so this works whether\n // the anchor is a zero-height decorative wrapper (FloatingMenu, whose real panel\n // hangs off it via absolute-positioned CSS) or the visible panel itself\n // (Dropdown) — for the former the shift is a no-op (height 0).\n anchor.style.top = `${renderAbove ? rect.top - anchor.offsetHeight : rect.bottom}px`;\n anchor.style.left = `${rect.left}px`;\n\n // Horizontal clamp: shift the anchor so the panel stays within the viewport, since\n // `align` CSS only positions it relative to the anchor's own box. Use offsetWidth/\n // offsetLeft (untransformed layout geometry), not getBoundingClientRect — both this\n // anchor and Dropdown's animate in via a CSS `transform: scale(...)`, which\n // getBoundingClientRect reflects but the box-model offsets don't, so measuring via\n // the transformed rect would under- or over-correct while that entrance animation runs.\n const panelForClamp = panelRef.current;\n if (panelForClamp) {\n const relativeLeft = panelForClamp === anchor ? 0 : panelForClamp.offsetLeft;\n const panelLeft = rect.left + relativeLeft;\n const panelRight = panelLeft + panelForClamp.offsetWidth;\n const overflowRight = panelRight - (vv.left + vv.width - EDGE_MARGIN);\n const overflowLeft = vv.left + EDGE_MARGIN - panelLeft;\n if (overflowRight > 0) {\n anchor.style.left = `${rect.left - overflowRight}px`;\n } else if (overflowLeft > 0) {\n anchor.style.left = `${rect.left + overflowLeft}px`;\n }\n }\n\n anchor.style.visibility = isHiddenByAnyAncestor(rect, ancestors) ? 'hidden' : '';\n },\n\n teardown: () => {\n // Positioning is written as inline styles, which outrank any class the popup might switch\n // to while it stays mounted — a popup turning into a bottom sheet (`useSheet`) would keep\n // the coordinates computed for its anchored self. Hand the element back as we found it.\n const anchor = anchorRef.current;\n if (!anchor) return;\n anchor.style.top = '';\n anchor.style.left = '';\n anchor.style.visibility = '';\n anchor.classList.remove(flipClassName);\n },\n });\n}\n"],"mappings":"4MAoBA,IAAM,EAAc,EAcpB,SAAgB,EAAoB,CAClC,SACA,aACA,YACA,WACA,gBACA,YAAY,UACc,CAC1B,EAAkB,CAChB,SACA,aACA,YAAa,CAAC,CAAS,EAGvB,WAAY,CAAC,EAAW,CAAQ,EAChC,KAAM,CAAC,EAAW,EAAU,EAAe,CAAS,EAEpD,QAAS,EAAS,IAAc,CAC9B,IAAM,EAAS,EAAU,QACzB,GAAI,CAAC,EAAQ,OAEb,IAAM,EAAO,EAAQ,sBAAsB,EACrC,EAAc,EAAS,SAAS,cAAgB,EAIhD,EAAK,EAAsB,EAC3B,EAAa,EAAG,IAAM,EAAG,OAAS,EAAK,OACvC,EAAa,EAAK,IAAM,EAAG,IAC3B,EAAiB,IAAc,MAAQ,EAAa,EAEpD,EAAO,EAAiB,IADP,IAAc,MAAQ,EAAa,GACI,EACxD,EAAc,IAAc,MAAQ,CAAC,EAAO,EAClD,EAAO,UAAU,OAAO,EAAe,CAAI,EAK3C,EAAO,MAAM,IAAM,GAAG,EAAc,EAAK,IAAM,EAAO,aAAe,EAAK,OAAO,IACjF,EAAO,MAAM,KAAO,GAAG,EAAK,KAAK,IAQjC,IAAM,EAAgB,EAAS,QAC/B,GAAI,EAAe,CACjB,IAAM,EAAe,IAAkB,EAAS,EAAI,EAAc,WAC5D,EAAY,EAAK,KAAO,EAExB,EADa,EAAY,EAAc,aACT,EAAG,KAAO,EAAG,MAAQ,GACnD,EAAe,EAAG,KAAO,EAAc,EACzC,EAAgB,EAClB,EAAO,MAAM,KAAO,GAAG,EAAK,KAAO,EAAc,IACxC,EAAe,IACxB,EAAO,MAAM,KAAO,GAAG,EAAK,KAAO,EAAa,IAEpD,CAEA,EAAO,MAAM,WAAa,EAAsB,EAAM,CAAS,EAAI,SAAW,EAChF,EAEA,aAAgB,CAId,IAAM,EAAS,EAAU,QACpB,IACL,EAAO,MAAM,IAAM,GACnB,EAAO,MAAM,KAAO,GACpB,EAAO,MAAM,WAAa,GAC1B,EAAO,UAAU,OAAO,CAAa,EACvC,CACF,CAAC,CACH"}
@@ -1,3 +0,0 @@
1
- import { FloatingMenuProps } from './floatingMenu.types';
2
- declare function FloatingMenu(props: FloatingMenuProps): import("react").JSX.Element;
3
- export default FloatingMenu;
@@ -1,32 +0,0 @@
1
- import { CSSProperties, ReactNode } from 'react';
2
- import { SlotClassNames, SlotStyles, HtmlProps } from '../types/slots.types';
3
- /** How a surface is presented on screen. */
4
- export declare enum Presentation {
5
- /** Wherever the component normally puts it: anchored to its trigger, or centred for a Modal. */
6
- Default = "default",
7
- /** Pinned to the bottom of the screen, full width up to a maximum. */
8
- Sheet = "sheet",
9
- /** A sheet on touch devices with a small screen, anchored everywhere else. */
10
- Auto = "auto"
11
- }
12
- export declare enum Align {
13
- Left = "left",
14
- Right = "right",
15
- Center = "center"
16
- }
17
- export type FloatingMenuSlots = 'root' | 'trigger' | 'menu' | 'menuContainer' | 'backdrop';
18
- export interface FloatingMenuProps extends Omit<HtmlProps, 'content'> {
19
- align?: Align;
20
- children?: ReactNode;
21
- content?: ReactNode;
22
- isOpen?: boolean;
23
- onOpenChange?: (isOpen: boolean) => void;
24
- dontCloseOnChildClick?: boolean;
25
- /** Where the menu opens: anchored to the trigger (`Default`), pinned to the bottom of the
26
- * screen, or the latter only on a small touch screen. */
27
- presentation?: Presentation;
28
- className?: string;
29
- style?: CSSProperties;
30
- classNames?: SlotClassNames<FloatingMenuSlots>;
31
- styles?: SlotStyles<FloatingMenuSlots>;
32
- }
@@ -1,2 +0,0 @@
1
- export { default } from './floatingMenu';
2
- export * from './floatingMenu.types';
@@ -1,27 +0,0 @@
1
- import { RefObject } from 'react';
2
- export interface UseFloatingPositionArgs {
3
- isOpen: boolean;
4
- /** The element the popup is anchored to. */
5
- triggerRef: RefObject<HTMLElement | null>;
6
- /** The `position: fixed` element that gets `top`/`left`/`visibility` written to it directly. */
7
- anchorRef: RefObject<HTMLElement | null>;
8
- /** The visible panel whose height decides whether there's room to render on the preferred side. */
9
- panelRef: RefObject<HTMLElement | null>;
10
- /** Class toggled on `anchorRef` when flipped to the non-preferred side. */
11
- flipClassName: string;
12
- /** Preferred side relative to the trigger (default `'bottom'`) — flips to the other side when there's no room. */
13
- placement?: 'top' | 'bottom';
14
- }
15
- /**
16
- * Keeps a portaled, `position: fixed` popup anchored to a trigger element: flips above the
17
- * trigger when there's no room below, and hides (not closes) the popup when the trigger itself
18
- * scrolls behind a clipping ancestor — matching Floating UI's autoUpdate + hide middleware.
19
- * It also shifts the popup horizontally to stay within the viewport: `align`/RTL-style CSS
20
- * only positions the panel relative to the anchor's own box and has no awareness of where
21
- * that box actually sits on screen, so a trigger near a screen edge would otherwise let the
22
- * panel overflow it with no correction.
23
- *
24
- * `useAnchorTracking` supplies the lifecycle around this: mount wait, ancestor resolution, and
25
- * re-running on scroll, viewport resize and panel size changes.
26
- */
27
- export declare function useFloatingPosition({ isOpen, triggerRef, anchorRef, panelRef, flipClassName, placement, }: UseFloatingPositionArgs): void;
@@ -1,90 +0,0 @@
1
- # FloatingMenu
2
-
3
- **When to use:** Contextual popover triggered by any element — action menus, dropdowns with custom content, "more options" menus, date pickers, colour swatches.
4
-
5
- **Keywords:** context menu, dropdown menu, bottom sheet, action sheet, mobile, touch
6
-
7
- **Import:** `import { FloatingMenu } from '@ahrowe/ui'`
8
-
9
- ```tsx
10
- import { FloatingMenu, Align } from '@ahrowe/ui';
11
-
12
- // Basic — children is the trigger, content is the popover body
13
- <FloatingMenu
14
- content={
15
- <ul>
16
- <li onClick={handleEdit}>Edit</li>
17
- <li onClick={handleDelete}>Delete</li>
18
- </ul>
19
- }
20
- >
21
- <button>More ▾</button>
22
- </FloatingMenu>
23
-
24
- // Controlled open state
25
- <FloatingMenu
26
- isOpen={isMenuOpen}
27
- onOpenChange={setIsMenuOpen}
28
- align={Align.Right}
29
- content={<MenuContent />}
30
- >
31
- <ActionIcon icon={faEllipsis} />
32
- </FloatingMenu>
33
-
34
- // Keep open through several interactions with content — a column-visibility toggle where
35
- // checking one box shouldn't close the whole menu — or when re-clicking the trigger itself
36
- // (e.g. DatePicker re-clicking its own input) shouldn't close it either
37
- <FloatingMenu dontCloseOnChildClick content={<Form />}>
38
- <button>Open form</button>
39
- </FloatingMenu>
40
- ```
41
-
42
- ```tsx
43
- import { FloatingMenu, Presentation } from '@ahrowe/ui';
44
-
45
- // On a small touch screen the menu becomes a bottom sheet instead of a popover anchored to
46
- // the trigger; everywhere else it stays anchored.
47
- <FloatingMenu presentation={Presentation.Auto} content={<MenuContent />}>
48
- <button>More ▾</button>
49
- </FloatingMenu>
50
- ```
51
-
52
- **Align enum:** `Align.Left` | `Align.Right` | `Align.Center`
53
-
54
- **Presentation enum:** `Presentation.Default` (anchored to the trigger) | `Presentation.Sheet` | `Presentation.Auto`
55
-
56
- **Key props:**
57
-
58
- | Prop | Type | Description |
59
- |------|------|-------------|
60
- | `content` | `ReactNode` | Popover body |
61
- | `children` | `ReactNode` | Trigger element |
62
- | `align` | `Align` | Popover alignment relative to trigger |
63
- | `isOpen` | `boolean` | Controlled open state |
64
- | `onOpenChange` | `(isOpen: boolean) => void` | Open state change callback |
65
- | `dontCloseOnChildClick` | `boolean` | Keep the menu open when its own content is clicked, and when the trigger itself is re-clicked while already open (default `false`) |
66
- | `presentation` | `Presentation` | Where the menu opens: anchored to the trigger (`Default`), always a bottom sheet, or a sheet only on a small touch screen |
67
-
68
- **Slots:** `root` `trigger` `menu` `menuContainer` `backdrop` (`backdrop` only exists while presenting as a sheet)
69
-
70
- **Bottom sheet:** with `Presentation.Sheet` the menu leaves its trigger entirely: it pins to the bottom of the screen, spans the full width up to 560px, scrolls internally past 70% of the viewport height, and dims the page behind a backdrop. Scrolling on the page behind it is locked while it's open, Escape closes it even when focus never entered it, and it lifts itself above an open on-screen keyboard, shrinking to fit the space that leaves rather than running off the top of the screen. Tapping the backdrop closes the sheet and nothing else: the tap is consumed by the backdrop rather than falling through to whatever sits behind it. `Presentation.Auto` applies that only when the pointer is coarse *and* the screen is under 768px wide: pointer alone would catch touchscreen laptops, width alone would catch a narrow desktop window. Set it once for a whole app via `ConfigProvider`:
71
-
72
- ```tsx
73
- <ConfigProvider defaultProps={{ FloatingMenu: { presentation: Presentation.Auto } }}>
74
- ```
75
-
76
- To set it for every sheet-capable component at once, use `ConfigProvider`'s own `presentation` prop instead of the four component-keyed entries — see [ConfigProvider.md](ConfigProvider.md).
77
-
78
- The default stays `Presentation.Default`, so nothing changes for an existing app until it opts in.
79
-
80
- **What that one setting covers.** Every component whose popup *is* a `FloatingMenu` inherits the default above, with no prop of its own: `SplitButton`'s action menu, `ColorPicker`'s picker, `Breadcrumb`'s collapsed-crumb menu, `VirtualList`'s column-visibility menu, and `DatePicker`/`TimeInput`/`KlipyPicker` when they're not already using their own `isModal`. To make one instance differ, wrap it in a nested `ConfigProvider`, which overrides only the keys it sets.
81
-
82
- `Dropdown`, `Popover` and `Modal` place their surfaces themselves rather than through `FloatingMenu`, so each takes its own `presentation` prop and its own `ConfigProvider` key (`Modal`'s covers `DatePicker`/`TimeInput`/`KlipyPicker` in their `isModal` mode). `InputDropdown` and `Tooltip` also position themselves and deliberately have no sheet mode: a typeahead's list belongs next to the text being typed, and a tooltip is a pointer hint, not a screen-owning panel.
83
-
84
- **Positioning:** the menu is portaled and tracks the trigger across scroll and resize, flipping above it when there's no room below. It re-measures whenever `content` changes size while open, so a menu holding a list that grows or shrinks (filtering, async loading) stays anchored to the trigger and re-evaluates whether it still needs to open upward. It's also shifted horizontally to stay within the viewport — a trigger near the left or right edge of the screen no longer lets the menu overflow off-screen, regardless of `align`.
85
-
86
- **Closing behaviour:** by default, clicking anywhere in `content` closes the menu — including inside a nested overlay that renders through its own portal (e.g. a `Dropdown` or another `FloatingMenu` used inside `content`), even though that overlay's DOM lives outside `content`'s own subtree. Re-clicking the trigger while open is a clean toggle: it closes the menu (unless `dontCloseOnChildClick` is set, in which case it's a no-op — the trigger owns its own open/close entirely, so it never fights with an outside-click check). Set `dontCloseOnChildClick` when `content` needs several interactions before the user is done (a multi-checkbox toggle, a color picker's slider, a calendar) — the consumer is then responsible for closing explicitly, e.g. calling `onOpenChange(false)` from the handler that reacts to a final selection.
87
-
88
- **Keyboard:** the menu is portaled to the end of the DOM, so Tab can't reach it in visual order on its own. Escape closes the menu and, when focus is inside it, returns focus to the trigger — it works wherever focus currently is, including on the trigger itself. When `content` has real focusable elements, Tab past the last focusable element (or Shift+Tab past the first) closes the menu and continues focus as if it sat right after the trigger. This doesn't include auto-focusing the first element on open — content ranges from menus to live controls (e.g. `ColorPicker`'s hue slider), where grabbing focus on open would let a stray arrow-key press change a value the user never touched. A consumer that wants that (like `SplitButton` focusing its first enabled action) implements it itself.
89
-
90
- **Nesting inside a Modal:** an open menu registers itself as the layer above whatever it was opened from, so a menu inside a `Modal` behaves the way it looks: Escape closes the menu and leaves the modal open (a second press closes the modal), and the modal's focus trap leaves focus alone while the menu has it. Both matter because the menu is portaled, so its DOM is a sibling of the modal's panel rather than a descendant, and neither DOM position nor mount order says which one is on top. The same applies to `Dropdown` and `Popover`.