smarthr-ui 99.3.2 → 99.4.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 (475) hide show
  1. package/lib/_virtual/plugin.cjs +1 -1
  2. package/lib/_virtual/plugin.js +1 -1
  3. package/lib/components/AccordionPanel/AccordionPanel.cjs +1 -1
  4. package/lib/components/AccordionPanel/AccordionPanel.js +1 -1
  5. package/lib/components/AccordionPanel/AccordionPanelContent.cjs +1 -1
  6. package/lib/components/AccordionPanel/AccordionPanelContent.js +1 -1
  7. package/lib/components/AccordionPanel/AccordionPanelItem.cjs +1 -1
  8. package/lib/components/AccordionPanel/AccordionPanelItem.js +1 -1
  9. package/lib/components/AccordionPanel/AccordionPanelTrigger.cjs +1 -1
  10. package/lib/components/AccordionPanel/AccordionPanelTrigger.js +1 -1
  11. package/lib/components/AppHeader/components/common/AppLauncherFeatures.cjs +1 -1
  12. package/lib/components/AppHeader/components/common/AppLauncherFeatures.js +1 -1
  13. package/lib/components/AppHeader/components/common/AppLauncherSortDropdown.cjs +1 -1
  14. package/lib/components/AppHeader/components/common/AppLauncherSortDropdown.js +1 -1
  15. package/lib/components/AppHeader/components/common/CommonButton.cjs +1 -1
  16. package/lib/components/AppHeader/components/common/CommonButton.js +1 -1
  17. package/lib/components/AppHeader/components/desktop/AppLauncher.cjs +3 -3
  18. package/lib/components/AppHeader/components/desktop/AppLauncher.cjs.map +1 -1
  19. package/lib/components/AppHeader/components/desktop/AppLauncher.js +3 -3
  20. package/lib/components/AppHeader/components/desktop/AppLauncher.js.map +1 -1
  21. package/lib/components/AppHeader/components/desktop/DesktopHeader.cjs +1 -1
  22. package/lib/components/AppHeader/components/desktop/DesktopHeader.js +1 -1
  23. package/lib/components/AppHeader/components/desktop/Navigation.cjs +1 -1
  24. package/lib/components/AppHeader/components/desktop/Navigation.js +1 -1
  25. package/lib/components/AppHeader/components/desktop/ReleaseNotesDropdown.cjs +1 -1
  26. package/lib/components/AppHeader/components/desktop/ReleaseNotesDropdown.js +1 -1
  27. package/lib/components/AppHeader/components/desktop/UserInfo.cjs +1 -1
  28. package/lib/components/AppHeader/components/desktop/UserInfo.js +1 -1
  29. package/lib/components/AppHeader/components/mobile/AppLauncher.cjs +3 -3
  30. package/lib/components/AppHeader/components/mobile/AppLauncher.cjs.map +1 -1
  31. package/lib/components/AppHeader/components/mobile/AppLauncher.js +3 -3
  32. package/lib/components/AppHeader/components/mobile/AppLauncher.js.map +1 -1
  33. package/lib/components/AppHeader/components/mobile/AppLauncherFilterDropdown.cjs +1 -1
  34. package/lib/components/AppHeader/components/mobile/AppLauncherFilterDropdown.js +1 -1
  35. package/lib/components/AppHeader/components/mobile/LanguageSelector.cjs +1 -1
  36. package/lib/components/AppHeader/components/mobile/LanguageSelector.js +1 -1
  37. package/lib/components/AppHeader/components/mobile/Menu.cjs +1 -1
  38. package/lib/components/AppHeader/components/mobile/Menu.js +1 -1
  39. package/lib/components/AppHeader/components/mobile/MenuDialog.cjs +1 -1
  40. package/lib/components/AppHeader/components/mobile/MenuDialog.js +1 -1
  41. package/lib/components/AppHeader/components/mobile/MobileHeader.cjs +1 -1
  42. package/lib/components/AppHeader/components/mobile/MobileHeader.cjs.map +1 -1
  43. package/lib/components/AppHeader/components/mobile/MobileHeader.js +1 -1
  44. package/lib/components/AppHeader/components/mobile/MobileHeader.js.map +1 -1
  45. package/lib/components/AppHeader/components/mobile/Navigation.cjs +1 -1
  46. package/lib/components/AppHeader/components/mobile/Navigation.js +1 -1
  47. package/lib/components/AppHeader/components/mobile/NavigationItem.cjs +1 -1
  48. package/lib/components/AppHeader/components/mobile/NavigationItem.js +1 -1
  49. package/lib/components/AppHeader/components/mobile/ReleaseNote.cjs +1 -1
  50. package/lib/components/AppHeader/components/mobile/ReleaseNote.js +1 -1
  51. package/lib/components/AppHeader/components/mobile/TenantSelector.cjs +1 -1
  52. package/lib/components/AppHeader/components/mobile/TenantSelector.js +1 -1
  53. package/lib/components/AppHeader/components/mobile/UserInfo.cjs +1 -1
  54. package/lib/components/AppHeader/components/mobile/UserInfo.js +1 -1
  55. package/lib/components/AppHeader/hooks/useAppLauncher.cjs +10 -2
  56. package/lib/components/AppHeader/hooks/useAppLauncher.cjs.map +1 -1
  57. package/lib/components/AppHeader/hooks/useAppLauncher.d.ts +1 -0
  58. package/lib/components/AppHeader/hooks/useAppLauncher.js +10 -2
  59. package/lib/components/AppHeader/hooks/useAppLauncher.js.map +1 -1
  60. package/lib/components/AppNavi/AppNavi.cjs +1 -1
  61. package/lib/components/AppNavi/AppNavi.js +1 -1
  62. package/lib/components/AppNavi/AppNaviAnchor.cjs +1 -1
  63. package/lib/components/AppNavi/AppNaviAnchor.js +1 -1
  64. package/lib/components/AppNavi/AppNaviButton.cjs +1 -1
  65. package/lib/components/AppNavi/AppNaviButton.js +1 -1
  66. package/lib/components/AppNavi/AppNaviCustomTag.cjs +1 -1
  67. package/lib/components/AppNavi/AppNaviCustomTag.js +1 -1
  68. package/lib/components/AppNavi/AppNaviDropdown.cjs +1 -1
  69. package/lib/components/AppNavi/AppNaviDropdown.js +1 -1
  70. package/lib/components/AppNavi/AppNaviDropdownMenuButton.cjs +1 -1
  71. package/lib/components/AppNavi/AppNaviDropdownMenuButton.js +1 -1
  72. package/lib/components/AppNavi/itemClassNameGenerator.cjs +1 -1
  73. package/lib/components/AppNavi/itemClassNameGenerator.js +1 -1
  74. package/lib/components/Badge/Badge.cjs +1 -1
  75. package/lib/components/Badge/Badge.js +1 -1
  76. package/lib/components/BottomFixedArea/BottomFixedArea.cjs +1 -1
  77. package/lib/components/BottomFixedArea/BottomFixedArea.js +1 -1
  78. package/lib/components/Browser/Browser.cjs +1 -1
  79. package/lib/components/Browser/Browser.js +1 -1
  80. package/lib/components/Browser/BrowserColumn.cjs +1 -1
  81. package/lib/components/Browser/BrowserColumn.js +1 -1
  82. package/lib/components/Browser/BrowserItem.cjs +1 -1
  83. package/lib/components/Browser/BrowserItem.js +1 -1
  84. package/lib/components/Button/AnchorButton.cjs +1 -1
  85. package/lib/components/Button/AnchorButton.js +1 -1
  86. package/lib/components/Button/Button.cjs +1 -1
  87. package/lib/components/Button/Button.js +1 -1
  88. package/lib/components/Button/DisabledReason.cjs +1 -1
  89. package/lib/components/Button/DisabledReason.js +1 -1
  90. package/lib/components/Button/UnstyledButton.cjs +1 -1
  91. package/lib/components/Button/UnstyledButton.js +1 -1
  92. package/lib/components/Button/useButtonWrapper.cjs +1 -1
  93. package/lib/components/Button/useButtonWrapper.js +1 -1
  94. package/lib/components/Calendar/Calendar.cjs +1 -1
  95. package/lib/components/Calendar/Calendar.js +1 -1
  96. package/lib/components/Calendar/CalendarTable.cjs +1 -1
  97. package/lib/components/Calendar/CalendarTable.js +1 -1
  98. package/lib/components/Calendar/YearPicker.cjs +1 -1
  99. package/lib/components/Calendar/YearPicker.js +1 -1
  100. package/lib/components/Checkbox/Checkbox.cjs +1 -1
  101. package/lib/components/Checkbox/Checkbox.js +1 -1
  102. package/lib/components/Chip/Chip.cjs +1 -1
  103. package/lib/components/Chip/Chip.js +1 -1
  104. package/lib/components/Combobox/ItemButton.cjs +1 -1
  105. package/lib/components/Combobox/ItemButton.js +1 -1
  106. package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs +15 -5
  107. package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs.map +1 -1
  108. package/lib/components/Combobox/MultiCombobox/MultiCombobox.js +16 -6
  109. package/lib/components/Combobox/MultiCombobox/MultiCombobox.js.map +1 -1
  110. package/lib/components/Combobox/MultiCombobox/MultiSelectedItem.cjs +1 -1
  111. package/lib/components/Combobox/MultiCombobox/MultiSelectedItem.js +1 -1
  112. package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs +7 -3
  113. package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs.map +1 -1
  114. package/lib/components/Combobox/SingleCombobox/SingleCombobox.js +8 -4
  115. package/lib/components/Combobox/SingleCombobox/SingleCombobox.js.map +1 -1
  116. package/lib/components/Combobox/useListbox.cjs +8 -4
  117. package/lib/components/Combobox/useListbox.cjs.map +1 -1
  118. package/lib/components/Combobox/useListbox.js +8 -4
  119. package/lib/components/Combobox/useListbox.js.map +1 -1
  120. package/lib/components/DatePicker/DatePicker.cjs +7 -3
  121. package/lib/components/DatePicker/DatePicker.cjs.map +1 -1
  122. package/lib/components/DatePicker/DatePicker.js +7 -3
  123. package/lib/components/DatePicker/DatePicker.js.map +1 -1
  124. package/lib/components/DefinitionList/DefinitionList.cjs +1 -1
  125. package/lib/components/DefinitionList/DefinitionList.js +1 -1
  126. package/lib/components/DefinitionList/DefinitionListItem.cjs +8 -9
  127. package/lib/components/DefinitionList/DefinitionListItem.cjs.map +1 -1
  128. package/lib/components/DefinitionList/DefinitionListItem.js +8 -9
  129. package/lib/components/DefinitionList/DefinitionListItem.js.map +1 -1
  130. package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.cjs +1 -1
  131. package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.js +1 -1
  132. package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.cjs +32 -4
  133. package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.cjs.map +1 -1
  134. package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.d.ts +1 -1
  135. package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.js +29 -1
  136. package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.js.map +1 -1
  137. package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.cjs.map +1 -1
  138. package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.d.ts +1 -2
  139. package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.js.map +1 -1
  140. package/lib/components/Dialog/ControlledStepFormDialog/type.cjs +3 -0
  141. package/lib/components/Dialog/ControlledStepFormDialog/type.cjs.map +1 -0
  142. package/lib/components/Dialog/ControlledStepFormDialog/type.d.ts +25 -0
  143. package/lib/components/Dialog/ControlledStepFormDialog/type.js +2 -0
  144. package/lib/components/Dialog/ControlledStepFormDialog/type.js.map +1 -0
  145. package/lib/components/Dialog/DialogBody.cjs +1 -1
  146. package/lib/components/Dialog/DialogBody.js +1 -1
  147. package/lib/components/Dialog/DialogContentInner.cjs +1 -1
  148. package/lib/components/Dialog/DialogContentInner.js +1 -1
  149. package/lib/components/Dialog/DialogOverlap.cjs +1 -1
  150. package/lib/components/Dialog/DialogOverlap.js +1 -1
  151. package/lib/components/Dialog/FocusTrap.cjs +61 -44
  152. package/lib/components/Dialog/FocusTrap.cjs.map +1 -1
  153. package/lib/components/Dialog/FocusTrap.js +62 -45
  154. package/lib/components/Dialog/FocusTrap.js.map +1 -1
  155. package/lib/components/Dialog/ModelessDialog/ModelessDialog.cjs +1 -1
  156. package/lib/components/Dialog/ModelessDialog/ModelessDialog.js +1 -1
  157. package/lib/components/Dialog/RemoteDialogTrigger/useRemoteTrigger.cjs +20 -10
  158. package/lib/components/Dialog/RemoteDialogTrigger/useRemoteTrigger.cjs.map +1 -1
  159. package/lib/components/Dialog/RemoteDialogTrigger/useRemoteTrigger.d.ts +1 -1
  160. package/lib/components/Dialog/RemoteDialogTrigger/useRemoteTrigger.js +20 -10
  161. package/lib/components/Dialog/RemoteDialogTrigger/useRemoteTrigger.js.map +1 -1
  162. package/lib/components/Dialog/dialogInnerStyle.cjs +1 -1
  163. package/lib/components/Dialog/dialogInnerStyle.js +1 -1
  164. package/lib/components/Disclosure/useDisclosure.cjs +6 -3
  165. package/lib/components/Disclosure/useDisclosure.cjs.map +1 -1
  166. package/lib/components/Disclosure/useDisclosure.js +6 -3
  167. package/lib/components/Disclosure/useDisclosure.js.map +1 -1
  168. package/lib/components/DropZone/DropZone.cjs +1 -1
  169. package/lib/components/DropZone/DropZone.js +1 -1
  170. package/lib/components/Dropdown/Dropdown.cjs +20 -9
  171. package/lib/components/Dropdown/Dropdown.cjs.map +1 -1
  172. package/lib/components/Dropdown/Dropdown.js +20 -9
  173. package/lib/components/Dropdown/Dropdown.js.map +1 -1
  174. package/lib/components/Dropdown/DropdownCloser.cjs +1 -1
  175. package/lib/components/Dropdown/DropdownCloser.js +1 -1
  176. package/lib/components/Dropdown/DropdownContentInner.cjs +79 -3
  177. package/lib/components/Dropdown/DropdownContentInner.cjs.map +1 -1
  178. package/lib/components/Dropdown/DropdownContentInner.js +81 -5
  179. package/lib/components/Dropdown/DropdownContentInner.js.map +1 -1
  180. package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.cjs +70 -3
  181. package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.cjs.map +1 -1
  182. package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.js +71 -4
  183. package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.js.map +1 -1
  184. package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuGroup.cjs +1 -1
  185. package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuGroup.js +1 -1
  186. package/lib/components/Dropdown/DropdownTrigger.cjs +1 -1
  187. package/lib/components/Dropdown/DropdownTrigger.js +1 -1
  188. package/lib/components/Dropdown/FilterDropdown/FilterDropdown.cjs +1 -1
  189. package/lib/components/Dropdown/FilterDropdown/FilterDropdown.js +1 -1
  190. package/lib/components/Dropdown/SortDropdown/SortDropdown.cjs +68 -14
  191. package/lib/components/Dropdown/SortDropdown/SortDropdown.cjs.map +1 -1
  192. package/lib/components/Dropdown/SortDropdown/SortDropdown.js +69 -15
  193. package/lib/components/Dropdown/SortDropdown/SortDropdown.js.map +1 -1
  194. package/lib/components/ErrorScreen/ErrorScreen.cjs +1 -1
  195. package/lib/components/ErrorScreen/ErrorScreen.js +1 -1
  196. package/lib/components/FileViewer/PDFViewer.cjs +27 -26
  197. package/lib/components/FileViewer/PDFViewer.cjs.map +1 -1
  198. package/lib/components/FileViewer/PDFViewer.js +28 -27
  199. package/lib/components/FileViewer/PDFViewer.js.map +1 -1
  200. package/lib/components/FileViewer/SearchController.cjs +1 -1
  201. package/lib/components/FileViewer/SearchController.js +1 -1
  202. package/lib/components/FloatArea/FloatArea.cjs +26 -85
  203. package/lib/components/FloatArea/FloatArea.cjs.map +1 -1
  204. package/lib/components/FloatArea/FloatArea.js +26 -85
  205. package/lib/components/FloatArea/FloatArea.js.map +1 -1
  206. package/lib/components/FormControl/FormControl.cjs +60 -41
  207. package/lib/components/FormControl/FormControl.cjs.map +1 -1
  208. package/lib/components/FormControl/FormControl.js +60 -41
  209. package/lib/components/FormControl/FormControl.js.map +1 -1
  210. package/lib/components/Header/AppLauncher/AppLauncher.cjs +5 -5
  211. package/lib/components/Header/AppLauncher/AppLauncher.cjs.map +1 -1
  212. package/lib/components/Header/AppLauncher/AppLauncher.js +5 -5
  213. package/lib/components/Header/AppLauncher/AppLauncher.js.map +1 -1
  214. package/lib/components/Header/Header.cjs +1 -1
  215. package/lib/components/Header/Header.js +1 -1
  216. package/lib/components/Header/HeaderDropdownMenuButton.cjs +1 -1
  217. package/lib/components/Header/HeaderDropdownMenuButton.js +1 -1
  218. package/lib/components/Header/HeaderLink.cjs +1 -1
  219. package/lib/components/Header/HeaderLink.js +1 -1
  220. package/lib/components/Header/LanguageSwitcher/LanguageSwitcher.cjs +1 -1
  221. package/lib/components/Header/LanguageSwitcher/LanguageSwitcher.js +1 -1
  222. package/lib/components/Heading/Heading.cjs +1 -1
  223. package/lib/components/Heading/Heading.js +1 -1
  224. package/lib/components/Heading/PageHeading/PageHeading.cjs +43 -27
  225. package/lib/components/Heading/PageHeading/PageHeading.cjs.map +1 -1
  226. package/lib/components/Heading/PageHeading/PageHeading.js +44 -28
  227. package/lib/components/Heading/PageHeading/PageHeading.js.map +1 -1
  228. package/lib/components/Icon/generateIcon.cjs +1 -1
  229. package/lib/components/Icon/generateIcon.js +1 -1
  230. package/lib/components/InformationPanel/InformationPanel.cjs +7 -7
  231. package/lib/components/InformationPanel/InformationPanel.cjs.map +1 -1
  232. package/lib/components/InformationPanel/InformationPanel.js +8 -8
  233. package/lib/components/InformationPanel/InformationPanel.js.map +1 -1
  234. package/lib/components/Input/CurrencyInput/CurrencyInput.cjs +17 -16
  235. package/lib/components/Input/CurrencyInput/CurrencyInput.cjs.map +1 -1
  236. package/lib/components/Input/CurrencyInput/CurrencyInput.js +18 -17
  237. package/lib/components/Input/CurrencyInput/CurrencyInput.js.map +1 -1
  238. package/lib/components/Input/Input.cjs +15 -16
  239. package/lib/components/Input/Input.cjs.map +1 -1
  240. package/lib/components/Input/Input.js +16 -17
  241. package/lib/components/Input/Input.js.map +1 -1
  242. package/lib/components/Input/InputWithTooltip/InputWithTooltip.cjs +3 -3
  243. package/lib/components/Input/InputWithTooltip/InputWithTooltip.cjs.map +1 -1
  244. package/lib/components/Input/InputWithTooltip/InputWithTooltip.js +3 -3
  245. package/lib/components/Input/InputWithTooltip/InputWithTooltip.js.map +1 -1
  246. package/lib/components/Input/SearchInput/SearchInput.cjs +10 -3
  247. package/lib/components/Input/SearchInput/SearchInput.cjs.map +1 -1
  248. package/lib/components/Input/SearchInput/SearchInput.js +10 -3
  249. package/lib/components/Input/SearchInput/SearchInput.js.map +1 -1
  250. package/lib/components/InputFile/style.cjs +1 -1
  251. package/lib/components/InputFile/style.js +1 -1
  252. package/lib/components/Layout/Center/Center.cjs +1 -1
  253. package/lib/components/Layout/Center/Center.js +1 -1
  254. package/lib/components/Layout/Cluster/Cluster.cjs +1 -1
  255. package/lib/components/Layout/Cluster/Cluster.js +1 -1
  256. package/lib/components/Layout/Container/Container.cjs +1 -1
  257. package/lib/components/Layout/Container/Container.js +1 -1
  258. package/lib/components/Layout/Reel/Reel.cjs +1 -1
  259. package/lib/components/Layout/Reel/Reel.js +1 -1
  260. package/lib/components/Layout/Sidebar/Sidebar.cjs +1 -1
  261. package/lib/components/Layout/Sidebar/Sidebar.js +1 -1
  262. package/lib/components/Layout/Stack/Stack.cjs +1 -1
  263. package/lib/components/Layout/Stack/Stack.js +1 -1
  264. package/lib/components/LineClamp/LineClamp.cjs +1 -1
  265. package/lib/components/LineClamp/LineClamp.js +1 -1
  266. package/lib/components/Loader/Loader.cjs +1 -1
  267. package/lib/components/Loader/Loader.js +1 -1
  268. package/lib/components/Loader/LoaderSpinner.cjs +1 -1
  269. package/lib/components/Loader/LoaderSpinner.js +1 -1
  270. package/lib/components/NotificationBar/NotificationBar.cjs +1 -1
  271. package/lib/components/NotificationBar/NotificationBar.js +1 -1
  272. package/lib/components/PageCounter/PageCounter.cjs +1 -1
  273. package/lib/components/PageCounter/PageCounter.js +1 -1
  274. package/lib/components/Pagination/Pagination.cjs +1 -1
  275. package/lib/components/Pagination/Pagination.js +1 -1
  276. package/lib/components/Panel/Groupbox/Groupbox.cjs +1 -1
  277. package/lib/components/Panel/Groupbox/Groupbox.js +1 -1
  278. package/lib/components/Panel/Panel.cjs +1 -1
  279. package/lib/components/Panel/Panel.js +1 -1
  280. package/lib/components/Picker/style.cjs +1 -1
  281. package/lib/components/Picker/style.js +1 -1
  282. package/lib/components/RadioButton/RadioButton.cjs +1 -1
  283. package/lib/components/RadioButton/RadioButton.js +1 -1
  284. package/lib/components/RadioButtonPanel/RadioButtonPanel.cjs +5 -4
  285. package/lib/components/RadioButtonPanel/RadioButtonPanel.cjs.map +1 -1
  286. package/lib/components/RadioButtonPanel/RadioButtonPanel.js +6 -5
  287. package/lib/components/RadioButtonPanel/RadioButtonPanel.js.map +1 -1
  288. package/lib/components/ResponseMessage/ResponseMessage.cjs +1 -1
  289. package/lib/components/ResponseMessage/ResponseMessage.js +1 -1
  290. package/lib/components/Scroller/Scroller.cjs +23 -13
  291. package/lib/components/Scroller/Scroller.cjs.map +1 -1
  292. package/lib/components/Scroller/Scroller.js +24 -14
  293. package/lib/components/Scroller/Scroller.js.map +1 -1
  294. package/lib/components/SegmentedControl/SegmentedControl.cjs +30 -23
  295. package/lib/components/SegmentedControl/SegmentedControl.cjs.map +1 -1
  296. package/lib/components/SegmentedControl/SegmentedControl.js +31 -24
  297. package/lib/components/SegmentedControl/SegmentedControl.js.map +1 -1
  298. package/lib/components/Select/Select.cjs +1 -1
  299. package/lib/components/Select/Select.js +1 -1
  300. package/lib/components/SideMenu/SideMenu.cjs +1 -1
  301. package/lib/components/SideMenu/SideMenu.js +1 -1
  302. package/lib/components/SideMenu/SideMenuGroup.cjs +1 -1
  303. package/lib/components/SideMenu/SideMenuGroup.js +1 -1
  304. package/lib/components/SideMenu/SideMenuItem.cjs +1 -1
  305. package/lib/components/SideMenu/SideMenuItem.js +1 -1
  306. package/lib/components/SideNav/SideNav.cjs +1 -1
  307. package/lib/components/SideNav/SideNav.js +1 -1
  308. package/lib/components/SideNav/SideNavItemButton.cjs +1 -1
  309. package/lib/components/SideNav/SideNavItemButton.js +1 -1
  310. package/lib/components/SmartHRLogo/SmartHRLogo.cjs +1 -1
  311. package/lib/components/SmartHRLogo/SmartHRLogo.js +1 -1
  312. package/lib/components/SpreadsheetTable/SpreadsheetTable.cjs +1 -1
  313. package/lib/components/SpreadsheetTable/SpreadsheetTable.js +1 -1
  314. package/lib/components/StatusLabel/StatusLabel.cjs +1 -1
  315. package/lib/components/StatusLabel/StatusLabel.js +1 -1
  316. package/lib/components/Stepper/HorizontalStepItem.cjs +1 -1
  317. package/lib/components/Stepper/HorizontalStepItem.js +1 -1
  318. package/lib/components/Stepper/StepCounter.cjs +1 -1
  319. package/lib/components/Stepper/StepCounter.js +1 -1
  320. package/lib/components/Stepper/StepStatusIcon.cjs +1 -1
  321. package/lib/components/Stepper/StepStatusIcon.js +1 -1
  322. package/lib/components/Stepper/Stepper.cjs +1 -1
  323. package/lib/components/Stepper/Stepper.js +1 -1
  324. package/lib/components/Stepper/VerticalStepItem.cjs +1 -1
  325. package/lib/components/Stepper/VerticalStepItem.js +1 -1
  326. package/lib/components/Switch/Switch.cjs +1 -1
  327. package/lib/components/Switch/Switch.js +1 -1
  328. package/lib/components/TabBar/TabBar.cjs +1 -1
  329. package/lib/components/TabBar/TabBar.js +1 -1
  330. package/lib/components/TabBar/TabItem.cjs +1 -1
  331. package/lib/components/TabBar/TabItem.js +1 -1
  332. package/lib/components/Table/BulkActionRow.cjs +1 -1
  333. package/lib/components/Table/BulkActionRow.js +1 -1
  334. package/lib/components/Table/EmptyTableBody.cjs +1 -1
  335. package/lib/components/Table/EmptyTableBody.js +1 -1
  336. package/lib/components/Table/Table.cjs +1 -1
  337. package/lib/components/Table/Table.js +1 -1
  338. package/lib/components/Table/TableReel.cjs +1 -1
  339. package/lib/components/Table/TableReel.js +1 -1
  340. package/lib/components/Table/Td.cjs +1 -1
  341. package/lib/components/Table/Td.js +1 -1
  342. package/lib/components/Table/TdCheckbox.cjs +1 -1
  343. package/lib/components/Table/TdCheckbox.js +1 -1
  344. package/lib/components/Table/TdRadioButton.cjs +1 -1
  345. package/lib/components/Table/TdRadioButton.js +1 -1
  346. package/lib/components/Table/Th.cjs +1 -1
  347. package/lib/components/Table/Th.js +1 -1
  348. package/lib/components/Table/ThCheckbox.cjs +1 -1
  349. package/lib/components/Table/ThCheckbox.js +1 -1
  350. package/lib/components/Table/ThSortButton.cjs +1 -1
  351. package/lib/components/Table/ThSortButton.js +1 -1
  352. package/lib/components/Table/reelShadowStyle.cjs +1 -1
  353. package/lib/components/Table/reelShadowStyle.js +1 -1
  354. package/lib/components/Text/Text.cjs +1 -1
  355. package/lib/components/Text/Text.js +1 -1
  356. package/lib/components/TextLink/TextLink.cjs +1 -1
  357. package/lib/components/TextLink/TextLink.js +1 -1
  358. package/lib/components/TextLink/UpwardLink/UpwardLink.cjs +1 -1
  359. package/lib/components/TextLink/UpwardLink/UpwardLink.js +1 -1
  360. package/lib/components/Textarea/Textarea.cjs +1 -1
  361. package/lib/components/Textarea/Textarea.js +1 -1
  362. package/lib/components/Timeline/Timeline.cjs +1 -1
  363. package/lib/components/Timeline/Timeline.js +1 -1
  364. package/lib/components/Timeline/TimelineItem.cjs +1 -1
  365. package/lib/components/Timeline/TimelineItem.js +1 -1
  366. package/lib/components/Tooltip/ControlledTooltip.cjs +1 -1
  367. package/lib/components/Tooltip/ControlledTooltip.js +1 -1
  368. package/lib/components/Tooltip/Tooltip.cjs +1 -1
  369. package/lib/components/Tooltip/Tooltip.js +1 -1
  370. package/lib/components/Tooltip/TooltipPortal.cjs +1 -1
  371. package/lib/components/Tooltip/TooltipPortal.js +1 -1
  372. package/lib/components/VisuallyHiddenText/VisuallyHiddenText.cjs +1 -1
  373. package/lib/components/VisuallyHiddenText/VisuallyHiddenText.js +1 -1
  374. package/lib/configureTwMerge.cjs +1 -1
  375. package/lib/configureTwMerge.js +1 -1
  376. package/lib/hooks/useAnimationFrame.cjs +40 -0
  377. package/lib/hooks/useAnimationFrame.cjs.map +1 -0
  378. package/lib/hooks/useAnimationFrame.d.ts +19 -0
  379. package/lib/hooks/useAnimationFrame.js +38 -0
  380. package/lib/hooks/useAnimationFrame.js.map +1 -0
  381. package/lib/hooks/useLatest.cjs +1 -2
  382. package/lib/hooks/useLatest.cjs.map +1 -1
  383. package/lib/hooks/useLatest.js +1 -2
  384. package/lib/hooks/useLatest.js.map +1 -1
  385. package/lib/hooks/useMediaQueries/useMediaQueries.cjs +41 -29
  386. package/lib/hooks/useMediaQueries/useMediaQueries.cjs.map +1 -1
  387. package/lib/hooks/useMediaQueries/useMediaQueries.js +42 -30
  388. package/lib/hooks/useMediaQueries/useMediaQueries.js.map +1 -1
  389. package/lib/hooks/useMergeRefs.cjs +56 -0
  390. package/lib/hooks/useMergeRefs.cjs.map +1 -0
  391. package/lib/hooks/useMergeRefs.d.ts +18 -0
  392. package/lib/hooks/useMergeRefs.js +54 -0
  393. package/lib/hooks/useMergeRefs.js.map +1 -0
  394. package/lib/hooks/useOnce.cjs +42 -0
  395. package/lib/hooks/useOnce.cjs.map +1 -0
  396. package/lib/hooks/useOnce.d.ts +19 -0
  397. package/lib/hooks/useOnce.js +40 -0
  398. package/lib/hooks/useOnce.js.map +1 -0
  399. package/lib/hooks/useSV/useSV.cjs +1 -1
  400. package/lib/hooks/useSV/useSV.js +1 -1
  401. package/lib/index.cjs +2 -0
  402. package/lib/index.cjs.map +1 -1
  403. package/lib/index.d.ts +1 -0
  404. package/lib/index.js +1 -0
  405. package/lib/index.js.map +1 -1
  406. package/lib/{components/Input/CurrencyInput/currencyInputHelper.js → libs/formatNumericString.cjs} +11 -3
  407. package/lib/libs/formatNumericString.cjs.map +1 -0
  408. package/lib/libs/formatNumericString.d.ts +7 -0
  409. package/lib/{components/Input/CurrencyInput/currencyInputHelper.cjs → libs/formatNumericString.js} +9 -5
  410. package/lib/libs/formatNumericString.js.map +1 -0
  411. package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/chunk-I2QGXAA3.cjs.map +1 -0
  412. package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/chunk-I2QGXAA3.js.map +1 -0
  413. package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.cjs.map +1 -0
  414. package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.js.map +1 -0
  415. package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/public/create-plugin.cjs.map +1 -0
  416. package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/public/create-plugin.js.map +1 -0
  417. package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/util/createPlugin.cjs.map +1 -0
  418. package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/util/createPlugin.js.map +1 -0
  419. package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/plugin.cjs.map +1 -0
  420. package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/plugin.js.map +1 -0
  421. package/metadata.json +1 -1
  422. package/package.json +1 -1
  423. package/lib/components/Dialog/ControlledStepFormDialog/useStepFormDialogButton.cjs +0 -36
  424. package/lib/components/Dialog/ControlledStepFormDialog/useStepFormDialogButton.cjs.map +0 -1
  425. package/lib/components/Dialog/ControlledStepFormDialog/useStepFormDialogButton.d.ts +0 -32
  426. package/lib/components/Dialog/ControlledStepFormDialog/useStepFormDialogButton.js +0 -34
  427. package/lib/components/Dialog/ControlledStepFormDialog/useStepFormDialogButton.js.map +0 -1
  428. package/lib/components/Dropdown/DropdownMenuButton/useKeyboardNavigation.cjs +0 -78
  429. package/lib/components/Dropdown/DropdownMenuButton/useKeyboardNavigation.cjs.map +0 -1
  430. package/lib/components/Dropdown/DropdownMenuButton/useKeyboardNavigation.d.ts +0 -3
  431. package/lib/components/Dropdown/DropdownMenuButton/useKeyboardNavigation.js +0 -76
  432. package/lib/components/Dropdown/DropdownMenuButton/useKeyboardNavigation.js.map +0 -1
  433. package/lib/components/Dropdown/SortDropdown/useSortDropdown.cjs +0 -136
  434. package/lib/components/Dropdown/SortDropdown/useSortDropdown.cjs.map +0 -1
  435. package/lib/components/Dropdown/SortDropdown/useSortDropdown.d.ts +0 -34
  436. package/lib/components/Dropdown/SortDropdown/useSortDropdown.js +0 -134
  437. package/lib/components/Dropdown/SortDropdown/useSortDropdown.js.map +0 -1
  438. package/lib/components/Dropdown/useKeyboardNavigation.cjs +0 -90
  439. package/lib/components/Dropdown/useKeyboardNavigation.cjs.map +0 -1
  440. package/lib/components/Dropdown/useKeyboardNavigation.d.ts +0 -2
  441. package/lib/components/Dropdown/useKeyboardNavigation.js +0 -88
  442. package/lib/components/Dropdown/useKeyboardNavigation.js.map +0 -1
  443. package/lib/components/Input/CurrencyInput/currencyInputHelper.cjs.map +0 -1
  444. package/lib/components/Input/CurrencyInput/currencyInputHelper.d.ts +0 -1
  445. package/lib/components/Input/CurrencyInput/currencyInputHelper.js.map +0 -1
  446. package/lib/components/Input/SearchInput/SearchInputIcon.cjs +0 -18
  447. package/lib/components/Input/SearchInput/SearchInputIcon.cjs.map +0 -1
  448. package/lib/components/Input/SearchInput/SearchInputIcon.d.ts +0 -1
  449. package/lib/components/Input/SearchInput/SearchInputIcon.js +0 -16
  450. package/lib/components/Input/SearchInput/SearchInputIcon.js.map +0 -1
  451. package/lib/libs/object.cjs +0 -8
  452. package/lib/libs/object.cjs.map +0 -1
  453. package/lib/libs/object.d.ts +0 -6
  454. package/lib/libs/object.js +0 -5
  455. package/lib/libs/object.js.map +0 -1
  456. package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/chunk-I2QGXAA3.cjs.map +0 -1
  457. package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/chunk-I2QGXAA3.js.map +0 -1
  458. package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/index.cjs.map +0 -1
  459. package/lib/vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/index.js.map +0 -1
  460. package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/public/create-plugin.cjs.map +0 -1
  461. package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/public/create-plugin.js.map +0 -1
  462. package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/util/createPlugin.cjs.map +0 -1
  463. package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/lib/util/createPlugin.js.map +0 -1
  464. package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/plugin.cjs.map +0 -1
  465. package/lib/vendor/.pnpm/tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_/vendor/tailwindcss/plugin.js.map +0 -1
  466. /package/lib/vendor/.pnpm/{tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__ → tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c}/vendor/tailwind-variants/dist/chunk-I2QGXAA3.cjs +0 -0
  467. /package/lib/vendor/.pnpm/{tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__ → tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c}/vendor/tailwind-variants/dist/chunk-I2QGXAA3.js +0 -0
  468. /package/lib/vendor/.pnpm/{tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__ → tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c}/vendor/tailwind-variants/dist/index.cjs +0 -0
  469. /package/lib/vendor/.pnpm/{tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__ → tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c}/vendor/tailwind-variants/dist/index.js +0 -0
  470. /package/lib/vendor/.pnpm/{tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_ → tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_}/vendor/tailwindcss/lib/public/create-plugin.cjs +0 -0
  471. /package/lib/vendor/.pnpm/{tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_ → tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_}/vendor/tailwindcss/lib/public/create-plugin.js +0 -0
  472. /package/lib/vendor/.pnpm/{tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_ → tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_}/vendor/tailwindcss/lib/util/createPlugin.cjs +0 -0
  473. /package/lib/vendor/.pnpm/{tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_ → tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_}/vendor/tailwindcss/lib/util/createPlugin.js +0 -0
  474. /package/lib/vendor/.pnpm/{tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_ → tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_}/vendor/tailwindcss/plugin.cjs +0 -0
  475. /package/lib/vendor/.pnpm/{tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3_ → tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helpers@0.5.23__@types_node@20.19.43_typescript@5.9.3_}/vendor/tailwindcss/plugin.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.cjs","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["'use client'\n\nimport {\n type FC,\n type MutableRefObject,\n type PropsWithChildren,\n type ReactNode,\n createContext,\n createRef,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { usePortal } from '../../hooks/usePortal'\n\nimport { type Rect, getFirstTabbable, isEventFromChild } from './dropdownHelper'\n\ntype Props = PropsWithChildren<{\n onOpen?: () => void\n onClose?: () => void\n}>\n\ntype DropdownContextType = {\n active: boolean\n triggerRect: Rect\n triggerElementRef: MutableRefObject<HTMLDivElement | null>\n rootTriggerRef: MutableRefObject<HTMLDivElement | null> | null\n handleClickTrigger: (rect: Rect) => void\n handleDelegateClickCloser: () => void\n DropdownContentRoot: FC<{ children: ReactNode }>\n contentId: string\n}\n\nconst initialRect = { top: 0, right: 0, bottom: 0, left: 0 }\n\nexport const DropdownContext = createContext<DropdownContextType>({\n active: false,\n triggerRect: initialRect,\n triggerElementRef: createRef(),\n rootTriggerRef: null,\n handleClickTrigger: () => {\n /* noop */\n },\n handleDelegateClickCloser: () => {\n /* noop */\n },\n DropdownContentRoot: () => null,\n contentId: '',\n})\n\nexport const Dropdown: FC<Props> = ({ onOpen, onClose, children }) => {\n const [active, setActive] = useState(false)\n const [triggerRect, setTriggerRect] = useState<Rect>(initialRect)\n\n const { rootTriggerRef } = useContext(DropdownContext)\n\n const contentId = useId()\n const { createPortal, portalRoot, isChildPortal, PortalParentProvider } = usePortal({\n rootId: contentId,\n })\n\n const triggerElementRef = useRef<HTMLDivElement>(null)\n\n const latest = useLatest({\n active,\n isChildPortal,\n portalRoot,\n onOpen,\n onClose,\n createPortal,\n })\n\n const functions = useMemo(() => {\n // This is the root container of a dropdown content located in outside the DOM tree\n const DropdownContentRoot: FC<{ children: ReactNode }> = (props) =>\n latest.active ? latest.createPortal(props.children) : null\n DropdownContentRoot.displayName = 'DropdownContentRoot'\n\n return {\n DropdownContentRoot,\n handleClickTrigger: (rect: Rect) => {\n if (latest.active) {\n setActive(false)\n if (latest.onClose) requestAnimationFrame(() => latest.onClose?.())\n } else {\n setActive(true)\n setTriggerRect(rect)\n if (latest.onOpen) requestAnimationFrame(() => latest.onOpen?.())\n }\n },\n handleDelegateClickCloser: () => {\n setActive(false)\n if (latest.onClose) requestAnimationFrame(() => latest.onClose?.())\n\n // return focus to the Trigger\n getFirstTabbable(triggerElementRef)?.focus()\n },\n handleClickBody: (e: any) => {\n // ignore events from events within DropdownTrigger and DropdownContent\n if (\n latest.active &&\n !isEventFromChild(e, triggerElementRef.current) &&\n !latest.isChildPortal(e.target)\n ) {\n setActive(false)\n\n if (latest.onClose) {\n requestAnimationFrame(() => latest.onClose?.())\n }\n }\n },\n updateTriggerRect: () => {\n if (triggerElementRef.current) {\n setTriggerRect(triggerElementRef.current.getBoundingClientRect())\n }\n },\n }\n }, [latest])\n\n useEffect(() => {\n if (!active) return\n\n document.body.addEventListener('click', functions.handleClickBody, false)\n window.addEventListener('scroll', functions.updateTriggerRect, { passive: true })\n window.addEventListener('resize', functions.updateTriggerRect, { passive: true })\n\n return () => {\n document.body.removeEventListener('click', functions.handleClickBody, false)\n window.removeEventListener('scroll', functions.updateTriggerRect)\n window.removeEventListener('resize', functions.updateTriggerRect)\n }\n }, [active, functions])\n\n return (\n <PortalParentProvider>\n <DropdownContext.Provider\n value={{\n active,\n triggerRect,\n triggerElementRef,\n rootTriggerRef: rootTriggerRef || triggerElementRef || null,\n handleClickTrigger: functions.handleClickTrigger,\n handleDelegateClickCloser: functions.handleDelegateClickCloser,\n DropdownContentRoot: functions.DropdownContentRoot,\n contentId,\n }}\n >\n {children}\n </DropdownContext.Provider>\n </PortalParentProvider>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;AAsCA;AAEO;AACL;AACA;;AAEA;;;;;;;AAOA;AACA;AACD;AAEM;;;;AAML;;AAEE;AACD;AAED;;;;;;;;AASC;AAED;;;AAIE;;;AAIE;AACE;;;;;;;;;;;;;;;;;AAcA;;AAEF;;;AAII;;;AAKA;;;;;;AAMF;;;;;AAKN;;AAGE;;AAEA;AACA;AACA;AAEA;AACE;;;AAGF;AACF;;;;;AASQ;;;;;AAKD;AAMT;;;"}
1
+ {"version":3,"file":"Dropdown.cjs","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["'use client'\n\nimport {\n type FC,\n type MutableRefObject,\n type PropsWithChildren,\n type ReactNode,\n createContext,\n createRef,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { useAnimationFrame } from '../../hooks/useAnimationFrame'\nimport { useLatest } from '../../hooks/useLatest'\nimport { usePortal } from '../../hooks/usePortal'\n\nimport { type Rect, getFirstTabbable, isEventFromChild } from './dropdownHelper'\n\ntype Props = PropsWithChildren<{\n onOpen?: () => void\n onClose?: () => void\n}>\n\ntype DropdownContextType = {\n active: boolean\n triggerRect: Rect\n triggerElementRef: MutableRefObject<HTMLDivElement | null>\n rootTriggerRef: MutableRefObject<HTMLDivElement | null> | null\n handleClickTrigger: (rect: Rect) => void\n handleDelegateClickCloser: () => void\n DropdownContentRoot: FC<{ children: ReactNode }>\n contentId: string\n}\n\nconst initialRect = { top: 0, right: 0, bottom: 0, left: 0 }\n\nexport const DropdownContext = createContext<DropdownContextType>({\n active: false,\n triggerRect: initialRect,\n triggerElementRef: createRef(),\n rootTriggerRef: null,\n handleClickTrigger: () => {\n /* noop */\n },\n handleDelegateClickCloser: () => {\n /* noop */\n },\n DropdownContentRoot: () => null,\n contentId: '',\n})\n\nexport const Dropdown: FC<Props> = ({ onOpen, onClose, children }) => {\n const [active, setActive] = useState(false)\n const [triggerRect, setTriggerRect] = useState<Rect>(initialRect)\n\n const { rootTriggerRef } = useContext(DropdownContext)\n\n const contentId = useId()\n const { createPortal, portalRoot, isChildPortal, PortalParentProvider } = usePortal({\n rootId: contentId,\n })\n\n const triggerElementRef = useRef<HTMLDivElement>(null)\n const openFrame = useAnimationFrame()\n const closeFrame = useAnimationFrame()\n\n const latest = useLatest({\n active,\n isChildPortal,\n portalRoot,\n onOpen,\n onClose,\n createPortal,\n openFrame,\n closeFrame,\n })\n\n const functions = useMemo(() => {\n // This is the root container of a dropdown content located in outside the DOM tree\n const DropdownContentRoot: FC<{ children: ReactNode }> = (props) =>\n latest.active ? latest.createPortal(props.children) : null\n DropdownContentRoot.displayName = 'DropdownContentRoot'\n const actualClose = () => {\n if (latest.onClose) {\n latest.closeFrame.request(() => latest.onClose?.())\n }\n }\n\n return {\n DropdownContentRoot,\n handleClickTrigger: (rect: Rect) => {\n if (latest.active) {\n setActive(false)\n actualClose()\n } else {\n setActive(true)\n setTriggerRect(rect)\n\n if (latest.onOpen) {\n latest.openFrame.request(() => latest.onOpen?.())\n }\n }\n },\n handleDelegateClickCloser: () => {\n setActive(false)\n actualClose()\n\n // return focus to the Trigger\n getFirstTabbable(triggerElementRef)?.focus()\n },\n handleClickBody: (e: any) => {\n // ignore events from events within DropdownTrigger and DropdownContent\n if (\n latest.active &&\n !isEventFromChild(e, triggerElementRef.current) &&\n !latest.isChildPortal(e.target)\n ) {\n setActive(false)\n actualClose()\n }\n },\n updateTriggerRect: () => {\n if (triggerElementRef.current) {\n setTriggerRect(triggerElementRef.current.getBoundingClientRect())\n }\n },\n }\n }, [latest])\n\n useEffect(\n () => () => {\n latest.openFrame.cancel()\n latest.closeFrame.cancel()\n },\n [latest],\n )\n\n useEffect(() => {\n if (!active) return\n\n document.body.addEventListener('click', functions.handleClickBody, false)\n window.addEventListener('scroll', functions.updateTriggerRect, { passive: true })\n window.addEventListener('resize', functions.updateTriggerRect, { passive: true })\n\n return () => {\n document.body.removeEventListener('click', functions.handleClickBody, false)\n window.removeEventListener('scroll', functions.updateTriggerRect)\n window.removeEventListener('resize', functions.updateTriggerRect)\n }\n }, [active, functions])\n\n return (\n <PortalParentProvider>\n <DropdownContext.Provider\n value={{\n active,\n triggerRect,\n triggerElementRef,\n rootTriggerRef: rootTriggerRef || triggerElementRef || null,\n handleClickTrigger: functions.handleClickTrigger,\n handleDelegateClickCloser: functions.handleDelegateClickCloser,\n DropdownContentRoot: functions.DropdownContentRoot,\n contentId,\n }}\n >\n {children}\n </DropdownContext.Provider>\n </PortalParentProvider>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;;AAuCA;AAEO;AACL;AACA;;AAEA;;;;;;;AAOA;AACA;AACD;AAEM;;;;AAML;;AAEE;AACD;AAED;AACA;AACA;;;;;;;;;;AAWC;AAED;;;AAIE;;AAEE;AACE;;AAEJ;;;AAIE;AACE;;AAEE;;;;;AAKA;AACE;;;;;;AAMJ;;AAGA;;AAEF;;;AAII;;;AAIA;;;;AAIF;;;;;AAKN;AAEA;AAEI;AACA;AACF;;AAKA;;AAEA;AACA;AACA;AAEA;AACE;;;AAGF;AACF;;;;;AASQ;;;;;AAKD;AAMT;;;"}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx } from 'react/jsx-runtime';
3
3
  import { createContext, createRef, useState, useContext, useId, useRef, useMemo, useEffect } from 'react';
4
+ import { useAnimationFrame } from '../../hooks/useAnimationFrame.js';
4
5
  import { useLatest } from '../../hooks/useLatest.js';
5
6
  import { usePortal } from '../../hooks/usePortal.js';
6
7
  import { isEventFromChild, getFirstTabbable } from './dropdownHelper.js';
@@ -29,6 +30,8 @@ const Dropdown = ({ onOpen, onClose, children }) => {
29
30
  rootId: contentId,
30
31
  });
31
32
  const triggerElementRef = useRef(null);
33
+ const openFrame = useAnimationFrame();
34
+ const closeFrame = useAnimationFrame();
32
35
  const latest = useLatest({
33
36
  active,
34
37
  isChildPortal,
@@ -36,30 +39,36 @@ const Dropdown = ({ onOpen, onClose, children }) => {
36
39
  onOpen,
37
40
  onClose,
38
41
  createPortal,
42
+ openFrame,
43
+ closeFrame,
39
44
  });
40
45
  const functions = useMemo(() => {
41
46
  // This is the root container of a dropdown content located in outside the DOM tree
42
47
  const DropdownContentRoot = (props) => latest.active ? latest.createPortal(props.children) : null;
43
48
  DropdownContentRoot.displayName = 'DropdownContentRoot';
49
+ const actualClose = () => {
50
+ if (latest.onClose) {
51
+ latest.closeFrame.request(() => latest.onClose?.());
52
+ }
53
+ };
44
54
  return {
45
55
  DropdownContentRoot,
46
56
  handleClickTrigger: (rect) => {
47
57
  if (latest.active) {
48
58
  setActive(false);
49
- if (latest.onClose)
50
- requestAnimationFrame(() => latest.onClose?.());
59
+ actualClose();
51
60
  }
52
61
  else {
53
62
  setActive(true);
54
63
  setTriggerRect(rect);
55
- if (latest.onOpen)
56
- requestAnimationFrame(() => latest.onOpen?.());
64
+ if (latest.onOpen) {
65
+ latest.openFrame.request(() => latest.onOpen?.());
66
+ }
57
67
  }
58
68
  },
59
69
  handleDelegateClickCloser: () => {
60
70
  setActive(false);
61
- if (latest.onClose)
62
- requestAnimationFrame(() => latest.onClose?.());
71
+ actualClose();
63
72
  // return focus to the Trigger
64
73
  getFirstTabbable(triggerElementRef)?.focus();
65
74
  },
@@ -69,9 +78,7 @@ const Dropdown = ({ onOpen, onClose, children }) => {
69
78
  !isEventFromChild(e, triggerElementRef.current) &&
70
79
  !latest.isChildPortal(e.target)) {
71
80
  setActive(false);
72
- if (latest.onClose) {
73
- requestAnimationFrame(() => latest.onClose?.());
74
- }
81
+ actualClose();
75
82
  }
76
83
  },
77
84
  updateTriggerRect: () => {
@@ -81,6 +88,10 @@ const Dropdown = ({ onOpen, onClose, children }) => {
81
88
  },
82
89
  };
83
90
  }, [latest]);
91
+ useEffect(() => () => {
92
+ latest.openFrame.cancel();
93
+ latest.closeFrame.cancel();
94
+ }, [latest]);
84
95
  useEffect(() => {
85
96
  if (!active)
86
97
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.js","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["'use client'\n\nimport {\n type FC,\n type MutableRefObject,\n type PropsWithChildren,\n type ReactNode,\n createContext,\n createRef,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { usePortal } from '../../hooks/usePortal'\n\nimport { type Rect, getFirstTabbable, isEventFromChild } from './dropdownHelper'\n\ntype Props = PropsWithChildren<{\n onOpen?: () => void\n onClose?: () => void\n}>\n\ntype DropdownContextType = {\n active: boolean\n triggerRect: Rect\n triggerElementRef: MutableRefObject<HTMLDivElement | null>\n rootTriggerRef: MutableRefObject<HTMLDivElement | null> | null\n handleClickTrigger: (rect: Rect) => void\n handleDelegateClickCloser: () => void\n DropdownContentRoot: FC<{ children: ReactNode }>\n contentId: string\n}\n\nconst initialRect = { top: 0, right: 0, bottom: 0, left: 0 }\n\nexport const DropdownContext = createContext<DropdownContextType>({\n active: false,\n triggerRect: initialRect,\n triggerElementRef: createRef(),\n rootTriggerRef: null,\n handleClickTrigger: () => {\n /* noop */\n },\n handleDelegateClickCloser: () => {\n /* noop */\n },\n DropdownContentRoot: () => null,\n contentId: '',\n})\n\nexport const Dropdown: FC<Props> = ({ onOpen, onClose, children }) => {\n const [active, setActive] = useState(false)\n const [triggerRect, setTriggerRect] = useState<Rect>(initialRect)\n\n const { rootTriggerRef } = useContext(DropdownContext)\n\n const contentId = useId()\n const { createPortal, portalRoot, isChildPortal, PortalParentProvider } = usePortal({\n rootId: contentId,\n })\n\n const triggerElementRef = useRef<HTMLDivElement>(null)\n\n const latest = useLatest({\n active,\n isChildPortal,\n portalRoot,\n onOpen,\n onClose,\n createPortal,\n })\n\n const functions = useMemo(() => {\n // This is the root container of a dropdown content located in outside the DOM tree\n const DropdownContentRoot: FC<{ children: ReactNode }> = (props) =>\n latest.active ? latest.createPortal(props.children) : null\n DropdownContentRoot.displayName = 'DropdownContentRoot'\n\n return {\n DropdownContentRoot,\n handleClickTrigger: (rect: Rect) => {\n if (latest.active) {\n setActive(false)\n if (latest.onClose) requestAnimationFrame(() => latest.onClose?.())\n } else {\n setActive(true)\n setTriggerRect(rect)\n if (latest.onOpen) requestAnimationFrame(() => latest.onOpen?.())\n }\n },\n handleDelegateClickCloser: () => {\n setActive(false)\n if (latest.onClose) requestAnimationFrame(() => latest.onClose?.())\n\n // return focus to the Trigger\n getFirstTabbable(triggerElementRef)?.focus()\n },\n handleClickBody: (e: any) => {\n // ignore events from events within DropdownTrigger and DropdownContent\n if (\n latest.active &&\n !isEventFromChild(e, triggerElementRef.current) &&\n !latest.isChildPortal(e.target)\n ) {\n setActive(false)\n\n if (latest.onClose) {\n requestAnimationFrame(() => latest.onClose?.())\n }\n }\n },\n updateTriggerRect: () => {\n if (triggerElementRef.current) {\n setTriggerRect(triggerElementRef.current.getBoundingClientRect())\n }\n },\n }\n }, [latest])\n\n useEffect(() => {\n if (!active) return\n\n document.body.addEventListener('click', functions.handleClickBody, false)\n window.addEventListener('scroll', functions.updateTriggerRect, { passive: true })\n window.addEventListener('resize', functions.updateTriggerRect, { passive: true })\n\n return () => {\n document.body.removeEventListener('click', functions.handleClickBody, false)\n window.removeEventListener('scroll', functions.updateTriggerRect)\n window.removeEventListener('resize', functions.updateTriggerRect)\n }\n }, [active, functions])\n\n return (\n <PortalParentProvider>\n <DropdownContext.Provider\n value={{\n active,\n triggerRect,\n triggerElementRef,\n rootTriggerRef: rootTriggerRef || triggerElementRef || null,\n handleClickTrigger: functions.handleClickTrigger,\n handleDelegateClickCloser: functions.handleDelegateClickCloser,\n DropdownContentRoot: functions.DropdownContentRoot,\n contentId,\n }}\n >\n {children}\n </DropdownContext.Provider>\n </PortalParentProvider>\n )\n}\n"],"names":[],"mappings":";;;;;;;AAsCA;AAEO;AACL;AACA;;AAEA;;;;;;;AAOA;AACA;AACD;AAEM;;;;AAML;;AAEE;AACD;AAED;;;;;;;;AASC;AAED;;;AAIE;;;AAIE;AACE;;;;;;;;;;;;;;;;;AAcA;;AAEF;;;AAII;;;AAKA;;;;;;AAMF;;;;;AAKN;;AAGE;;AAEA;AACA;AACA;AAEA;AACE;;;AAGF;AACF;;;;;AASQ;;;;;AAKD;AAMT;;"}
1
+ {"version":3,"file":"Dropdown.js","sources":["../../../src/components/Dropdown/Dropdown.tsx"],"sourcesContent":["'use client'\n\nimport {\n type FC,\n type MutableRefObject,\n type PropsWithChildren,\n type ReactNode,\n createContext,\n createRef,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\nimport { useAnimationFrame } from '../../hooks/useAnimationFrame'\nimport { useLatest } from '../../hooks/useLatest'\nimport { usePortal } from '../../hooks/usePortal'\n\nimport { type Rect, getFirstTabbable, isEventFromChild } from './dropdownHelper'\n\ntype Props = PropsWithChildren<{\n onOpen?: () => void\n onClose?: () => void\n}>\n\ntype DropdownContextType = {\n active: boolean\n triggerRect: Rect\n triggerElementRef: MutableRefObject<HTMLDivElement | null>\n rootTriggerRef: MutableRefObject<HTMLDivElement | null> | null\n handleClickTrigger: (rect: Rect) => void\n handleDelegateClickCloser: () => void\n DropdownContentRoot: FC<{ children: ReactNode }>\n contentId: string\n}\n\nconst initialRect = { top: 0, right: 0, bottom: 0, left: 0 }\n\nexport const DropdownContext = createContext<DropdownContextType>({\n active: false,\n triggerRect: initialRect,\n triggerElementRef: createRef(),\n rootTriggerRef: null,\n handleClickTrigger: () => {\n /* noop */\n },\n handleDelegateClickCloser: () => {\n /* noop */\n },\n DropdownContentRoot: () => null,\n contentId: '',\n})\n\nexport const Dropdown: FC<Props> = ({ onOpen, onClose, children }) => {\n const [active, setActive] = useState(false)\n const [triggerRect, setTriggerRect] = useState<Rect>(initialRect)\n\n const { rootTriggerRef } = useContext(DropdownContext)\n\n const contentId = useId()\n const { createPortal, portalRoot, isChildPortal, PortalParentProvider } = usePortal({\n rootId: contentId,\n })\n\n const triggerElementRef = useRef<HTMLDivElement>(null)\n const openFrame = useAnimationFrame()\n const closeFrame = useAnimationFrame()\n\n const latest = useLatest({\n active,\n isChildPortal,\n portalRoot,\n onOpen,\n onClose,\n createPortal,\n openFrame,\n closeFrame,\n })\n\n const functions = useMemo(() => {\n // This is the root container of a dropdown content located in outside the DOM tree\n const DropdownContentRoot: FC<{ children: ReactNode }> = (props) =>\n latest.active ? latest.createPortal(props.children) : null\n DropdownContentRoot.displayName = 'DropdownContentRoot'\n const actualClose = () => {\n if (latest.onClose) {\n latest.closeFrame.request(() => latest.onClose?.())\n }\n }\n\n return {\n DropdownContentRoot,\n handleClickTrigger: (rect: Rect) => {\n if (latest.active) {\n setActive(false)\n actualClose()\n } else {\n setActive(true)\n setTriggerRect(rect)\n\n if (latest.onOpen) {\n latest.openFrame.request(() => latest.onOpen?.())\n }\n }\n },\n handleDelegateClickCloser: () => {\n setActive(false)\n actualClose()\n\n // return focus to the Trigger\n getFirstTabbable(triggerElementRef)?.focus()\n },\n handleClickBody: (e: any) => {\n // ignore events from events within DropdownTrigger and DropdownContent\n if (\n latest.active &&\n !isEventFromChild(e, triggerElementRef.current) &&\n !latest.isChildPortal(e.target)\n ) {\n setActive(false)\n actualClose()\n }\n },\n updateTriggerRect: () => {\n if (triggerElementRef.current) {\n setTriggerRect(triggerElementRef.current.getBoundingClientRect())\n }\n },\n }\n }, [latest])\n\n useEffect(\n () => () => {\n latest.openFrame.cancel()\n latest.closeFrame.cancel()\n },\n [latest],\n )\n\n useEffect(() => {\n if (!active) return\n\n document.body.addEventListener('click', functions.handleClickBody, false)\n window.addEventListener('scroll', functions.updateTriggerRect, { passive: true })\n window.addEventListener('resize', functions.updateTriggerRect, { passive: true })\n\n return () => {\n document.body.removeEventListener('click', functions.handleClickBody, false)\n window.removeEventListener('scroll', functions.updateTriggerRect)\n window.removeEventListener('resize', functions.updateTriggerRect)\n }\n }, [active, functions])\n\n return (\n <PortalParentProvider>\n <DropdownContext.Provider\n value={{\n active,\n triggerRect,\n triggerElementRef,\n rootTriggerRef: rootTriggerRef || triggerElementRef || null,\n handleClickTrigger: functions.handleClickTrigger,\n handleDelegateClickCloser: functions.handleDelegateClickCloser,\n DropdownContentRoot: functions.DropdownContentRoot,\n contentId,\n }}\n >\n {children}\n </DropdownContext.Provider>\n </PortalParentProvider>\n )\n}\n"],"names":[],"mappings":";;;;;;;;AAuCA;AAEO;AACL;AACA;;AAEA;;;;;;;AAOA;AACA;AACD;AAEM;;;;AAML;;AAEE;AACD;AAED;AACA;AACA;;;;;;;;;;AAWC;AAED;;;AAIE;;AAEE;AACE;;AAEJ;;;AAIE;AACE;;AAEE;;;;;AAKA;AACE;;;;;;AAMJ;;AAGA;;AAEF;;;AAII;;;AAIA;;;;AAIF;;;;;AAKN;AAEA;AAEI;AACA;AACF;;AAKA;;AAEA;AACA;AACA;AAEA;AACE;;;AAGF;AACF;;;;;AASQ;;;;;AAKD;AAMT;;"}
@@ -3,7 +3,7 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
- var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/index.cjs');
6
+ var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.cjs');
7
7
  var components_Dropdown_DropdownContent = require('./DropdownContent.cjs');
8
8
  var components_Dropdown_DropdownContentInner = require('./DropdownContentInner.cjs');
9
9
 
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { jsx } from 'react/jsx-runtime';
3
3
  import { useContext, useMemo } from 'react';
4
- import { tv as ce } from './../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/index.js';
4
+ import { tv as ce } from './../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.js';
5
5
  import { DropdownContentContext } from './DropdownContent.js';
6
6
  import { DropdownContentInnerContext } from './DropdownContentInner.js';
7
7
 
@@ -3,12 +3,15 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
- var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/index.cjs');
6
+ var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.cjs');
7
+ var hooks_useLatest = require('../../hooks/useLatest.cjs');
7
8
  var hooks_useTheme = require('../../hooks/useTheme.cjs');
9
+ var libs_tabbable = require('../../libs/tabbable.cjs');
10
+ var components_Dropdown_Dropdown = require('./Dropdown.cjs');
8
11
  var components_Dropdown_DropdownCloser = require('./DropdownCloser.cjs');
9
12
  var components_Dropdown_dropdownHelper = require('./dropdownHelper.cjs');
10
- var components_Dropdown_useKeyboardNavigation = require('./useKeyboardNavigation.cjs');
11
13
 
14
+ const KEY_ESCAPE = /^Esc(ape)?$/;
12
15
  const classNameGenerator = index.tv({
13
16
  base: 'smarthr-ui-Dropdown-content shr-absolute shr-z-overlap-base shr-overflow-y-auto shr-break-words shr-rounded-m shr-bg-white shr-shadow-layer-3 forced-colors:shr-outline forced-colors:shr-outline-1',
14
17
  variants: {
@@ -73,7 +76,80 @@ const DropdownContentInner = ({ triggerRect, children, className, controllable,
73
76
  focusTargetRef.current?.focus();
74
77
  }
75
78
  }, [isActive]);
76
- components_Dropdown_useKeyboardNavigation.useKeyboardNavigation(wrapperRef, focusTargetRef);
79
+ const { triggerElementRef, rootTriggerRef, handleDelegateClickCloser } = React.useContext(components_Dropdown_Dropdown.DropdownContext);
80
+ const latest = hooks_useLatest.useLatest({
81
+ triggerElementRef,
82
+ rootTriggerRef,
83
+ handleDelegateClickCloser,
84
+ });
85
+ React.useEffect(() => {
86
+ const handleKeyDown = (e) => {
87
+ if (e.key === 'Tab') {
88
+ if (!wrapperRef.current ||
89
+ !latest.triggerElementRef.current ||
90
+ !latest.rootTriggerRef?.current) {
91
+ return;
92
+ }
93
+ const tabbablesInContent = libs_tabbable.tabbable(wrapperRef.current);
94
+ if (tabbablesInContent.length === 0) {
95
+ return;
96
+ }
97
+ const trigger = libs_tabbable.tabbable(latest.triggerElementRef.current).at(-1);
98
+ const firstTabbable = tabbablesInContent[0];
99
+ if (e.target === trigger) {
100
+ if (e.shiftKey) {
101
+ // move focus previous of the Trigger
102
+ return;
103
+ }
104
+ // focus a first tabbable element in the dropdown content
105
+ e.preventDefault();
106
+ firstTabbable.focus();
107
+ return;
108
+ }
109
+ else if (e.shiftKey) {
110
+ if (e.target === firstTabbable || e.target === focusTargetRef.current) {
111
+ // focus the Trigger
112
+ e.preventDefault();
113
+ trigger.focus();
114
+ latest.handleDelegateClickCloser();
115
+ }
116
+ }
117
+ else if (e.target === tabbablesInContent.at(-1)) {
118
+ // move focus next of the Trigger
119
+ const rootTrigger = libs_tabbable.tabbable(latest.rootTriggerRef.current).at(-1);
120
+ if (rootTrigger) {
121
+ rootTrigger.focus();
122
+ latest.handleDelegateClickCloser();
123
+ }
124
+ }
125
+ }
126
+ else if (KEY_ESCAPE.test(e.key)) {
127
+ if (e.target && e.target === focusTargetRef.current) {
128
+ latest.handleDelegateClickCloser();
129
+ return;
130
+ }
131
+ const trigger = components_Dropdown_dropdownHelper.getFirstTabbable(latest.triggerElementRef);
132
+ if (trigger && e.target === trigger) {
133
+ // close the dropdown when the Trigger is focused and Esc key is pressed
134
+ latest.handleDelegateClickCloser();
135
+ return;
136
+ }
137
+ if (wrapperRef.current) {
138
+ for (const inner of libs_tabbable.tabbable(wrapperRef.current)) {
139
+ if (inner === e.target) {
140
+ // close the dropdown when an element that is included in dropdown content is focused and Esc key is pressed
141
+ latest.handleDelegateClickCloser();
142
+ break;
143
+ }
144
+ }
145
+ }
146
+ }
147
+ };
148
+ window.addEventListener('keydown', handleKeyDown);
149
+ return () => {
150
+ window.removeEventListener('keydown', handleKeyDown);
151
+ };
152
+ }, [latest]);
77
153
  return (jsxRuntime.jsxs("div", { ...rest, ref: wrapperRef, className: actualClassName, style: style, children: [jsxRuntime.jsx("div", { ref: focusTargetRef, tabIndex: -1 }), controllable ? (jsxRuntime.jsx("div", { style: {
78
154
  maxHeight: contentBox.maxHeight || undefined,
79
155
  }, children: children })) : (jsxRuntime.jsx(DropdownContentInnerContext.Provider, { value: { maxHeight: contentBox.maxHeight }, children: jsxRuntime.jsx(components_Dropdown_DropdownCloser.DropdownCloser, { children: children }) }))] }));
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownContentInner.cjs","sources":["../../../src/components/Dropdown/DropdownContentInner.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentProps,\n type FC,\n type PropsWithChildren,\n createContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useTheme } from '../../hooks/useTheme'\n\nimport { DropdownCloser } from './DropdownCloser'\nimport { type ContentBoxStyle, type Rect, getContentBoxStyle } from './dropdownHelper'\nimport { useKeyboardNavigation } from './useKeyboardNavigation'\n\nconst classNameGenerator = tv({\n base: 'smarthr-ui-Dropdown-content shr-absolute shr-z-overlap-base shr-overflow-y-auto shr-break-words shr-rounded-m shr-bg-white shr-shadow-layer-3 forced-colors:shr-outline forced-colors:shr-outline-1',\n variants: {\n isActive: {\n true: 'shr-visible',\n false: 'shr-invisible',\n },\n },\n})\n\ntype BaseProps = PropsWithChildren<{\n triggerRect: Rect\n controllable: boolean\n}>\n\nexport type ElementProps = Omit<ComponentProps<'div'>, keyof BaseProps>\ntype Props = BaseProps & ElementProps\n\ntype DropdownContentInnerContextType = {\n maxHeight: string\n}\n\nexport const DropdownContentInnerContext = createContext<DropdownContentInnerContextType>({\n maxHeight: '',\n})\n\nexport const DropdownContentInner: FC<Props> = ({\n triggerRect,\n children,\n className,\n controllable,\n ...rest\n}) => {\n const theme = useTheme()\n const [isActive, setIsActive] = useState(false)\n const [contentBox, setContentBox] = useState<ContentBoxStyle>({\n top: 'auto',\n maxHeight: '',\n })\n const wrapperRef = useRef<HTMLDivElement>(null)\n const focusTargetRef = useRef<HTMLDivElement>(null)\n\n const actualClassName = useMemo(\n () => classNameGenerator({ isActive, className }),\n [isActive, className],\n )\n\n const style = (() => {\n const defaultMargin = theme.spacingByChar(0.5)\n const leftMargin =\n contentBox.left === undefined ? defaultMargin : `max(${contentBox.left}, 0px)`\n const rightMargin =\n contentBox.right === undefined ? defaultMargin : `max(${contentBox.right}, 0px)`\n const maxWidthStyle = `calc(100% - ${leftMargin} - ${rightMargin})`\n\n return {\n insetBlockStart: contentBox.top,\n insetInlineStart: contentBox.left || undefined,\n insetInlineEnd: contentBox.right || undefined,\n maxWidth: maxWidthStyle,\n }\n })()\n\n useEffect(() => {\n if (wrapperRef.current) {\n setContentBox(\n getContentBoxStyle(\n triggerRect,\n {\n width: wrapperRef.current.offsetWidth,\n height: wrapperRef.current.offsetHeight,\n },\n {\n width: document.body.clientWidth,\n height: innerHeight,\n },\n {\n top: scrollY,\n left: scrollX,\n },\n ),\n )\n setIsActive(true)\n }\n }, [triggerRect])\n\n // setIsActive(true) と同じ useEffect 内で直接 focus() を呼ぶことはできない。\n // このコンポーネントは Dropdown が開かれた時のみマウントされるが、マウント直後は\n // 位置計算が完了していないためコンテンツが誤った位置にちらつくのを防ぐために\n // shr-invisible (visibility: hidden) でレンダリングされる。\n // ちらつき防止には実寸法を保持したまま視覚的に隠せる visibility: hidden が唯一の手段となる。\n // visibility: hidden の要素はフォーカスを受け付けないため、setIsActive(true) の直後に\n // focus() を呼んでも DOM がまだ更新されておらず無効になる。\n //\n // useEffect([isActive]) であれば、isActive=true になった後の render commit 後に\n // 必ず実行されることが保証されるため、この実装が最も信頼性が高い。\n useEffect(() => {\n if (isActive) {\n focusTargetRef.current?.focus()\n }\n }, [isActive])\n\n useKeyboardNavigation(wrapperRef, focusTargetRef)\n\n return (\n <div {...rest} ref={wrapperRef} className={actualClassName} style={style}>\n {/* eslint-disable-next-line smarthr/a11y-scroller-has-tabindex -- dummy element for focus management. */}\n <div ref={focusTargetRef} tabIndex={-1} />\n {controllable ? (\n <div\n style={{\n maxHeight: contentBox.maxHeight || undefined,\n }}\n >\n {children}\n </div>\n ) : (\n <DropdownContentInnerContext.Provider value={{ maxHeight: contentBox.maxHeight }}>\n <DropdownCloser>{children}</DropdownCloser>\n </DropdownContentInnerContext.Provider>\n )}\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAoBA;AACE;AACA;AACE;AACE;AACA;AACD;AACF;AACF;AAcM;AACL;AACD;AAEM;AAOL;;AAEA;AACE;AACA;AACD;AACD;AACA;;AAOA;;AAEE;AAEA;AAEA;;;AAIE;AACA;AACA;;;;AAKF;AACE;AAIM;AACA;;AAGA;AACA;;AAGA;AACA;AACD;;;AAKT;;;;;;;;;;;;;AAcI;;AAEJ;AAEA;AAEA;AAOU;AACD;AAWX;;;"}
1
+ {"version":3,"file":"DropdownContentInner.cjs","sources":["../../../src/components/Dropdown/DropdownContentInner.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentProps,\n type FC,\n type PropsWithChildren,\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { useTheme } from '../../hooks/useTheme'\nimport { tabbable } from '../../libs/tabbable'\n\nimport { DropdownContext } from './Dropdown'\nimport { DropdownCloser } from './DropdownCloser'\nimport {\n type ContentBoxStyle,\n type Rect,\n getContentBoxStyle,\n getFirstTabbable,\n} from './dropdownHelper'\n\nconst KEY_ESCAPE = /^Esc(ape)?$/\n\nconst classNameGenerator = tv({\n base: 'smarthr-ui-Dropdown-content shr-absolute shr-z-overlap-base shr-overflow-y-auto shr-break-words shr-rounded-m shr-bg-white shr-shadow-layer-3 forced-colors:shr-outline forced-colors:shr-outline-1',\n variants: {\n isActive: {\n true: 'shr-visible',\n false: 'shr-invisible',\n },\n },\n})\n\ntype BaseProps = PropsWithChildren<{\n triggerRect: Rect\n controllable: boolean\n}>\n\nexport type ElementProps = Omit<ComponentProps<'div'>, keyof BaseProps>\ntype Props = BaseProps & ElementProps\n\ntype DropdownContentInnerContextType = {\n maxHeight: string\n}\n\nexport const DropdownContentInnerContext = createContext<DropdownContentInnerContextType>({\n maxHeight: '',\n})\n\nexport const DropdownContentInner: FC<Props> = ({\n triggerRect,\n children,\n className,\n controllable,\n ...rest\n}) => {\n const theme = useTheme()\n const [isActive, setIsActive] = useState(false)\n const [contentBox, setContentBox] = useState<ContentBoxStyle>({\n top: 'auto',\n maxHeight: '',\n })\n const wrapperRef = useRef<HTMLDivElement>(null)\n const focusTargetRef = useRef<HTMLDivElement>(null)\n\n const actualClassName = useMemo(\n () => classNameGenerator({ isActive, className }),\n [isActive, className],\n )\n\n const style = (() => {\n const defaultMargin = theme.spacingByChar(0.5)\n const leftMargin =\n contentBox.left === undefined ? defaultMargin : `max(${contentBox.left}, 0px)`\n const rightMargin =\n contentBox.right === undefined ? defaultMargin : `max(${contentBox.right}, 0px)`\n const maxWidthStyle = `calc(100% - ${leftMargin} - ${rightMargin})`\n\n return {\n insetBlockStart: contentBox.top,\n insetInlineStart: contentBox.left || undefined,\n insetInlineEnd: contentBox.right || undefined,\n maxWidth: maxWidthStyle,\n }\n })()\n\n useEffect(() => {\n if (wrapperRef.current) {\n setContentBox(\n getContentBoxStyle(\n triggerRect,\n {\n width: wrapperRef.current.offsetWidth,\n height: wrapperRef.current.offsetHeight,\n },\n {\n width: document.body.clientWidth,\n height: innerHeight,\n },\n {\n top: scrollY,\n left: scrollX,\n },\n ),\n )\n setIsActive(true)\n }\n }, [triggerRect])\n\n // setIsActive(true) と同じ useEffect 内で直接 focus() を呼ぶことはできない。\n // このコンポーネントは Dropdown が開かれた時のみマウントされるが、マウント直後は\n // 位置計算が完了していないためコンテンツが誤った位置にちらつくのを防ぐために\n // shr-invisible (visibility: hidden) でレンダリングされる。\n // ちらつき防止には実寸法を保持したまま視覚的に隠せる visibility: hidden が唯一の手段となる。\n // visibility: hidden の要素はフォーカスを受け付けないため、setIsActive(true) の直後に\n // focus() を呼んでも DOM がまだ更新されておらず無効になる。\n //\n // useEffect([isActive]) であれば、isActive=true になった後の render commit 後に\n // 必ず実行されることが保証されるため、この実装が最も信頼性が高い。\n useEffect(() => {\n if (isActive) {\n focusTargetRef.current?.focus()\n }\n }, [isActive])\n\n const { triggerElementRef, rootTriggerRef, handleDelegateClickCloser } =\n useContext(DropdownContext)\n\n const latest = useLatest({\n triggerElementRef,\n rootTriggerRef,\n handleDelegateClickCloser,\n })\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Tab') {\n if (\n !wrapperRef.current ||\n !latest.triggerElementRef.current ||\n !latest.rootTriggerRef?.current\n ) {\n return\n }\n\n const tabbablesInContent = tabbable(wrapperRef.current)\n\n if (tabbablesInContent.length === 0) {\n return\n }\n\n const trigger = tabbable(latest.triggerElementRef.current).at(-1)\n const firstTabbable = tabbablesInContent[0]\n\n if (e.target === trigger) {\n if (e.shiftKey) {\n // move focus previous of the Trigger\n return\n }\n\n // focus a first tabbable element in the dropdown content\n e.preventDefault()\n firstTabbable.focus()\n\n return\n } else if (e.shiftKey) {\n if (e.target === firstTabbable || e.target === focusTargetRef.current) {\n // focus the Trigger\n e.preventDefault()\n trigger!.focus()\n latest.handleDelegateClickCloser()\n }\n } else if (e.target === tabbablesInContent.at(-1)) {\n // move focus next of the Trigger\n const rootTrigger = tabbable(latest.rootTriggerRef.current).at(-1)\n\n if (rootTrigger) {\n rootTrigger.focus()\n latest.handleDelegateClickCloser()\n }\n }\n } else if (KEY_ESCAPE.test(e.key)) {\n if (e.target && e.target === focusTargetRef.current) {\n latest.handleDelegateClickCloser()\n\n return\n }\n\n const trigger = getFirstTabbable(latest.triggerElementRef)\n\n if (trigger && e.target === trigger) {\n // close the dropdown when the Trigger is focused and Esc key is pressed\n latest.handleDelegateClickCloser()\n\n return\n }\n\n if (wrapperRef.current) {\n for (const inner of tabbable(wrapperRef.current)) {\n if (inner === e.target) {\n // close the dropdown when an element that is included in dropdown content is focused and Esc key is pressed\n latest.handleDelegateClickCloser()\n\n break\n }\n }\n }\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [latest])\n\n return (\n <div {...rest} ref={wrapperRef} className={actualClassName} style={style}>\n {/* eslint-disable-next-line smarthr/a11y-scroller-has-tabindex -- dummy element for focus management. */}\n <div ref={focusTargetRef} tabIndex={-1} />\n {controllable ? (\n <div\n style={{\n maxHeight: contentBox.maxHeight || undefined,\n }}\n >\n {children}\n </div>\n ) : (\n <DropdownContentInnerContext.Provider value={{ maxHeight: contentBox.maxHeight }}>\n <DropdownCloser>{children}</DropdownCloser>\n </DropdownContentInnerContext.Provider>\n )}\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;AA4BA;AAEA;AACE;AACA;AACE;AACE;AACA;AACD;AACF;AACF;AAcM;AACL;AACD;AAEM;AAOL;;AAEA;AACE;AACA;AACD;AACD;AACA;;AAOA;;AAEE;AAEA;AAEA;;;AAIE;AACA;AACA;;;;AAKF;AACE;AAIM;AACA;;AAGA;AACA;;AAGA;AACA;AACD;;;AAKT;;;;;;;;;;;;;AAcI;;AAEJ;AAEA;;;;;AAOC;;AAGC;AACE;;AAGI;AACA;;;;AAOF;;;AAIA;AACA;AAEA;AACE;;;;;;;;;AAUK;AACL;;;;;;;AAMK;;AAEL;;;;;;;;AAQF;;;;;;;;;;AAeA;;AAEI;;;;;;;;AASR;AAEA;AAEA;AACE;AACF;AACF;AAEA;AAOU;AACD;AAWX;;;"}
@@ -1,12 +1,15 @@
1
1
  "use client";
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
- import { createContext, useState, useRef, useMemo, useEffect } from 'react';
4
- import { tv as ce } from './../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/index.js';
3
+ import { createContext, useState, useRef, useMemo, useEffect, useContext } from 'react';
4
+ import { tv as ce } from './../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.js';
5
+ import { useLatest } from '../../hooks/useLatest.js';
5
6
  import { useTheme } from '../../hooks/useTheme.js';
7
+ import { tabbable } from '../../libs/tabbable.js';
8
+ import { DropdownContext } from './Dropdown.js';
6
9
  import { DropdownCloser } from './DropdownCloser.js';
7
- import { getContentBoxStyle } from './dropdownHelper.js';
8
- import { useKeyboardNavigation } from './useKeyboardNavigation.js';
10
+ import { getContentBoxStyle, getFirstTabbable } from './dropdownHelper.js';
9
11
 
12
+ const KEY_ESCAPE = /^Esc(ape)?$/;
10
13
  const classNameGenerator = ce({
11
14
  base: 'smarthr-ui-Dropdown-content shr-absolute shr-z-overlap-base shr-overflow-y-auto shr-break-words shr-rounded-m shr-bg-white shr-shadow-layer-3 forced-colors:shr-outline forced-colors:shr-outline-1',
12
15
  variants: {
@@ -71,7 +74,80 @@ const DropdownContentInner = ({ triggerRect, children, className, controllable,
71
74
  focusTargetRef.current?.focus();
72
75
  }
73
76
  }, [isActive]);
74
- useKeyboardNavigation(wrapperRef, focusTargetRef);
77
+ const { triggerElementRef, rootTriggerRef, handleDelegateClickCloser } = useContext(DropdownContext);
78
+ const latest = useLatest({
79
+ triggerElementRef,
80
+ rootTriggerRef,
81
+ handleDelegateClickCloser,
82
+ });
83
+ useEffect(() => {
84
+ const handleKeyDown = (e) => {
85
+ if (e.key === 'Tab') {
86
+ if (!wrapperRef.current ||
87
+ !latest.triggerElementRef.current ||
88
+ !latest.rootTriggerRef?.current) {
89
+ return;
90
+ }
91
+ const tabbablesInContent = tabbable(wrapperRef.current);
92
+ if (tabbablesInContent.length === 0) {
93
+ return;
94
+ }
95
+ const trigger = tabbable(latest.triggerElementRef.current).at(-1);
96
+ const firstTabbable = tabbablesInContent[0];
97
+ if (e.target === trigger) {
98
+ if (e.shiftKey) {
99
+ // move focus previous of the Trigger
100
+ return;
101
+ }
102
+ // focus a first tabbable element in the dropdown content
103
+ e.preventDefault();
104
+ firstTabbable.focus();
105
+ return;
106
+ }
107
+ else if (e.shiftKey) {
108
+ if (e.target === firstTabbable || e.target === focusTargetRef.current) {
109
+ // focus the Trigger
110
+ e.preventDefault();
111
+ trigger.focus();
112
+ latest.handleDelegateClickCloser();
113
+ }
114
+ }
115
+ else if (e.target === tabbablesInContent.at(-1)) {
116
+ // move focus next of the Trigger
117
+ const rootTrigger = tabbable(latest.rootTriggerRef.current).at(-1);
118
+ if (rootTrigger) {
119
+ rootTrigger.focus();
120
+ latest.handleDelegateClickCloser();
121
+ }
122
+ }
123
+ }
124
+ else if (KEY_ESCAPE.test(e.key)) {
125
+ if (e.target && e.target === focusTargetRef.current) {
126
+ latest.handleDelegateClickCloser();
127
+ return;
128
+ }
129
+ const trigger = getFirstTabbable(latest.triggerElementRef);
130
+ if (trigger && e.target === trigger) {
131
+ // close the dropdown when the Trigger is focused and Esc key is pressed
132
+ latest.handleDelegateClickCloser();
133
+ return;
134
+ }
135
+ if (wrapperRef.current) {
136
+ for (const inner of tabbable(wrapperRef.current)) {
137
+ if (inner === e.target) {
138
+ // close the dropdown when an element that is included in dropdown content is focused and Esc key is pressed
139
+ latest.handleDelegateClickCloser();
140
+ break;
141
+ }
142
+ }
143
+ }
144
+ }
145
+ };
146
+ window.addEventListener('keydown', handleKeyDown);
147
+ return () => {
148
+ window.removeEventListener('keydown', handleKeyDown);
149
+ };
150
+ }, [latest]);
75
151
  return (jsxs("div", { ...rest, ref: wrapperRef, className: actualClassName, style: style, children: [jsx("div", { ref: focusTargetRef, tabIndex: -1 }), controllable ? (jsx("div", { style: {
76
152
  maxHeight: contentBox.maxHeight || undefined,
77
153
  }, children: children })) : (jsx(DropdownContentInnerContext.Provider, { value: { maxHeight: contentBox.maxHeight }, children: jsx(DropdownCloser, { children: children }) }))] }));
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownContentInner.js","sources":["../../../src/components/Dropdown/DropdownContentInner.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentProps,\n type FC,\n type PropsWithChildren,\n createContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useTheme } from '../../hooks/useTheme'\n\nimport { DropdownCloser } from './DropdownCloser'\nimport { type ContentBoxStyle, type Rect, getContentBoxStyle } from './dropdownHelper'\nimport { useKeyboardNavigation } from './useKeyboardNavigation'\n\nconst classNameGenerator = tv({\n base: 'smarthr-ui-Dropdown-content shr-absolute shr-z-overlap-base shr-overflow-y-auto shr-break-words shr-rounded-m shr-bg-white shr-shadow-layer-3 forced-colors:shr-outline forced-colors:shr-outline-1',\n variants: {\n isActive: {\n true: 'shr-visible',\n false: 'shr-invisible',\n },\n },\n})\n\ntype BaseProps = PropsWithChildren<{\n triggerRect: Rect\n controllable: boolean\n}>\n\nexport type ElementProps = Omit<ComponentProps<'div'>, keyof BaseProps>\ntype Props = BaseProps & ElementProps\n\ntype DropdownContentInnerContextType = {\n maxHeight: string\n}\n\nexport const DropdownContentInnerContext = createContext<DropdownContentInnerContextType>({\n maxHeight: '',\n})\n\nexport const DropdownContentInner: FC<Props> = ({\n triggerRect,\n children,\n className,\n controllable,\n ...rest\n}) => {\n const theme = useTheme()\n const [isActive, setIsActive] = useState(false)\n const [contentBox, setContentBox] = useState<ContentBoxStyle>({\n top: 'auto',\n maxHeight: '',\n })\n const wrapperRef = useRef<HTMLDivElement>(null)\n const focusTargetRef = useRef<HTMLDivElement>(null)\n\n const actualClassName = useMemo(\n () => classNameGenerator({ isActive, className }),\n [isActive, className],\n )\n\n const style = (() => {\n const defaultMargin = theme.spacingByChar(0.5)\n const leftMargin =\n contentBox.left === undefined ? defaultMargin : `max(${contentBox.left}, 0px)`\n const rightMargin =\n contentBox.right === undefined ? defaultMargin : `max(${contentBox.right}, 0px)`\n const maxWidthStyle = `calc(100% - ${leftMargin} - ${rightMargin})`\n\n return {\n insetBlockStart: contentBox.top,\n insetInlineStart: contentBox.left || undefined,\n insetInlineEnd: contentBox.right || undefined,\n maxWidth: maxWidthStyle,\n }\n })()\n\n useEffect(() => {\n if (wrapperRef.current) {\n setContentBox(\n getContentBoxStyle(\n triggerRect,\n {\n width: wrapperRef.current.offsetWidth,\n height: wrapperRef.current.offsetHeight,\n },\n {\n width: document.body.clientWidth,\n height: innerHeight,\n },\n {\n top: scrollY,\n left: scrollX,\n },\n ),\n )\n setIsActive(true)\n }\n }, [triggerRect])\n\n // setIsActive(true) と同じ useEffect 内で直接 focus() を呼ぶことはできない。\n // このコンポーネントは Dropdown が開かれた時のみマウントされるが、マウント直後は\n // 位置計算が完了していないためコンテンツが誤った位置にちらつくのを防ぐために\n // shr-invisible (visibility: hidden) でレンダリングされる。\n // ちらつき防止には実寸法を保持したまま視覚的に隠せる visibility: hidden が唯一の手段となる。\n // visibility: hidden の要素はフォーカスを受け付けないため、setIsActive(true) の直後に\n // focus() を呼んでも DOM がまだ更新されておらず無効になる。\n //\n // useEffect([isActive]) であれば、isActive=true になった後の render commit 後に\n // 必ず実行されることが保証されるため、この実装が最も信頼性が高い。\n useEffect(() => {\n if (isActive) {\n focusTargetRef.current?.focus()\n }\n }, [isActive])\n\n useKeyboardNavigation(wrapperRef, focusTargetRef)\n\n return (\n <div {...rest} ref={wrapperRef} className={actualClassName} style={style}>\n {/* eslint-disable-next-line smarthr/a11y-scroller-has-tabindex -- dummy element for focus management. */}\n <div ref={focusTargetRef} tabIndex={-1} />\n {controllable ? (\n <div\n style={{\n maxHeight: contentBox.maxHeight || undefined,\n }}\n >\n {children}\n </div>\n ) : (\n <DropdownContentInnerContext.Provider value={{ maxHeight: contentBox.maxHeight }}>\n <DropdownCloser>{children}</DropdownCloser>\n </DropdownContentInnerContext.Provider>\n )}\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;AAoBA;AACE;AACA;AACE;AACE;AACA;AACD;AACF;AACF;AAcM;AACL;AACD;AAEM;AAOL;;AAEA;AACE;AACA;AACD;AACD;AACA;;AAOA;;AAEE;AAEA;AAEA;;;AAIE;AACA;AACA;;;;AAKF;AACE;AAIM;AACA;;AAGA;AACA;;AAGA;AACA;AACD;;;AAKT;;;;;;;;;;;;;AAcI;;AAEJ;AAEA;AAEA;AAOU;AACD;AAWX;;"}
1
+ {"version":3,"file":"DropdownContentInner.js","sources":["../../../src/components/Dropdown/DropdownContentInner.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentProps,\n type FC,\n type PropsWithChildren,\n createContext,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useLatest } from '../../hooks/useLatest'\nimport { useTheme } from '../../hooks/useTheme'\nimport { tabbable } from '../../libs/tabbable'\n\nimport { DropdownContext } from './Dropdown'\nimport { DropdownCloser } from './DropdownCloser'\nimport {\n type ContentBoxStyle,\n type Rect,\n getContentBoxStyle,\n getFirstTabbable,\n} from './dropdownHelper'\n\nconst KEY_ESCAPE = /^Esc(ape)?$/\n\nconst classNameGenerator = tv({\n base: 'smarthr-ui-Dropdown-content shr-absolute shr-z-overlap-base shr-overflow-y-auto shr-break-words shr-rounded-m shr-bg-white shr-shadow-layer-3 forced-colors:shr-outline forced-colors:shr-outline-1',\n variants: {\n isActive: {\n true: 'shr-visible',\n false: 'shr-invisible',\n },\n },\n})\n\ntype BaseProps = PropsWithChildren<{\n triggerRect: Rect\n controllable: boolean\n}>\n\nexport type ElementProps = Omit<ComponentProps<'div'>, keyof BaseProps>\ntype Props = BaseProps & ElementProps\n\ntype DropdownContentInnerContextType = {\n maxHeight: string\n}\n\nexport const DropdownContentInnerContext = createContext<DropdownContentInnerContextType>({\n maxHeight: '',\n})\n\nexport const DropdownContentInner: FC<Props> = ({\n triggerRect,\n children,\n className,\n controllable,\n ...rest\n}) => {\n const theme = useTheme()\n const [isActive, setIsActive] = useState(false)\n const [contentBox, setContentBox] = useState<ContentBoxStyle>({\n top: 'auto',\n maxHeight: '',\n })\n const wrapperRef = useRef<HTMLDivElement>(null)\n const focusTargetRef = useRef<HTMLDivElement>(null)\n\n const actualClassName = useMemo(\n () => classNameGenerator({ isActive, className }),\n [isActive, className],\n )\n\n const style = (() => {\n const defaultMargin = theme.spacingByChar(0.5)\n const leftMargin =\n contentBox.left === undefined ? defaultMargin : `max(${contentBox.left}, 0px)`\n const rightMargin =\n contentBox.right === undefined ? defaultMargin : `max(${contentBox.right}, 0px)`\n const maxWidthStyle = `calc(100% - ${leftMargin} - ${rightMargin})`\n\n return {\n insetBlockStart: contentBox.top,\n insetInlineStart: contentBox.left || undefined,\n insetInlineEnd: contentBox.right || undefined,\n maxWidth: maxWidthStyle,\n }\n })()\n\n useEffect(() => {\n if (wrapperRef.current) {\n setContentBox(\n getContentBoxStyle(\n triggerRect,\n {\n width: wrapperRef.current.offsetWidth,\n height: wrapperRef.current.offsetHeight,\n },\n {\n width: document.body.clientWidth,\n height: innerHeight,\n },\n {\n top: scrollY,\n left: scrollX,\n },\n ),\n )\n setIsActive(true)\n }\n }, [triggerRect])\n\n // setIsActive(true) と同じ useEffect 内で直接 focus() を呼ぶことはできない。\n // このコンポーネントは Dropdown が開かれた時のみマウントされるが、マウント直後は\n // 位置計算が完了していないためコンテンツが誤った位置にちらつくのを防ぐために\n // shr-invisible (visibility: hidden) でレンダリングされる。\n // ちらつき防止には実寸法を保持したまま視覚的に隠せる visibility: hidden が唯一の手段となる。\n // visibility: hidden の要素はフォーカスを受け付けないため、setIsActive(true) の直後に\n // focus() を呼んでも DOM がまだ更新されておらず無効になる。\n //\n // useEffect([isActive]) であれば、isActive=true になった後の render commit 後に\n // 必ず実行されることが保証されるため、この実装が最も信頼性が高い。\n useEffect(() => {\n if (isActive) {\n focusTargetRef.current?.focus()\n }\n }, [isActive])\n\n const { triggerElementRef, rootTriggerRef, handleDelegateClickCloser } =\n useContext(DropdownContext)\n\n const latest = useLatest({\n triggerElementRef,\n rootTriggerRef,\n handleDelegateClickCloser,\n })\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key === 'Tab') {\n if (\n !wrapperRef.current ||\n !latest.triggerElementRef.current ||\n !latest.rootTriggerRef?.current\n ) {\n return\n }\n\n const tabbablesInContent = tabbable(wrapperRef.current)\n\n if (tabbablesInContent.length === 0) {\n return\n }\n\n const trigger = tabbable(latest.triggerElementRef.current).at(-1)\n const firstTabbable = tabbablesInContent[0]\n\n if (e.target === trigger) {\n if (e.shiftKey) {\n // move focus previous of the Trigger\n return\n }\n\n // focus a first tabbable element in the dropdown content\n e.preventDefault()\n firstTabbable.focus()\n\n return\n } else if (e.shiftKey) {\n if (e.target === firstTabbable || e.target === focusTargetRef.current) {\n // focus the Trigger\n e.preventDefault()\n trigger!.focus()\n latest.handleDelegateClickCloser()\n }\n } else if (e.target === tabbablesInContent.at(-1)) {\n // move focus next of the Trigger\n const rootTrigger = tabbable(latest.rootTriggerRef.current).at(-1)\n\n if (rootTrigger) {\n rootTrigger.focus()\n latest.handleDelegateClickCloser()\n }\n }\n } else if (KEY_ESCAPE.test(e.key)) {\n if (e.target && e.target === focusTargetRef.current) {\n latest.handleDelegateClickCloser()\n\n return\n }\n\n const trigger = getFirstTabbable(latest.triggerElementRef)\n\n if (trigger && e.target === trigger) {\n // close the dropdown when the Trigger is focused and Esc key is pressed\n latest.handleDelegateClickCloser()\n\n return\n }\n\n if (wrapperRef.current) {\n for (const inner of tabbable(wrapperRef.current)) {\n if (inner === e.target) {\n // close the dropdown when an element that is included in dropdown content is focused and Esc key is pressed\n latest.handleDelegateClickCloser()\n\n break\n }\n }\n }\n }\n }\n\n window.addEventListener('keydown', handleKeyDown)\n\n return () => {\n window.removeEventListener('keydown', handleKeyDown)\n }\n }, [latest])\n\n return (\n <div {...rest} ref={wrapperRef} className={actualClassName} style={style}>\n {/* eslint-disable-next-line smarthr/a11y-scroller-has-tabindex -- dummy element for focus management. */}\n <div ref={focusTargetRef} tabIndex={-1} />\n {controllable ? (\n <div\n style={{\n maxHeight: contentBox.maxHeight || undefined,\n }}\n >\n {children}\n </div>\n ) : (\n <DropdownContentInnerContext.Provider value={{ maxHeight: contentBox.maxHeight }}>\n <DropdownCloser>{children}</DropdownCloser>\n </DropdownContentInnerContext.Provider>\n )}\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;;;AA4BA;AAEA;AACE;AACA;AACE;AACE;AACA;AACD;AACF;AACF;AAcM;AACL;AACD;AAEM;AAOL;;AAEA;AACE;AACA;AACD;AACD;AACA;;AAOA;;AAEE;AAEA;AAEA;;;AAIE;AACA;AACA;;;;AAKF;AACE;AAIM;AACA;;AAGA;AACA;;AAGA;AACA;AACD;;;AAKT;;;;;;;;;;;;;AAcI;;AAEJ;AAEA;;;;;AAOC;;AAGC;AACE;;AAGI;AACA;;;;AAOF;;;AAIA;AACA;AAEA;AACE;;;;;;;;;AAUK;AACL;;;;;;;AAMK;;AAEL;;;;;;;;AAQF;;;;;;;;;;AAeA;;AAEI;;;;;;;;AASR;AAEA;AAEA;AACE;AACF;AACF;AAEA;AAOU;AACD;AAWX;;"}
@@ -3,7 +3,7 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
- var index = require('./../../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@types_node@20.19.43_typescript@5.9.3__/vendor/tailwind-variants/dist/index.cjs');
6
+ var index = require('./../../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.46_@swc_helper_93b9c5ee15e3d3d2221e194197be3b5c/vendor/tailwind-variants/dist/index.cjs');
7
7
  var hooks_useObjectAttributes = require('../../../hooks/useObjectAttributes.cjs');
8
8
  require('../../../intl/IntlProvider.cjs');
9
9
  require('react-intl');
@@ -21,8 +21,48 @@ var components_Dropdown_DropdownCloser = require('../DropdownCloser.cjs');
21
21
  var components_Dropdown_DropdownContent = require('../DropdownContent.cjs');
22
22
  var components_Dropdown_DropdownTrigger = require('../DropdownTrigger.cjs');
23
23
  var components_Dropdown_DropdownMenuButton_DropdownMenuGroup = require('./DropdownMenuGroup.cjs');
24
- var components_Dropdown_DropdownMenuButton_useKeyboardNavigation = require('./useKeyboardNavigation.cjs');
25
24
 
25
+ const TABBABLE_SELECTOR = 'li button,li a,li [tabindex]:not([tabindex="-1"])';
26
+ const DISABLED_SELECTOR = ':disabled,[aria-disabled="true"]';
27
+ const isElementEnabled = (element) => !element.matches(DISABLED_SELECTOR) && !element.querySelector(DISABLED_SELECTOR);
28
+ const KEY_UP_REGEX = /^(Arrow)?(Up|Left)$/;
29
+ const KEY_DOWN_REGEX = /^(Arrow)?(Down|Right)$/;
30
+ const moveFocus = (element, direction) => {
31
+ let hoveredItem = null;
32
+ const tabbableItems = [];
33
+ let focusedIndex = -1;
34
+ const pushTabbaleItem = (item) => {
35
+ tabbableItems.push(item);
36
+ if (document.activeElement === item) {
37
+ focusedIndex = tabbableItems.length - 1;
38
+ }
39
+ };
40
+ element.querySelectorAll(TABBABLE_SELECTOR).forEach((item) => {
41
+ if (hoveredItem === null && item.matches(':hover')) {
42
+ hoveredItem = item;
43
+ }
44
+ if (isElementEnabled(item)) {
45
+ pushTabbaleItem(item);
46
+ }
47
+ });
48
+ let nextIndex = 0;
49
+ if (focusedIndex > -1) {
50
+ // フォーカスされているアイテムが存在する場合
51
+ nextIndex = (focusedIndex + direction + tabbableItems.length) % tabbableItems.length;
52
+ }
53
+ else if (hoveredItem) {
54
+ // ホバー状態のアイテムが存在する場合
55
+ nextIndex =
56
+ (tabbableItems.indexOf(hoveredItem) + direction + tabbableItems.length) % tabbableItems.length;
57
+ }
58
+ else if (direction === -1) {
59
+ nextIndex = tabbableItems.length - 1;
60
+ }
61
+ const nextItem = tabbableItems[nextIndex];
62
+ if (nextItem instanceof HTMLElement) {
63
+ nextItem.focus();
64
+ }
65
+ };
26
66
  const triggerObjectConverter = (trigger) => ({
27
67
  children: trigger,
28
68
  });
@@ -51,12 +91,39 @@ const { triggerWrapper, triggerButton, actionList, actionListItemButton } = clas
51
91
  const DropdownMenuButton = ({ trigger, children, onOpen, onClose, className, ...rest }) => {
52
92
  const { children: triggerChildren, size: triggerSize, onlyIcon: onlyIconTrigger, } = hooks_useObjectAttributes.useObjectAttributes(trigger, triggerObjectConverter);
53
93
  const containerRef = React.useRef(null);
54
- components_Dropdown_DropdownMenuButton_useKeyboardNavigation(containerRef);
55
94
  const classNames = React.useMemo(() => ({
56
95
  triggerWrapper: triggerWrapper({ className }),
57
96
  triggerButton: triggerButton(),
58
97
  actionList: actionList(),
59
98
  }), [className]);
99
+ React.useEffect(() => {
100
+ const handleKeyDown = (e) => {
101
+ if (!containerRef.current || !document.activeElement) {
102
+ return;
103
+ }
104
+ let direction = 0;
105
+ // HINT: tabとarrow keyで挙動を揃えるため、tabもhandling対象にする
106
+ if (e.key === 'Tab') {
107
+ // HINT: tbのデフォルトの挙動の場合のみ、preventDefaultが必要
108
+ e.preventDefault();
109
+ direction = e.shiftKey ? -1 : 1;
110
+ }
111
+ else if (KEY_UP_REGEX.test(e.key)) {
112
+ direction = -1;
113
+ }
114
+ else if (KEY_DOWN_REGEX.test(e.key)) {
115
+ direction = 1;
116
+ }
117
+ if (direction !== 0) {
118
+ moveFocus(containerRef.current, direction);
119
+ }
120
+ };
121
+ const eventKey = 'keydown';
122
+ document.addEventListener(eventKey, handleKeyDown);
123
+ return () => {
124
+ document.removeEventListener(eventKey, handleKeyDown);
125
+ };
126
+ }, []);
60
127
  return (jsxRuntime.jsxs(components_Dropdown_Dropdown.Dropdown, { onOpen: onOpen, onClose: onClose, children: [jsxRuntime.jsx(MemoizedTriggerButton, { ...rest, onlyIconTrigger: onlyIconTrigger, triggerSize: triggerSize, classNames: classNames, children: triggerChildren }), jsxRuntime.jsx(components_Dropdown_DropdownContent.DropdownContent, { controllable: true, children: jsxRuntime.jsx("menu", { ref: containerRef, role: "menu", className: classNames.actionList, children: renderButtonList(children) }) })] }));
61
128
  };
62
129
  const MemoizedTriggerButton = React.memo(({ onlyIconTrigger, triggerSize, children, classNames, ...rest }) => {
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenuButton.cjs","sources":["../../../../src/components/Dropdown/DropdownMenuButton/DropdownMenuButton.tsx"],"sourcesContent":["'use client'\n\nimport {\n Children,\n type ComponentProps,\n type ComponentPropsWithRef,\n type ComponentType,\n type FC,\n Fragment,\n type ReactElement,\n type ReactNode,\n isValidElement,\n memo,\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useObjectAttributes } from '../../../hooks/useObjectAttributes'\nimport { Localizer } from '../../../intl'\nimport { type AnchorButton, Button, type BaseProps as ButtonProps } from '../../Button'\nimport { FaCaretDownIcon, FaEllipsisIcon } from '../../Icon'\nimport { Dropdown, DropdownContext } from '../Dropdown'\nimport { DropdownCloser } from '../DropdownCloser'\nimport { DropdownContent } from '../DropdownContent'\nimport { DropdownTrigger } from '../DropdownTrigger'\n\nimport { DropdownMenuGroup } from './DropdownMenuGroup'\nimport useKeyboardNavigation from './useKeyboardNavigation'\n\nimport type { RemoteDialogTrigger } from '../../Dialog'\n\ntype Actions = ActionItem | ActionItem[]\n\n// これでコンポーネントを絞れるわけではないが Button[variant=text] を使ってほしいんだよ! という気持ち\ntype ActionItem =\n | ReactElement<ComponentProps<typeof Button>>\n | ReactElement<ComponentProps<typeof AnchorButton>>\n | ReactElement<ComponentProps<typeof RemoteDialogTrigger>>\n | ReactNode\n\ntype ObjectTriggerType = {\n /** 引き金となるボタンラベル */\n children: ReactNode\n /** 引き金となるボタンの大きさ */\n size?: ButtonProps['size']\n /** 引き金となるボタンをアイコンのみとするかどうか */\n onlyIcon?:\n | boolean\n | {\n /** 引き金となるアイコンを差し替えたい場合(onlyIcon=true の場合のみ有効) */\n component?: ComponentType<ComponentProps<typeof FaCaretDownIcon>>\n }\n}\ntype BaseProps = {\n /** 引き金となるボタン */\n trigger: ReactNode | ObjectTriggerType\n /** 操作群 */\n children: Actions\n /** ドロップダウンメニューが開かれた際のイベント */\n onOpen?: () => void\n /** ドロップダウンメニューが閉じられた際のイベント */\n onClose?: () => void\n}\ntype ElementProps = Omit<ComponentPropsWithRef<'button'>, keyof BaseProps>\ntype Props = BaseProps & ElementProps\n\nconst triggerObjectConverter = (trigger: ReactNode) => ({\n children: trigger,\n})\n\nconst classNameGenerator = tv({\n slots: {\n triggerWrapper: 'smarthr-ui-DropdownMenuButton',\n triggerButton:\n 'smarthr-ui-DropdownMenuButton-trigger [&[aria-expanded=\"true\"]_.smarthr-ui-Icon:last-child]:shr-rotate-180',\n actionList: [\n 'smarthr-ui-DropdownMenuButton-panel',\n 'shr-list-none shr-py-0.5',\n [\n /* unset した Button の右 padding 分 */\n '[&_.smarthr-ui-Button-disabledWrapper]:shr-pe-1',\n '[&_.smarthr-ui-Button-disabledWrapper]:shr-gap-x-0.5',\n '[&_.smarthr-ui-Button-disabledWrapper_>_.smarthr-ui-Button]:shr-w-[unset] [&_.smarthr-ui-Button-disabledWrapper_>_.smarthr-ui-Button]:shr-bg-transparent [&_.smarthr-ui-Button-disabledWrapper_>_.smarthr-ui-Button]:shr-pe-[unset]',\n ],\n ],\n actionListItemButton: [\n // HINT: 実際にレンダリングされた要素のclassに対して追加されるため、優先度を上げる必要がある\n '[&&]:shr-w-full [&&]:shr-justify-start [&&]:shr-rounded-none [&&]:shr-border-none [&&]:shr-py-0.5 [&&]:shr-font-normal',\n '[&&]:focus-visible:shr-focus-indicator',\n ],\n },\n})\n\nconst { triggerWrapper, triggerButton, actionList, actionListItemButton } = classNameGenerator()\n\nexport const DropdownMenuButton: FC<Props> = ({\n trigger,\n children,\n onOpen,\n onClose,\n className,\n ...rest\n}) => {\n const {\n children: triggerChildren,\n size: triggerSize,\n onlyIcon: onlyIconTrigger,\n } = useObjectAttributes<ReactNode | ObjectTriggerType, ObjectTriggerType>(\n trigger,\n triggerObjectConverter,\n )\n\n const containerRef = useRef<HTMLUListElement>(null)\n\n useKeyboardNavigation(containerRef)\n\n const classNames = useMemo(\n () => ({\n triggerWrapper: triggerWrapper({ className }),\n triggerButton: triggerButton(),\n actionList: actionList(),\n }),\n [className],\n )\n\n return (\n <Dropdown onOpen={onOpen} onClose={onClose}>\n <MemoizedTriggerButton\n {...rest}\n onlyIconTrigger={onlyIconTrigger}\n triggerSize={triggerSize}\n classNames={classNames}\n >\n {triggerChildren}\n </MemoizedTriggerButton>\n <DropdownContent controllable={true}>\n <menu ref={containerRef} role=\"menu\" className={classNames.actionList}>\n {renderButtonList(children)}\n </menu>\n </DropdownContent>\n </Dropdown>\n )\n}\n\nconst MemoizedTriggerButton = memo<\n ElementProps & {\n onlyIconTrigger: ObjectTriggerType['onlyIcon']\n triggerSize: ObjectTriggerType['size']\n children: ObjectTriggerType['children']\n classNames: {\n triggerWrapper: string\n triggerButton: string\n }\n }\n>(({ onlyIconTrigger, triggerSize, children, classNames, ...rest }) => {\n const { active } = useContext(DropdownContext)\n\n return (\n <DropdownTrigger\n className={classNames.triggerWrapper}\n tooltip={{ show: !!onlyIconTrigger, message: children }}\n >\n <Button\n {...rest}\n suffix={\n !onlyIconTrigger && (\n <FaCaretDownIcon\n alt={\n active ? (\n <Localizer\n id=\"smarthr-ui/DropdownMenuButton/triggerActive\"\n defaultText=\"候補を閉じる\"\n />\n ) : (\n <Localizer\n id=\"smarthr-ui/DropdownMenuButton/triggerInactive\"\n defaultText=\"候補を開く\"\n />\n )\n }\n />\n )\n }\n size={triggerSize}\n className={classNames.triggerButton}\n >\n <TriggerLabelText onlyIconTrigger={onlyIconTrigger}>{children}</TriggerLabelText>\n </Button>\n </DropdownTrigger>\n )\n})\n\nconst TriggerLabelText = memo<{\n onlyIconTrigger: ObjectTriggerType['onlyIcon']\n children: ObjectTriggerType['children']\n}>(({ children, onlyIconTrigger }) => {\n if (!onlyIconTrigger) {\n return children\n }\n\n const Icon = (typeof onlyIconTrigger === 'object' && onlyIconTrigger.component) || FaEllipsisIcon\n\n return <Icon alt={children} />\n})\n\nexport const renderButtonList = (children: Actions) =>\n Children.map(children, (item): ReactNode => {\n if (!item || !isValidElement(item)) {\n return null\n }\n\n switch (item.type) {\n case Fragment:\n return renderButtonList(item.props.children)\n case DropdownMenuGroup:\n return item\n }\n\n return <ButtonListItem>{item}</ButtonListItem>\n })\n\nconst ButtonListItem: FC<{ children: ReactElement }> = ({ children }) => {\n const ref = useRef<HTMLLIElement>(null)\n\n useEffect(() => {\n const listItem = ref.current\n if (!listItem) {\n return\n }\n\n const setupButton = () => {\n const button = listItem.querySelector('button,a')\n\n if (button) {\n button.setAttribute('role', 'menuitem')\n button.setAttribute(\n 'class',\n actionListItemButton({ className: button.getAttribute('class') }),\n )\n }\n }\n\n setupButton()\n\n const observer = new MutationObserver(setupButton)\n observer.observe(listItem, {\n childList: true,\n subtree: true,\n // button要素の disabled / aria-disabled が動的に変化した場合も検知してリスナーを貼り直す\n attributes: true,\n attributeFilter: ['disabled', 'aria-disabled'],\n })\n\n return () => {\n observer.disconnect()\n }\n }, [])\n\n return (\n <li role=\"presentation\" ref={ref}>\n <DropdownCloser>{children}</DropdownCloser>\n </li>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAqEA;AACE;AACD;AAED;AACE;AACE;AACA;AAEA;;;AAGE;;;;;AAKC;AACF;AACD;;;;AAIC;AACF;AACF;AAED;;;AAmBE;;AAIA;AAEI;;;AAGD;AAIH;AAiBF;AAEA;;;AA8CA;AAEA;;AAKI;;AAGF;AAEA;AACF;AAEO;;AAGD;;AAGF;AACE;;AAEA;AACE;;AAGJ;AACF;AAEF;AACE;;AAGE;;;;;;;AASI;AACA;;AAKJ;AAEA;AAEA;AACA;AACE;AACA;;AAEA;AACA;AACD;AAED;;AAEA;;AAGF;AAKF;;;"}
1
+ {"version":3,"file":"DropdownMenuButton.cjs","sources":["../../../../src/components/Dropdown/DropdownMenuButton/DropdownMenuButton.tsx"],"sourcesContent":["'use client'\n\nimport {\n Children,\n type ComponentProps,\n type ComponentPropsWithRef,\n type ComponentType,\n type FC,\n Fragment,\n type ReactElement,\n type ReactNode,\n isValidElement,\n memo,\n useContext,\n useEffect,\n useMemo,\n useRef,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { useObjectAttributes } from '../../../hooks/useObjectAttributes'\nimport { Localizer } from '../../../intl'\nimport { type AnchorButton, Button, type BaseProps as ButtonProps } from '../../Button'\nimport { FaCaretDownIcon, FaEllipsisIcon } from '../../Icon'\nimport { Dropdown, DropdownContext } from '../Dropdown'\nimport { DropdownCloser } from '../DropdownCloser'\nimport { DropdownContent } from '../DropdownContent'\nimport { DropdownTrigger } from '../DropdownTrigger'\n\nimport { DropdownMenuGroup } from './DropdownMenuGroup'\n\nimport type { RemoteDialogTrigger } from '../../Dialog'\n\ntype Actions = ActionItem | ActionItem[]\n\n// これでコンポーネントを絞れるわけではないが Button[variant=text] を使ってほしいんだよ! という気持ち\ntype ActionItem =\n | ReactElement<ComponentProps<typeof Button>>\n | ReactElement<ComponentProps<typeof AnchorButton>>\n | ReactElement<ComponentProps<typeof RemoteDialogTrigger>>\n | ReactNode\n\ntype ObjectTriggerType = {\n /** 引き金となるボタンラベル */\n children: ReactNode\n /** 引き金となるボタンの大きさ */\n size?: ButtonProps['size']\n /** 引き金となるボタンをアイコンのみとするかどうか */\n onlyIcon?:\n | boolean\n | {\n /** 引き金となるアイコンを差し替えたい場合(onlyIcon=true の場合のみ有効) */\n component?: ComponentType<ComponentProps<typeof FaCaretDownIcon>>\n }\n}\ntype BaseProps = {\n /** 引き金となるボタン */\n trigger: ReactNode | ObjectTriggerType\n /** 操作群 */\n children: Actions\n /** ドロップダウンメニューが開かれた際のイベント */\n onOpen?: () => void\n /** ドロップダウンメニューが閉じられた際のイベント */\n onClose?: () => void\n}\ntype ElementProps = Omit<ComponentPropsWithRef<'button'>, keyof BaseProps>\ntype Props = BaseProps & ElementProps\n\nconst TABBABLE_SELECTOR = 'li button,li a,li [tabindex]:not([tabindex=\"-1\"])'\nconst DISABLED_SELECTOR = ':disabled,[aria-disabled=\"true\"]'\nconst isElementEnabled = (element: Element): boolean =>\n !element.matches(DISABLED_SELECTOR) && !element.querySelector(DISABLED_SELECTOR)\nconst KEY_UP_REGEX = /^(Arrow)?(Up|Left)$/\nconst KEY_DOWN_REGEX = /^(Arrow)?(Down|Right)$/\n\nconst moveFocus = (element: Element, direction: 1 | -1) => {\n let hoveredItem: Element | null = null\n const tabbableItems: Element[] = []\n let focusedIndex: number = -1\n\n const pushTabbaleItem = (item: Element) => {\n tabbableItems.push(item)\n\n if (document.activeElement === item) {\n focusedIndex = tabbableItems.length - 1\n }\n }\n\n element.querySelectorAll(TABBABLE_SELECTOR).forEach((item) => {\n if (hoveredItem === null && item.matches(':hover')) {\n hoveredItem = item\n }\n\n if (isElementEnabled(item)) {\n pushTabbaleItem(item)\n }\n })\n\n let nextIndex = 0\n\n if (focusedIndex > -1) {\n // フォーカスされているアイテムが存在する場合\n nextIndex = (focusedIndex + direction + tabbableItems.length) % tabbableItems.length\n } else if (hoveredItem) {\n // ホバー状態のアイテムが存在する場合\n nextIndex =\n (tabbableItems.indexOf(hoveredItem) + direction + tabbableItems.length) % tabbableItems.length\n } else if (direction === -1) {\n nextIndex = tabbableItems.length - 1\n }\n\n const nextItem = tabbableItems[nextIndex]\n\n if (nextItem instanceof HTMLElement) {\n nextItem.focus()\n }\n}\n\nconst triggerObjectConverter = (trigger: ReactNode) => ({\n children: trigger,\n})\n\nconst classNameGenerator = tv({\n slots: {\n triggerWrapper: 'smarthr-ui-DropdownMenuButton',\n triggerButton:\n 'smarthr-ui-DropdownMenuButton-trigger [&[aria-expanded=\"true\"]_.smarthr-ui-Icon:last-child]:shr-rotate-180',\n actionList: [\n 'smarthr-ui-DropdownMenuButton-panel',\n 'shr-list-none shr-py-0.5',\n [\n /* unset した Button の右 padding 分 */\n '[&_.smarthr-ui-Button-disabledWrapper]:shr-pe-1',\n '[&_.smarthr-ui-Button-disabledWrapper]:shr-gap-x-0.5',\n '[&_.smarthr-ui-Button-disabledWrapper_>_.smarthr-ui-Button]:shr-w-[unset] [&_.smarthr-ui-Button-disabledWrapper_>_.smarthr-ui-Button]:shr-bg-transparent [&_.smarthr-ui-Button-disabledWrapper_>_.smarthr-ui-Button]:shr-pe-[unset]',\n ],\n ],\n actionListItemButton: [\n // HINT: 実際にレンダリングされた要素のclassに対して追加されるため、優先度を上げる必要がある\n '[&&]:shr-w-full [&&]:shr-justify-start [&&]:shr-rounded-none [&&]:shr-border-none [&&]:shr-py-0.5 [&&]:shr-font-normal',\n '[&&]:focus-visible:shr-focus-indicator',\n ],\n },\n})\n\nconst { triggerWrapper, triggerButton, actionList, actionListItemButton } = classNameGenerator()\n\nexport const DropdownMenuButton: FC<Props> = ({\n trigger,\n children,\n onOpen,\n onClose,\n className,\n ...rest\n}) => {\n const {\n children: triggerChildren,\n size: triggerSize,\n onlyIcon: onlyIconTrigger,\n } = useObjectAttributes<ReactNode | ObjectTriggerType, ObjectTriggerType>(\n trigger,\n triggerObjectConverter,\n )\n\n const containerRef = useRef<HTMLUListElement>(null)\n\n const classNames = useMemo(\n () => ({\n triggerWrapper: triggerWrapper({ className }),\n triggerButton: triggerButton(),\n actionList: actionList(),\n }),\n [className],\n )\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!containerRef.current || !document.activeElement) {\n return\n }\n\n let direction: -1 | 0 | 1 = 0\n\n // HINT: tabとarrow keyで挙動を揃えるため、tabもhandling対象にする\n if (e.key === 'Tab') {\n // HINT: tbのデフォルトの挙動の場合のみ、preventDefaultが必要\n e.preventDefault()\n direction = e.shiftKey ? -1 : 1\n } else if (KEY_UP_REGEX.test(e.key)) {\n direction = -1\n } else if (KEY_DOWN_REGEX.test(e.key)) {\n direction = 1\n }\n\n if (direction !== 0) {\n moveFocus(containerRef.current, direction)\n }\n }\n\n const eventKey = 'keydown'\n\n document.addEventListener(eventKey, handleKeyDown)\n\n return () => {\n document.removeEventListener(eventKey, handleKeyDown)\n }\n }, [])\n\n return (\n <Dropdown onOpen={onOpen} onClose={onClose}>\n <MemoizedTriggerButton\n {...rest}\n onlyIconTrigger={onlyIconTrigger}\n triggerSize={triggerSize}\n classNames={classNames}\n >\n {triggerChildren}\n </MemoizedTriggerButton>\n <DropdownContent controllable={true}>\n <menu ref={containerRef} role=\"menu\" className={classNames.actionList}>\n {renderButtonList(children)}\n </menu>\n </DropdownContent>\n </Dropdown>\n )\n}\n\nconst MemoizedTriggerButton = memo<\n ElementProps & {\n onlyIconTrigger: ObjectTriggerType['onlyIcon']\n triggerSize: ObjectTriggerType['size']\n children: ObjectTriggerType['children']\n classNames: {\n triggerWrapper: string\n triggerButton: string\n }\n }\n>(({ onlyIconTrigger, triggerSize, children, classNames, ...rest }) => {\n const { active } = useContext(DropdownContext)\n\n return (\n <DropdownTrigger\n className={classNames.triggerWrapper}\n tooltip={{ show: !!onlyIconTrigger, message: children }}\n >\n <Button\n {...rest}\n suffix={\n !onlyIconTrigger && (\n <FaCaretDownIcon\n alt={\n active ? (\n <Localizer\n id=\"smarthr-ui/DropdownMenuButton/triggerActive\"\n defaultText=\"候補を閉じる\"\n />\n ) : (\n <Localizer\n id=\"smarthr-ui/DropdownMenuButton/triggerInactive\"\n defaultText=\"候補を開く\"\n />\n )\n }\n />\n )\n }\n size={triggerSize}\n className={classNames.triggerButton}\n >\n <TriggerLabelText onlyIconTrigger={onlyIconTrigger}>{children}</TriggerLabelText>\n </Button>\n </DropdownTrigger>\n )\n})\n\nconst TriggerLabelText = memo<{\n onlyIconTrigger: ObjectTriggerType['onlyIcon']\n children: ObjectTriggerType['children']\n}>(({ children, onlyIconTrigger }) => {\n if (!onlyIconTrigger) {\n return children\n }\n\n const Icon = (typeof onlyIconTrigger === 'object' && onlyIconTrigger.component) || FaEllipsisIcon\n\n return <Icon alt={children} />\n})\n\nexport const renderButtonList = (children: Actions) =>\n Children.map(children, (item): ReactNode => {\n if (!item || !isValidElement(item)) {\n return null\n }\n\n switch (item.type) {\n case Fragment:\n return renderButtonList(item.props.children)\n case DropdownMenuGroup:\n return item\n }\n\n return <ButtonListItem>{item}</ButtonListItem>\n })\n\nconst ButtonListItem: FC<{ children: ReactElement }> = ({ children }) => {\n const ref = useRef<HTMLLIElement>(null)\n\n useEffect(() => {\n const listItem = ref.current\n if (!listItem) {\n return\n }\n\n const setupButton = () => {\n const button = listItem.querySelector('button,a')\n\n if (button) {\n button.setAttribute('role', 'menuitem')\n button.setAttribute(\n 'class',\n actionListItemButton({ className: button.getAttribute('class') }),\n )\n }\n }\n\n setupButton()\n\n const observer = new MutationObserver(setupButton)\n observer.observe(listItem, {\n childList: true,\n subtree: true,\n // button要素の disabled / aria-disabled が動的に変化した場合も検知してリスナーを貼り直す\n attributes: true,\n attributeFilter: ['disabled', 'aria-disabled'],\n })\n\n return () => {\n observer.disconnect()\n }\n }, [])\n\n return (\n <li role=\"presentation\" ref={ref}>\n <DropdownCloser>{children}</DropdownCloser>\n </li>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAoEA;AACA;AACA;AAEA;AACA;AAEA;;;AAGE;AAEA;AACE;AAEA;AACE;;AAEJ;;;;;AAOE;;;AAGF;;AAIA;;AAEE;;;;;AAIE;;AACG;AACL;;AAGF;AAEA;;;AAGF;AAEA;AACE;AACD;AAED;AACE;AACE;AACA;AAEA;;;AAGE;;;;;AAKC;AACF;AACD;;;;AAIC;AACF;AACF;AAED;;;AAmBE;AAEA;AAEI;;;AAGD;;AAKD;;;;;;AAQE;;;AAGE;;;;;;;;AAOF;AACE;;AAEJ;;AAIA;AAEA;AACE;AACF;;AAGF;AAiBF;AAEA;;;AA8CA;AAEA;;AAKI;;AAGF;AAEA;AACF;AAEO;;AAGD;;AAGF;AACE;;AAEA;AACE;;AAGJ;AACF;AAEF;AACE;;AAGE;;;;;;;AASI;AACA;;AAKJ;AAEA;AAEA;AACA;AACE;AACA;;AAEA;AACA;AACD;AAED;;AAEA;;AAGF;AAKF;;;"}