smarthr-ui 96.1.3 → 98.0.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 (341) hide show
  1. package/lib/components/AppHeader/components/common/AppLauncherFeatures.cjs +1 -1
  2. package/lib/components/AppHeader/components/common/AppLauncherFeatures.js +1 -1
  3. package/lib/components/AppHeader/components/common/AppLauncherSortDropdown.cjs +1 -1
  4. package/lib/components/AppHeader/components/common/AppLauncherSortDropdown.js +1 -1
  5. package/lib/components/AppHeader/components/desktop/AppLauncher.cjs +5 -5
  6. package/lib/components/AppHeader/components/desktop/AppLauncher.cjs.map +1 -1
  7. package/lib/components/AppHeader/components/desktop/AppLauncher.js +5 -5
  8. package/lib/components/AppHeader/components/desktop/AppLauncher.js.map +1 -1
  9. package/lib/components/AppHeader/components/desktop/DesktopHeader.cjs +1 -1
  10. package/lib/components/AppHeader/components/desktop/DesktopHeader.js +1 -1
  11. package/lib/components/AppHeader/components/desktop/ReleaseNotesDropdown.cjs +1 -1
  12. package/lib/components/AppHeader/components/desktop/ReleaseNotesDropdown.js +1 -1
  13. package/lib/components/AppHeader/components/desktop/UserInfo.cjs +1 -1
  14. package/lib/components/AppHeader/components/desktop/UserInfo.js +1 -1
  15. package/lib/components/AppHeader/components/mobile/AppLauncher.cjs +1 -1
  16. package/lib/components/AppHeader/components/mobile/AppLauncher.js +1 -1
  17. package/lib/components/AppHeader/components/mobile/AppLauncherFilterDropdown.cjs +1 -1
  18. package/lib/components/AppHeader/components/mobile/AppLauncherFilterDropdown.js +1 -1
  19. package/lib/components/AppHeader/components/mobile/Help.cjs +1 -1
  20. package/lib/components/AppHeader/components/mobile/Help.js +1 -1
  21. package/lib/components/AppHeader/components/mobile/LanguageSelector.cjs +1 -1
  22. package/lib/components/AppHeader/components/mobile/LanguageSelector.js +1 -1
  23. package/lib/components/AppHeader/components/mobile/Menu.cjs +1 -1
  24. package/lib/components/AppHeader/components/mobile/Menu.js +1 -1
  25. package/lib/components/AppHeader/components/mobile/MenuAccordion.cjs +1 -1
  26. package/lib/components/AppHeader/components/mobile/MenuAccordion.js +1 -1
  27. package/lib/components/AppHeader/components/mobile/MenuDialog.cjs +2 -2
  28. package/lib/components/AppHeader/components/mobile/MenuDialog.js +2 -2
  29. package/lib/components/AppHeader/components/mobile/MenuSubHeading.cjs +1 -1
  30. package/lib/components/AppHeader/components/mobile/MenuSubHeading.js +1 -1
  31. package/lib/components/AppHeader/components/mobile/ReleaseNote.cjs +1 -1
  32. package/lib/components/AppHeader/components/mobile/ReleaseNote.js +1 -1
  33. package/lib/components/AppHeader/components/mobile/UserInfo.cjs +2 -2
  34. package/lib/components/AppHeader/components/mobile/UserInfo.js +2 -2
  35. package/lib/components/Browser/Browser.cjs +11 -7
  36. package/lib/components/Browser/Browser.cjs.map +1 -1
  37. package/lib/components/Browser/Browser.js +12 -8
  38. package/lib/components/Browser/Browser.js.map +1 -1
  39. package/lib/components/Calendar/Calendar.cjs +1 -1
  40. package/lib/components/Calendar/Calendar.js +1 -1
  41. package/lib/components/Calendar/CalendarTable.cjs +1 -1
  42. package/lib/components/Calendar/CalendarTable.js +1 -1
  43. package/lib/components/Calendar/YearPicker.cjs +1 -1
  44. package/lib/components/Calendar/YearPicker.js +1 -1
  45. package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs +122 -134
  46. package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs.map +1 -1
  47. package/lib/components/Combobox/MultiCombobox/MultiCombobox.js +123 -135
  48. package/lib/components/Combobox/MultiCombobox/MultiCombobox.js.map +1 -1
  49. package/lib/components/Combobox/MultiCombobox/MultiSelectedItem.cjs +1 -1
  50. package/lib/components/Combobox/MultiCombobox/MultiSelectedItem.js +1 -1
  51. package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs +96 -46
  52. package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs.map +1 -1
  53. package/lib/components/Combobox/SingleCombobox/SingleCombobox.js +98 -48
  54. package/lib/components/Combobox/SingleCombobox/SingleCombobox.js.map +1 -1
  55. package/lib/components/Combobox/helper.cjs +29 -13
  56. package/lib/components/Combobox/helper.cjs.map +1 -1
  57. package/lib/components/Combobox/helper.d.ts +1 -1
  58. package/lib/components/Combobox/helper.js +29 -13
  59. package/lib/components/Combobox/helper.js.map +1 -1
  60. package/lib/components/Combobox/useListbox.cjs +1 -1
  61. package/lib/components/Combobox/useListbox.js +1 -1
  62. package/lib/components/Combobox/useOptions.cjs +24 -18
  63. package/lib/components/Combobox/useOptions.cjs.map +1 -1
  64. package/lib/components/Combobox/useOptions.js +25 -19
  65. package/lib/components/Combobox/useOptions.js.map +1 -1
  66. package/lib/components/Dialog/ControlledActionDialog/ActionDialogContentInner.cjs +3 -3
  67. package/lib/components/Dialog/ControlledActionDialog/ActionDialogContentInner.cjs.map +1 -1
  68. package/lib/components/Dialog/ControlledActionDialog/ActionDialogContentInner.js +3 -3
  69. package/lib/components/Dialog/ControlledActionDialog/ActionDialogContentInner.js.map +1 -1
  70. package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.cjs +3 -3
  71. package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.cjs.map +1 -1
  72. package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.js +3 -3
  73. package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.js.map +1 -1
  74. package/lib/components/Dialog/ControlledMessageDialog/MessageDialogContentInner.cjs +1 -1
  75. package/lib/components/Dialog/ControlledMessageDialog/MessageDialogContentInner.js +1 -1
  76. package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.cjs +1 -1
  77. package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.js +1 -1
  78. package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.cjs +2 -2
  79. package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.cjs.map +1 -1
  80. package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.js +2 -2
  81. package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.js.map +1 -1
  82. package/lib/components/Dialog/DialogContentInner.cjs +8 -1
  83. package/lib/components/Dialog/DialogContentInner.cjs.map +1 -1
  84. package/lib/components/Dialog/DialogContentInner.js +9 -2
  85. package/lib/components/Dialog/DialogContentInner.js.map +1 -1
  86. package/lib/components/Dialog/DialogContentResponseStatusMessage.cjs +3 -8
  87. package/lib/components/Dialog/DialogContentResponseStatusMessage.cjs.map +1 -1
  88. package/lib/components/Dialog/DialogContentResponseStatusMessage.d.ts +1 -1
  89. package/lib/components/Dialog/DialogContentResponseStatusMessage.js +3 -8
  90. package/lib/components/Dialog/DialogContentResponseStatusMessage.js.map +1 -1
  91. package/lib/components/Dialog/FocusTrap.cjs +4 -1
  92. package/lib/components/Dialog/FocusTrap.cjs.map +1 -1
  93. package/lib/components/Dialog/FocusTrap.js +4 -1
  94. package/lib/components/Dialog/FocusTrap.js.map +1 -1
  95. package/lib/components/Dialog/ModelessDialog/ModelessDialog.cjs +14 -12
  96. package/lib/components/Dialog/ModelessDialog/ModelessDialog.cjs.map +1 -1
  97. package/lib/components/Dialog/ModelessDialog/ModelessDialog.js +14 -12
  98. package/lib/components/Dialog/ModelessDialog/ModelessDialog.js.map +1 -1
  99. package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.cjs +5 -2
  100. package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.cjs.map +1 -1
  101. package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.js +5 -2
  102. package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.js.map +1 -1
  103. package/lib/components/Disclosure/DisclosureTrigger.cjs +39 -18
  104. package/lib/components/Disclosure/DisclosureTrigger.cjs.map +1 -1
  105. package/lib/components/Disclosure/DisclosureTrigger.js +40 -19
  106. package/lib/components/Disclosure/DisclosureTrigger.js.map +1 -1
  107. package/lib/components/Disclosure/useDisclosure.cjs +8 -14
  108. package/lib/components/Disclosure/useDisclosure.cjs.map +1 -1
  109. package/lib/components/Disclosure/useDisclosure.js +8 -14
  110. package/lib/components/Disclosure/useDisclosure.js.map +1 -1
  111. package/lib/components/DropZone/DropZone.cjs +1 -1
  112. package/lib/components/DropZone/DropZone.js +1 -1
  113. package/lib/components/Dropdown/Dropdown.cjs +36 -34
  114. package/lib/components/Dropdown/Dropdown.cjs.map +1 -1
  115. package/lib/components/Dropdown/Dropdown.js +37 -35
  116. package/lib/components/Dropdown/Dropdown.js.map +1 -1
  117. package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.cjs +5 -3
  118. package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.cjs.map +1 -1
  119. package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.js +5 -3
  120. package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.js.map +1 -1
  121. package/lib/components/Dropdown/DropdownTrigger.cjs +3 -0
  122. package/lib/components/Dropdown/DropdownTrigger.cjs.map +1 -1
  123. package/lib/components/Dropdown/DropdownTrigger.js +3 -0
  124. package/lib/components/Dropdown/DropdownTrigger.js.map +1 -1
  125. package/lib/components/Dropdown/FilterDropdown/FilterDropdown.cjs +3 -5
  126. package/lib/components/Dropdown/FilterDropdown/FilterDropdown.cjs.map +1 -1
  127. package/lib/components/Dropdown/FilterDropdown/FilterDropdown.d.ts +1 -1
  128. package/lib/components/Dropdown/FilterDropdown/FilterDropdown.js +3 -5
  129. package/lib/components/Dropdown/FilterDropdown/FilterDropdown.js.map +1 -1
  130. package/lib/components/Dropdown/SortDropdown/useSortDropdown.cjs +1 -1
  131. package/lib/components/Dropdown/SortDropdown/useSortDropdown.js +1 -1
  132. package/lib/components/ErrorScreen/AuthErrorScreen.cjs +1 -1
  133. package/lib/components/ErrorScreen/AuthErrorScreen.js +1 -1
  134. package/lib/components/ErrorScreen/ForbiddenErrorScreen.cjs +1 -1
  135. package/lib/components/ErrorScreen/ForbiddenErrorScreen.js +1 -1
  136. package/lib/components/ErrorScreen/NotFoundErrorScreen.cjs +1 -1
  137. package/lib/components/ErrorScreen/NotFoundErrorScreen.js +1 -1
  138. package/lib/components/ErrorScreen/UnauthorizedErrorScreen.cjs +1 -1
  139. package/lib/components/ErrorScreen/UnauthorizedErrorScreen.js +1 -1
  140. package/lib/components/FormControl/FormControl.cjs +2 -22
  141. package/lib/components/FormControl/FormControl.cjs.map +1 -1
  142. package/lib/components/FormControl/FormControl.js +2 -22
  143. package/lib/components/FormControl/FormControl.js.map +1 -1
  144. package/lib/components/Header/AppLauncher/AppLauncher.cjs +1 -1
  145. package/lib/components/Header/AppLauncher/AppLauncher.js +1 -1
  146. package/lib/components/Header/LanguageSwitcher/LanguageSwitcher.cjs +1 -1
  147. package/lib/components/Header/LanguageSwitcher/LanguageSwitcher.js +1 -1
  148. package/lib/components/Icon/OpenInNewTabIcon.cjs +1 -1
  149. package/lib/components/Icon/OpenInNewTabIcon.js +1 -1
  150. package/lib/components/InformationPanel/InformationPanel.cjs +1 -1
  151. package/lib/components/InformationPanel/InformationPanel.js +1 -1
  152. package/lib/components/Input/SearchInput/SearchInputIcon.cjs +1 -1
  153. package/lib/components/Input/SearchInput/SearchInputIcon.js +1 -1
  154. package/lib/components/InputFile/InputFileMultiplyAppendable.cjs +13 -18
  155. package/lib/components/InputFile/InputFileMultiplyAppendable.cjs.map +1 -1
  156. package/lib/components/InputFile/InputFileMultiplyAppendable.js +13 -18
  157. package/lib/components/InputFile/InputFileMultiplyAppendable.js.map +1 -1
  158. package/lib/components/InputFile/InputFileNative.cjs +1 -1
  159. package/lib/components/InputFile/InputFileNative.js +1 -1
  160. package/lib/components/Layout/Cluster/Cluster.cjs +0 -1
  161. package/lib/components/Layout/Cluster/Cluster.cjs.map +1 -1
  162. package/lib/components/Layout/Cluster/Cluster.js +0 -1
  163. package/lib/components/Layout/Cluster/Cluster.js.map +1 -1
  164. package/lib/components/Layout/Container/Container.cjs +1 -5
  165. package/lib/components/Layout/Container/Container.cjs.map +1 -1
  166. package/lib/components/Layout/Container/Container.js +1 -5
  167. package/lib/components/Layout/Container/Container.js.map +1 -1
  168. package/lib/components/Layout/Stack/Stack.cjs +22 -22
  169. package/lib/components/Layout/Stack/Stack.cjs.map +1 -1
  170. package/lib/components/Layout/Stack/Stack.js +22 -22
  171. package/lib/components/Layout/Stack/Stack.js.map +1 -1
  172. package/lib/components/LineClamp/LineClamp.cjs +14 -3
  173. package/lib/components/LineClamp/LineClamp.cjs.map +1 -1
  174. package/lib/components/LineClamp/LineClamp.js +14 -3
  175. package/lib/components/LineClamp/LineClamp.js.map +1 -1
  176. package/lib/components/Loader/LoaderSpinner.cjs +1 -1
  177. package/lib/components/Loader/LoaderSpinner.js +1 -1
  178. package/lib/components/Pagination/Pagination.cjs +1 -1
  179. package/lib/components/Pagination/Pagination.js +1 -1
  180. package/lib/components/Pagination/PaginationItemButton.cjs +1 -1
  181. package/lib/components/Pagination/PaginationItemButton.js +1 -1
  182. package/lib/components/Select/Select.cjs +11 -11
  183. package/lib/components/Select/Select.cjs.map +1 -1
  184. package/lib/components/Select/Select.js +12 -12
  185. package/lib/components/Select/Select.js.map +1 -1
  186. package/lib/components/SideNav/SideNav.cjs +3 -22
  187. package/lib/components/SideNav/SideNav.cjs.map +1 -1
  188. package/lib/components/SideNav/SideNav.d.ts +2 -9
  189. package/lib/components/SideNav/SideNav.js +4 -23
  190. package/lib/components/SideNav/SideNav.js.map +1 -1
  191. package/lib/components/SideNav/SideNavContext.cjs +11 -0
  192. package/lib/components/SideNav/SideNavContext.cjs.map +1 -0
  193. package/lib/components/SideNav/SideNavContext.d.ts +7 -0
  194. package/lib/components/SideNav/SideNavContext.js +8 -0
  195. package/lib/components/SideNav/SideNavContext.js.map +1 -0
  196. package/lib/components/SideNav/SideNavItemButton.cjs +12 -7
  197. package/lib/components/SideNav/SideNavItemButton.cjs.map +1 -1
  198. package/lib/components/SideNav/SideNavItemButton.d.ts +5 -11
  199. package/lib/components/SideNav/SideNavItemButton.js +12 -7
  200. package/lib/components/SideNav/SideNavItemButton.js.map +1 -1
  201. package/lib/components/TabBar/TabItem.cjs +11 -9
  202. package/lib/components/TabBar/TabItem.cjs.map +1 -1
  203. package/lib/components/TabBar/TabItem.d.ts +2 -2
  204. package/lib/components/TabBar/TabItem.js +13 -11
  205. package/lib/components/TabBar/TabItem.js.map +1 -1
  206. package/lib/components/Table/Th.cjs +2 -2
  207. package/lib/components/Table/Th.cjs.map +1 -1
  208. package/lib/components/Table/Th.d.ts +0 -2
  209. package/lib/components/Table/Th.js +2 -2
  210. package/lib/components/Table/Th.js.map +1 -1
  211. package/lib/components/Table/ThCheckbox.cjs +1 -1
  212. package/lib/components/Table/ThCheckbox.js +1 -1
  213. package/lib/components/Table/ThSortButton.cjs +5 -6
  214. package/lib/components/Table/ThSortButton.cjs.map +1 -1
  215. package/lib/components/Table/ThSortButton.d.ts +1 -6
  216. package/lib/components/Table/ThSortButton.js +5 -6
  217. package/lib/components/Table/ThSortButton.js.map +1 -1
  218. package/lib/components/WarekiPicker/WarekiPicker.cjs +1 -1
  219. package/lib/components/WarekiPicker/WarekiPicker.js +1 -1
  220. package/lib/hooks/useHandleEscape.cjs +4 -4
  221. package/lib/hooks/useHandleEscape.cjs.map +1 -1
  222. package/lib/hooks/useHandleEscape.d.ts +1 -1
  223. package/lib/hooks/useHandleEscape.js +4 -4
  224. package/lib/hooks/useHandleEscape.js.map +1 -1
  225. package/lib/index.cjs +1 -6
  226. package/lib/index.cjs.map +1 -1
  227. package/lib/index.d.ts +0 -1
  228. package/lib/index.js +1 -4
  229. package/lib/index.js.map +1 -1
  230. package/lib/intl/Localizer.cjs +5 -1
  231. package/lib/intl/Localizer.cjs.map +1 -1
  232. package/lib/intl/Localizer.d.ts +4 -4
  233. package/lib/intl/Localizer.js +5 -1
  234. package/lib/intl/Localizer.js.map +1 -1
  235. package/lib/intl/locales/en_us.json.cjs +133 -0
  236. package/lib/intl/locales/en_us.json.cjs.map +1 -0
  237. package/lib/intl/locales/en_us.json.js +131 -0
  238. package/lib/intl/locales/en_us.json.js.map +1 -0
  239. package/lib/intl/locales/id_id.json.cjs +133 -0
  240. package/lib/intl/locales/id_id.json.cjs.map +1 -0
  241. package/lib/intl/locales/id_id.json.js +131 -0
  242. package/lib/intl/locales/id_id.json.js.map +1 -0
  243. package/lib/intl/locales/index.cjs +24 -18
  244. package/lib/intl/locales/index.cjs.map +1 -1
  245. package/lib/intl/locales/index.d.ts +1135 -1136
  246. package/lib/intl/locales/index.js +25 -19
  247. package/lib/intl/locales/index.js.map +1 -1
  248. package/lib/intl/locales/ja.json.cjs +133 -0
  249. package/lib/intl/locales/ja.json.cjs.map +1 -0
  250. package/lib/intl/locales/ja.json.js +131 -0
  251. package/lib/intl/locales/ja.json.js.map +1 -0
  252. package/lib/intl/locales/ja_easy.json.cjs +133 -0
  253. package/lib/intl/locales/ja_easy.json.cjs.map +1 -0
  254. package/lib/intl/locales/ja_easy.json.js +131 -0
  255. package/lib/intl/locales/ja_easy.json.js.map +1 -0
  256. package/lib/intl/locales/ko_kr.json.cjs +133 -0
  257. package/lib/intl/locales/ko_kr.json.cjs.map +1 -0
  258. package/lib/intl/locales/ko_kr.json.js +131 -0
  259. package/lib/intl/locales/ko_kr.json.js.map +1 -0
  260. package/lib/intl/locales/pt_br.json.cjs +133 -0
  261. package/lib/intl/locales/pt_br.json.cjs.map +1 -0
  262. package/lib/intl/locales/pt_br.json.js +131 -0
  263. package/lib/intl/locales/pt_br.json.js.map +1 -0
  264. package/lib/intl/locales/vi_vn.json.cjs +133 -0
  265. package/lib/intl/locales/vi_vn.json.cjs.map +1 -0
  266. package/lib/intl/locales/vi_vn.json.js +131 -0
  267. package/lib/intl/locales/vi_vn.json.js.map +1 -0
  268. package/lib/intl/locales/zh_hans_cn.json.cjs +133 -0
  269. package/lib/intl/locales/zh_hans_cn.json.cjs.map +1 -0
  270. package/lib/intl/locales/zh_hans_cn.json.js +131 -0
  271. package/lib/intl/locales/zh_hans_cn.json.js.map +1 -0
  272. package/lib/intl/locales/zh_hant_tw.json.cjs +133 -0
  273. package/lib/intl/locales/zh_hant_tw.json.cjs.map +1 -0
  274. package/lib/intl/locales/zh_hant_tw.json.js +131 -0
  275. package/lib/intl/locales/zh_hant_tw.json.js.map +1 -0
  276. package/lib/intl/useIntl.cjs.map +1 -1
  277. package/lib/intl/useIntl.d.ts +3 -3
  278. package/lib/intl/useIntl.js.map +1 -1
  279. package/metadata.json +1 -1
  280. package/package.json +2 -1
  281. package/smarthr-ui.css +0 -94
  282. package/lib/hooks/useDecorators.cjs +0 -18
  283. package/lib/hooks/useDecorators.cjs.map +0 -1
  284. package/lib/hooks/useDecorators.d.ts +0 -6
  285. package/lib/hooks/useDecorators.js +0 -16
  286. package/lib/hooks/useDecorators.js.map +0 -1
  287. package/lib/hooks/useDevice/DeviceProvider.cjs +0 -37
  288. package/lib/hooks/useDevice/DeviceProvider.cjs.map +0 -1
  289. package/lib/hooks/useDevice/DeviceProvider.d.ts +0 -4
  290. package/lib/hooks/useDevice/DeviceProvider.js +0 -35
  291. package/lib/hooks/useDevice/DeviceProvider.js.map +0 -1
  292. package/lib/hooks/useDevice/index.cjs +0 -10
  293. package/lib/hooks/useDevice/index.cjs.map +0 -1
  294. package/lib/hooks/useDevice/index.d.ts +0 -2
  295. package/lib/hooks/useDevice/index.js +0 -3
  296. package/lib/hooks/useDevice/index.js.map +0 -1
  297. package/lib/hooks/useDevice/useDevice.cjs +0 -11
  298. package/lib/hooks/useDevice/useDevice.cjs.map +0 -1
  299. package/lib/hooks/useDevice/useDevice.d.ts +0 -4
  300. package/lib/hooks/useDevice/useDevice.js +0 -8
  301. package/lib/hooks/useDevice/useDevice.js.map +0 -1
  302. package/lib/intl/locales/en_us.cjs +0 -135
  303. package/lib/intl/locales/en_us.cjs.map +0 -1
  304. package/lib/intl/locales/en_us.d.ts +0 -128
  305. package/lib/intl/locales/en_us.js +0 -133
  306. package/lib/intl/locales/en_us.js.map +0 -1
  307. package/lib/intl/locales/id_id.cjs +0 -135
  308. package/lib/intl/locales/id_id.cjs.map +0 -1
  309. package/lib/intl/locales/id_id.d.ts +0 -128
  310. package/lib/intl/locales/id_id.js +0 -133
  311. package/lib/intl/locales/id_id.js.map +0 -1
  312. package/lib/intl/locales/ja_easy.cjs +0 -135
  313. package/lib/intl/locales/ja_easy.cjs.map +0 -1
  314. package/lib/intl/locales/ja_easy.d.ts +0 -128
  315. package/lib/intl/locales/ja_easy.js +0 -133
  316. package/lib/intl/locales/ja_easy.js.map +0 -1
  317. package/lib/intl/locales/ko_kr.cjs +0 -135
  318. package/lib/intl/locales/ko_kr.cjs.map +0 -1
  319. package/lib/intl/locales/ko_kr.d.ts +0 -128
  320. package/lib/intl/locales/ko_kr.js +0 -133
  321. package/lib/intl/locales/ko_kr.js.map +0 -1
  322. package/lib/intl/locales/pt_br.cjs +0 -135
  323. package/lib/intl/locales/pt_br.cjs.map +0 -1
  324. package/lib/intl/locales/pt_br.d.ts +0 -128
  325. package/lib/intl/locales/pt_br.js +0 -133
  326. package/lib/intl/locales/pt_br.js.map +0 -1
  327. package/lib/intl/locales/vi_vn.cjs +0 -135
  328. package/lib/intl/locales/vi_vn.cjs.map +0 -1
  329. package/lib/intl/locales/vi_vn.d.ts +0 -128
  330. package/lib/intl/locales/vi_vn.js +0 -133
  331. package/lib/intl/locales/vi_vn.js.map +0 -1
  332. package/lib/intl/locales/zh_hans_cn.cjs +0 -135
  333. package/lib/intl/locales/zh_hans_cn.cjs.map +0 -1
  334. package/lib/intl/locales/zh_hans_cn.d.ts +0 -128
  335. package/lib/intl/locales/zh_hans_cn.js +0 -133
  336. package/lib/intl/locales/zh_hans_cn.js.map +0 -1
  337. package/lib/intl/locales/zh_hant_tw.cjs +0 -135
  338. package/lib/intl/locales/zh_hant_tw.cjs.map +0 -1
  339. package/lib/intl/locales/zh_hant_tw.d.ts +0 -128
  340. package/lib/intl/locales/zh_hant_tw.js +0 -133
  341. package/lib/intl/locales/zh_hant_tw.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useDisclosure.cjs","sources":["../../../src/components/Disclosure/useDisclosure.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\n\nconst DISCLOSURE_CHANGE_EVENT = 'smarthr-ui:disclosure-change'\ntype DisclosureChangeEventDetail = { id: string; expanded: boolean }\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface DocumentEventMap {\n [DISCLOSURE_CHANGE_EVENT]: CustomEvent<DisclosureChangeEventDetail>\n }\n}\n\ntype Setter = (value: boolean | ((prev: boolean) => boolean)) => void\n\ntype UseDisclosureResult = [expanded: boolean, setExpanded: Setter]\n\n/**\n * 同じ `id` で呼ぶとイベント経由で状態が同期される custom hook\n */\nexport const useDisclosure = (id: string): UseDisclosureResult => {\n const [expanded, setExpanded] = useState(false)\n\n useEffect(() => {\n document.dispatchEvent(\n new CustomEvent<DisclosureChangeEventDetail>(DISCLOSURE_CHANGE_EVENT, {\n detail: { id, expanded },\n }),\n )\n }, [expanded, id])\n\n const handleDisclosureChange = useCallback(\n (e: CustomEvent<DisclosureChangeEventDetail>) => {\n if (id === e.detail.id) {\n setExpanded(e.detail.expanded)\n }\n },\n [id],\n )\n\n useEffect(() => {\n document.addEventListener(DISCLOSURE_CHANGE_EVENT, handleDisclosureChange)\n return () => {\n document.removeEventListener(DISCLOSURE_CHANGE_EVENT, handleDisclosureChange)\n }\n }, [id, handleDisclosureChange])\n\n const safeSetExpanded: Setter = useCallback(\n (value) => {\n // DisclosureTrigger と DisclosureContent のレンダリング順序に影響しないように animation frame を待ってから state を更新する\n requestAnimationFrame(() => {\n if (typeof value === 'function') {\n const newValue = value(expanded)\n setExpanded(newValue)\n } else {\n setExpanded(value)\n }\n })\n },\n [expanded],\n )\n\n return [expanded, safeSetExpanded]\n}\n"],"names":["useState","useEffect","useCallback"],"mappings":";;;;AAEA,MAAM,uBAAuB,GAAG,8BAA8B;AAc9D;;AAEG;AACI,MAAM,aAAa,GAAG,CAAC,EAAU,KAAyB;IAC/D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAGA,cAAQ,CAAC,KAAK,CAAC;IAE/CC,eAAS,CAAC,MAAK;AACb,QAAA,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAA8B,uBAAuB,EAAE;AACpE,YAAA,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;AACzB,SAAA,CAAC,CACH;AACH,IAAA,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAElB,IAAA,MAAM,sBAAsB,GAAGC,iBAAW,CACxC,CAAC,CAA2C,KAAI;QAC9C,IAAI,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE;AACtB,YAAA,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;QAChC;AACF,IAAA,CAAC,EACD,CAAC,EAAE,CAAC,CACL;IAEDD,eAAS,CAAC,MAAK;AACb,QAAA,QAAQ,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,sBAAsB,CAAC;AAC1E,QAAA,OAAO,MAAK;AACV,YAAA,QAAQ,CAAC,mBAAmB,CAAC,uBAAuB,EAAE,sBAAsB,CAAC;AAC/E,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,EAAE,EAAE,sBAAsB,CAAC,CAAC;AAEhC,IAAA,MAAM,eAAe,GAAWC,iBAAW,CACzC,CAAC,KAAK,KAAI;;QAER,qBAAqB,CAAC,MAAK;AACzB,YAAA,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE;AAC/B,gBAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;gBAChC,WAAW,CAAC,QAAQ,CAAC;YACvB;iBAAO;gBACL,WAAW,CAAC,KAAK,CAAC;YACpB;AACF,QAAA,CAAC,CAAC;AACJ,IAAA,CAAC,EACD,CAAC,QAAQ,CAAC,CACX;AAED,IAAA,OAAO,CAAC,QAAQ,EAAE,eAAe,CAAC;AACpC;;;;"}
1
+ {"version":3,"file":"useDisclosure.cjs","sources":["../../../src/components/Disclosure/useDisclosure.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\n\nconst DISCLOSURE_CHANGE_EVENT = 'smarthr-ui:disclosure-change'\ntype DisclosureChangeEventDetail = { id: string; expanded: boolean }\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface DocumentEventMap {\n [DISCLOSURE_CHANGE_EVENT]: CustomEvent<DisclosureChangeEventDetail>\n }\n}\n\ntype Setter = (value: boolean | ((prev: boolean) => boolean)) => void\n\ntype UseDisclosureResult = [expanded: boolean, setExpanded: Setter]\n\n/**\n * 同じ `id` で呼ぶとイベント経由で状態が同期される custom hook\n */\nexport const useDisclosure = (id: string): UseDisclosureResult => {\n const [expanded, setExpanded] = useState(false)\n\n useEffect(() => {\n document.dispatchEvent(\n new CustomEvent<DisclosureChangeEventDetail>(DISCLOSURE_CHANGE_EVENT, {\n detail: { id, expanded },\n }),\n )\n }, [expanded, id])\n\n useEffect(() => {\n const handleDisclosureChange = (e: CustomEvent<DisclosureChangeEventDetail>) => {\n if (id === e.detail.id) {\n setExpanded(e.detail.expanded)\n }\n }\n\n document.addEventListener(DISCLOSURE_CHANGE_EVENT, handleDisclosureChange)\n return () => {\n document.removeEventListener(DISCLOSURE_CHANGE_EVENT, handleDisclosureChange)\n }\n }, [id])\n\n const safeSetExpanded: Setter = useCallback((value) => {\n // DisclosureTrigger と DisclosureContent のレンダリング順序に影響しないように animation frame を待ってから state を更新する\n requestAnimationFrame(() => {\n setExpanded(value)\n })\n }, [])\n\n return [expanded, safeSetExpanded]\n}\n"],"names":["useState","useEffect","useCallback"],"mappings":";;;;AAEA,MAAM,uBAAuB,GAAG,8BAA8B;AAc9D;;AAEG;AACI,MAAM,aAAa,GAAG,CAAC,EAAU,KAAyB;IAC/D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAGA,cAAQ,CAAC,KAAK,CAAC;IAE/CC,eAAS,CAAC,MAAK;AACb,QAAA,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAA8B,uBAAuB,EAAE;AACpE,YAAA,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;AACzB,SAAA,CAAC,CACH;AACH,IAAA,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAElBA,eAAS,CAAC,MAAK;AACb,QAAA,MAAM,sBAAsB,GAAG,CAAC,CAA2C,KAAI;YAC7E,IAAI,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE;AACtB,gBAAA,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;YAChC;AACF,QAAA,CAAC;AAED,QAAA,QAAQ,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,sBAAsB,CAAC;AAC1E,QAAA,OAAO,MAAK;AACV,YAAA,QAAQ,CAAC,mBAAmB,CAAC,uBAAuB,EAAE,sBAAsB,CAAC;AAC/E,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAER,IAAA,MAAM,eAAe,GAAWC,iBAAW,CAAC,CAAC,KAAK,KAAI;;QAEpD,qBAAqB,CAAC,MAAK;YACzB,WAAW,CAAC,KAAK,CAAC;AACpB,QAAA,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,OAAO,CAAC,QAAQ,EAAE,eAAe,CAAC;AACpC;;;;"}
@@ -11,29 +11,23 @@ const useDisclosure = (id) => {
11
11
  detail: { id, expanded },
12
12
  }));
13
13
  }, [expanded, id]);
14
- const handleDisclosureChange = useCallback((e) => {
15
- if (id === e.detail.id) {
16
- setExpanded(e.detail.expanded);
17
- }
18
- }, [id]);
19
14
  useEffect(() => {
15
+ const handleDisclosureChange = (e) => {
16
+ if (id === e.detail.id) {
17
+ setExpanded(e.detail.expanded);
18
+ }
19
+ };
20
20
  document.addEventListener(DISCLOSURE_CHANGE_EVENT, handleDisclosureChange);
21
21
  return () => {
22
22
  document.removeEventListener(DISCLOSURE_CHANGE_EVENT, handleDisclosureChange);
23
23
  };
24
- }, [id, handleDisclosureChange]);
24
+ }, [id]);
25
25
  const safeSetExpanded = useCallback((value) => {
26
26
  // DisclosureTrigger と DisclosureContent のレンダリング順序に影響しないように animation frame を待ってから state を更新する
27
27
  requestAnimationFrame(() => {
28
- if (typeof value === 'function') {
29
- const newValue = value(expanded);
30
- setExpanded(newValue);
31
- }
32
- else {
33
- setExpanded(value);
34
- }
28
+ setExpanded(value);
35
29
  });
36
- }, [expanded]);
30
+ }, []);
37
31
  return [expanded, safeSetExpanded];
38
32
  };
39
33
 
@@ -1 +1 @@
1
- {"version":3,"file":"useDisclosure.js","sources":["../../../src/components/Disclosure/useDisclosure.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\n\nconst DISCLOSURE_CHANGE_EVENT = 'smarthr-ui:disclosure-change'\ntype DisclosureChangeEventDetail = { id: string; expanded: boolean }\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface DocumentEventMap {\n [DISCLOSURE_CHANGE_EVENT]: CustomEvent<DisclosureChangeEventDetail>\n }\n}\n\ntype Setter = (value: boolean | ((prev: boolean) => boolean)) => void\n\ntype UseDisclosureResult = [expanded: boolean, setExpanded: Setter]\n\n/**\n * 同じ `id` で呼ぶとイベント経由で状態が同期される custom hook\n */\nexport const useDisclosure = (id: string): UseDisclosureResult => {\n const [expanded, setExpanded] = useState(false)\n\n useEffect(() => {\n document.dispatchEvent(\n new CustomEvent<DisclosureChangeEventDetail>(DISCLOSURE_CHANGE_EVENT, {\n detail: { id, expanded },\n }),\n )\n }, [expanded, id])\n\n const handleDisclosureChange = useCallback(\n (e: CustomEvent<DisclosureChangeEventDetail>) => {\n if (id === e.detail.id) {\n setExpanded(e.detail.expanded)\n }\n },\n [id],\n )\n\n useEffect(() => {\n document.addEventListener(DISCLOSURE_CHANGE_EVENT, handleDisclosureChange)\n return () => {\n document.removeEventListener(DISCLOSURE_CHANGE_EVENT, handleDisclosureChange)\n }\n }, [id, handleDisclosureChange])\n\n const safeSetExpanded: Setter = useCallback(\n (value) => {\n // DisclosureTrigger と DisclosureContent のレンダリング順序に影響しないように animation frame を待ってから state を更新する\n requestAnimationFrame(() => {\n if (typeof value === 'function') {\n const newValue = value(expanded)\n setExpanded(newValue)\n } else {\n setExpanded(value)\n }\n })\n },\n [expanded],\n )\n\n return [expanded, safeSetExpanded]\n}\n"],"names":[],"mappings":";;AAEA,MAAM,uBAAuB,GAAG,8BAA8B;AAc9D;;AAEG;AACI,MAAM,aAAa,GAAG,CAAC,EAAU,KAAyB;IAC/D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IAE/C,SAAS,CAAC,MAAK;AACb,QAAA,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAA8B,uBAAuB,EAAE;AACpE,YAAA,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;AACzB,SAAA,CAAC,CACH;AACH,IAAA,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAElB,IAAA,MAAM,sBAAsB,GAAG,WAAW,CACxC,CAAC,CAA2C,KAAI;QAC9C,IAAI,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE;AACtB,YAAA,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;QAChC;AACF,IAAA,CAAC,EACD,CAAC,EAAE,CAAC,CACL;IAED,SAAS,CAAC,MAAK;AACb,QAAA,QAAQ,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,sBAAsB,CAAC;AAC1E,QAAA,OAAO,MAAK;AACV,YAAA,QAAQ,CAAC,mBAAmB,CAAC,uBAAuB,EAAE,sBAAsB,CAAC;AAC/E,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,EAAE,EAAE,sBAAsB,CAAC,CAAC;AAEhC,IAAA,MAAM,eAAe,GAAW,WAAW,CACzC,CAAC,KAAK,KAAI;;QAER,qBAAqB,CAAC,MAAK;AACzB,YAAA,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE;AAC/B,gBAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;gBAChC,WAAW,CAAC,QAAQ,CAAC;YACvB;iBAAO;gBACL,WAAW,CAAC,KAAK,CAAC;YACpB;AACF,QAAA,CAAC,CAAC;AACJ,IAAA,CAAC,EACD,CAAC,QAAQ,CAAC,CACX;AAED,IAAA,OAAO,CAAC,QAAQ,EAAE,eAAe,CAAC;AACpC;;;;"}
1
+ {"version":3,"file":"useDisclosure.js","sources":["../../../src/components/Disclosure/useDisclosure.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react'\n\nconst DISCLOSURE_CHANGE_EVENT = 'smarthr-ui:disclosure-change'\ntype DisclosureChangeEventDetail = { id: string; expanded: boolean }\n\ndeclare global {\n // eslint-disable-next-line @typescript-eslint/consistent-type-definitions\n interface DocumentEventMap {\n [DISCLOSURE_CHANGE_EVENT]: CustomEvent<DisclosureChangeEventDetail>\n }\n}\n\ntype Setter = (value: boolean | ((prev: boolean) => boolean)) => void\n\ntype UseDisclosureResult = [expanded: boolean, setExpanded: Setter]\n\n/**\n * 同じ `id` で呼ぶとイベント経由で状態が同期される custom hook\n */\nexport const useDisclosure = (id: string): UseDisclosureResult => {\n const [expanded, setExpanded] = useState(false)\n\n useEffect(() => {\n document.dispatchEvent(\n new CustomEvent<DisclosureChangeEventDetail>(DISCLOSURE_CHANGE_EVENT, {\n detail: { id, expanded },\n }),\n )\n }, [expanded, id])\n\n useEffect(() => {\n const handleDisclosureChange = (e: CustomEvent<DisclosureChangeEventDetail>) => {\n if (id === e.detail.id) {\n setExpanded(e.detail.expanded)\n }\n }\n\n document.addEventListener(DISCLOSURE_CHANGE_EVENT, handleDisclosureChange)\n return () => {\n document.removeEventListener(DISCLOSURE_CHANGE_EVENT, handleDisclosureChange)\n }\n }, [id])\n\n const safeSetExpanded: Setter = useCallback((value) => {\n // DisclosureTrigger と DisclosureContent のレンダリング順序に影響しないように animation frame を待ってから state を更新する\n requestAnimationFrame(() => {\n setExpanded(value)\n })\n }, [])\n\n return [expanded, safeSetExpanded]\n}\n"],"names":[],"mappings":";;AAEA,MAAM,uBAAuB,GAAG,8BAA8B;AAc9D;;AAEG;AACI,MAAM,aAAa,GAAG,CAAC,EAAU,KAAyB;IAC/D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IAE/C,SAAS,CAAC,MAAK;AACb,QAAA,QAAQ,CAAC,aAAa,CACpB,IAAI,WAAW,CAA8B,uBAAuB,EAAE;AACpE,YAAA,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE;AACzB,SAAA,CAAC,CACH;AACH,IAAA,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAElB,SAAS,CAAC,MAAK;AACb,QAAA,MAAM,sBAAsB,GAAG,CAAC,CAA2C,KAAI;YAC7E,IAAI,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE;AACtB,gBAAA,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;YAChC;AACF,QAAA,CAAC;AAED,QAAA,QAAQ,CAAC,gBAAgB,CAAC,uBAAuB,EAAE,sBAAsB,CAAC;AAC1E,QAAA,OAAO,MAAK;AACV,YAAA,QAAQ,CAAC,mBAAmB,CAAC,uBAAuB,EAAE,sBAAsB,CAAC;AAC/E,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAER,IAAA,MAAM,eAAe,GAAW,WAAW,CAAC,CAAC,KAAK,KAAI;;QAEpD,qBAAqB,CAAC,MAAK;YACzB,WAAW,CAAC,KAAK,CAAC;AACpB,QAAA,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,OAAO,CAAC,QAAQ,EAAE,eAAe,CAAC;AACpC;;;;"}
@@ -6,7 +6,7 @@ var React = require('react');
6
6
  var index = require('./../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.17_@types_node@20.19.35_typescript@5.9.3__/vendor/tailwind-variants/dist/index.cjs');
7
7
  require('../../intl/IntlProvider.cjs');
8
8
  var intl_useIntl = require('../../intl/useIntl.cjs');
9
- require('react-intl');
9
+ require('../../intl/Localizer.cjs');
10
10
  require('../../_virtual/dayjs.min.cjs');
11
11
  require('../../intl/TimeFormatter.cjs');
12
12
  var components_Button_Button = require('../Button/Button.cjs');
@@ -4,7 +4,7 @@ import { forwardRef, useRef, useState, useMemo, useImperativeHandle, useCallback
4
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.17_@types_node@20.19.35_typescript@5.9.3__/vendor/tailwind-variants/dist/index.js';
5
5
  import '../../intl/IntlProvider.js';
6
6
  import { useIntl } from '../../intl/useIntl.js';
7
- import 'react-intl';
7
+ import '../../intl/Localizer.js';
8
8
  import '../../_virtual/dayjs.min.js';
9
9
  import '../../intl/TimeFormatter.js';
10
10
  import { Button } from '../Button/Button.js';
@@ -28,45 +28,27 @@ const Dropdown = ({ onOpen, onClose, children }) => {
28
28
  const { createPortal, portalRoot, isPortalRootMounted, isChildPortal, PortalParentProvider } = hooks_usePortal.usePortal();
29
29
  const triggerElementRef = React.useRef(null);
30
30
  const contentId = React.useId();
31
- if (portalRoot) {
32
- portalRoot.setAttribute('id', contentId);
33
- }
34
- React.useEffect(() => {
35
- const onClickBody = (e) => {
36
- // ignore events from events within DropdownTrigger and DropdownContent
37
- if (!components_Dropdown_dropdownHelper.isEventFromChild(e, triggerElementRef.current) && !isChildPortal(e.target)) {
38
- setActive(false);
39
- }
40
- };
41
- document.body.addEventListener('click', onClickBody, false);
42
- return () => {
43
- document.body.removeEventListener('click', onClickBody, false);
44
- };
45
- }, [isChildPortal, portalRoot]);
31
+ const unstableRef = React.useRef({
32
+ active,
33
+ isPortalRootMounted,
34
+ onOpen,
35
+ onClose,
36
+ createPortal,
37
+ });
38
+ unstableRef.current = {
39
+ active,
40
+ isPortalRootMounted,
41
+ onOpen,
42
+ onClose,
43
+ createPortal,
44
+ };
46
45
  // This is the root container of a dropdown content located in outside the DOM tree
47
46
  const DropdownContentRoot = React.useMemo(() => {
48
- const result = (props) => active ? createPortal(props.children) : null;
47
+ const result = (props) => unstableRef.current.active ? unstableRef.current.createPortal(props.children) : null;
49
48
  // set the displayName explicit for DevTools
50
49
  result.displayName = 'DropdownContentRoot';
51
50
  return result;
52
- }, [active, createPortal]);
53
- const togglerRef = React.useRef({
54
- isPortalRootMounted,
55
- onOpen,
56
- onClose,
57
- });
58
- React.useEffect(() => {
59
- togglerRef.current = {
60
- isPortalRootMounted,
61
- onOpen,
62
- onClose,
63
- };
64
- }, [isPortalRootMounted, onOpen, onClose]);
65
- React.useEffect(() => {
66
- if (togglerRef.current.isPortalRootMounted()) {
67
- togglerRef.current[active ? 'onOpen' : 'onClose']?.();
68
- }
69
- }, [active]);
51
+ }, []);
70
52
  const memoizedOnClickTrigger = React.useCallback((rect) => {
71
53
  setActive((current) => {
72
54
  const newActive = !current;
@@ -81,6 +63,26 @@ const Dropdown = ({ onOpen, onClose, children }) => {
81
63
  // return focus to the Trigger
82
64
  components_Dropdown_dropdownHelper.getFirstTabbable(triggerElementRef)?.focus();
83
65
  }, []);
66
+ React.useEffect(() => {
67
+ if (portalRoot) {
68
+ portalRoot.setAttribute('id', contentId);
69
+ }
70
+ const onClickBody = (e) => {
71
+ // ignore events from events within DropdownTrigger and DropdownContent
72
+ if (!components_Dropdown_dropdownHelper.isEventFromChild(e, triggerElementRef.current) && !isChildPortal(e.target)) {
73
+ setActive(false);
74
+ }
75
+ };
76
+ document.body.addEventListener('click', onClickBody, false);
77
+ return () => {
78
+ document.body.removeEventListener('click', onClickBody, false);
79
+ };
80
+ }, [isChildPortal, portalRoot, contentId]);
81
+ React.useEffect(() => {
82
+ if (unstableRef.current.isPortalRootMounted()) {
83
+ unstableRef.current[active ? 'onOpen' : 'onClose']?.();
84
+ }
85
+ }, [active]);
84
86
  return (jsxRuntime.jsx(PortalParentProvider, { children: jsxRuntime.jsx(DropdownContext.Provider, { value: {
85
87
  active,
86
88
  triggerRect,
@@ -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 useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\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 memoizedOnClickTrigger: (rect: Rect) => void\n onClickCloser: () => 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 memoizedOnClickTrigger: () => {\n /* noop */\n },\n onClickCloser: () => {\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 const { createPortal, portalRoot, isPortalRootMounted, isChildPortal, PortalParentProvider } =\n usePortal()\n\n const triggerElementRef = useRef<HTMLDivElement>(null)\n const contentId = useId()\n\n if (portalRoot) {\n portalRoot.setAttribute('id', contentId)\n }\n\n useEffect(() => {\n const onClickBody = (e: any) => {\n // ignore events from events within DropdownTrigger and DropdownContent\n if (!isEventFromChild(e, triggerElementRef.current) && !isChildPortal(e.target)) {\n setActive(false)\n }\n }\n\n document.body.addEventListener('click', onClickBody, false)\n\n return () => {\n document.body.removeEventListener('click', onClickBody, false)\n }\n }, [isChildPortal, portalRoot])\n\n // This is the root container of a dropdown content located in outside the DOM tree\n const DropdownContentRoot = useMemo<FC<{ children: ReactNode }>>(() => {\n const result: FC<{ children: ReactNode }> = (props) =>\n active ? createPortal(props.children) : null\n\n // set the displayName explicit for DevTools\n result.displayName = 'DropdownContentRoot'\n\n return result\n }, [active, createPortal])\n\n const togglerRef = useRef({\n isPortalRootMounted,\n onOpen,\n onClose,\n })\n useEffect(() => {\n togglerRef.current = {\n isPortalRootMounted,\n onOpen,\n onClose,\n }\n }, [isPortalRootMounted, onOpen, onClose])\n\n useEffect(() => {\n if (togglerRef.current.isPortalRootMounted()) {\n togglerRef.current[active ? 'onOpen' : 'onClose']?.()\n }\n }, [active])\n\n const memoizedOnClickTrigger = useCallback((rect: Rect) => {\n setActive((current) => {\n const newActive = !current\n\n if (newActive) {\n setTriggerRect(rect)\n }\n\n return newActive\n })\n }, [])\n\n const onClickCloser = useCallback(() => {\n setActive(false)\n\n // return focus to the Trigger\n getFirstTabbable(triggerElementRef)?.focus()\n }, [])\n\n return (\n <PortalParentProvider>\n <DropdownContext.Provider\n value={{\n active,\n triggerRect,\n triggerElementRef,\n rootTriggerRef: rootTriggerRef || triggerElementRef || null,\n memoizedOnClickTrigger,\n onClickCloser,\n 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;;;;AAKL;AAGA;AACA;;AAGE;;;AAIA;;AAEE;;;AAGF;;AAIA;;AAEA;AACF;;AAGA;;;AAKE;AAEA;AACF;;;;;AAMC;;;;;;;;;AAUC;AACE;;AAEJ;AAEA;AACE;AACE;;;;AAMA;AACF;;AAGF;;;AAIE;;;;;;AAUM;;;;;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 useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\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 memoizedOnClickTrigger: (rect: Rect) => void\n onClickCloser: () => 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 memoizedOnClickTrigger: () => {\n /* noop */\n },\n onClickCloser: () => {\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 const { createPortal, portalRoot, isPortalRootMounted, isChildPortal, PortalParentProvider } =\n usePortal()\n\n const triggerElementRef = useRef<HTMLDivElement>(null)\n const contentId = useId()\n\n const unstableRef = useRef({\n active,\n isPortalRootMounted,\n onOpen,\n onClose,\n createPortal,\n })\n unstableRef.current = {\n active,\n isPortalRootMounted,\n onOpen,\n onClose,\n createPortal,\n }\n\n // This is the root container of a dropdown content located in outside the DOM tree\n const DropdownContentRoot = useMemo<FC<{ children: ReactNode }>>(() => {\n const result: FC<{ children: ReactNode }> = (props) =>\n unstableRef.current.active ? unstableRef.current.createPortal(props.children) : null\n\n // set the displayName explicit for DevTools\n result.displayName = 'DropdownContentRoot'\n\n return result\n }, [])\n\n const memoizedOnClickTrigger = useCallback((rect: Rect) => {\n setActive((current) => {\n const newActive = !current\n\n if (newActive) {\n setTriggerRect(rect)\n }\n\n return newActive\n })\n }, [])\n\n const onClickCloser = useCallback(() => {\n setActive(false)\n\n // return focus to the Trigger\n getFirstTabbable(triggerElementRef)?.focus()\n }, [])\n\n useEffect(() => {\n if (portalRoot) {\n portalRoot.setAttribute('id', contentId)\n }\n\n const onClickBody = (e: any) => {\n // ignore events from events within DropdownTrigger and DropdownContent\n if (!isEventFromChild(e, triggerElementRef.current) && !isChildPortal(e.target)) {\n setActive(false)\n }\n }\n\n document.body.addEventListener('click', onClickBody, false)\n\n return () => {\n document.body.removeEventListener('click', onClickBody, false)\n }\n }, [isChildPortal, portalRoot, contentId])\n\n useEffect(() => {\n if (unstableRef.current.isPortalRootMounted()) {\n unstableRef.current[active ? 'onOpen' : 'onClose']?.()\n }\n }, [active])\n\n return (\n <PortalParentProvider>\n <DropdownContext.Provider\n value={{\n active,\n triggerRect,\n triggerElementRef,\n rootTriggerRef: rootTriggerRef || triggerElementRef || null,\n memoizedOnClickTrigger,\n onClickCloser,\n 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;;;;AAKL;AAGA;AACA;;;;;;;AAQC;;;;;;;;;AAUD;AACE;;AAIA;AAEA;;AAGF;AACE;AACE;;;;AAMA;AACF;;AAGF;;;AAIE;;;;AAKE;;AAGF;;AAEE;;;AAGF;;AAIA;;AAEA;;;AAIA;AACE;;AAEJ;;;;;AASQ;;;;;AAKD;AAMT;;;"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { jsx } from 'react/jsx-runtime';
3
- import { createContext, createRef, useState, useContext, useRef, useId, useEffect, useMemo, useCallback } from 'react';
3
+ import { createContext, createRef, useState, useContext, useRef, useId, useMemo, useCallback, useEffect } from 'react';
4
4
  import { usePortal } from '../../hooks/usePortal.js';
5
5
  import { getFirstTabbable, isEventFromChild } from './dropdownHelper.js';
6
6
 
@@ -26,45 +26,27 @@ const Dropdown = ({ onOpen, onClose, children }) => {
26
26
  const { createPortal, portalRoot, isPortalRootMounted, isChildPortal, PortalParentProvider } = usePortal();
27
27
  const triggerElementRef = useRef(null);
28
28
  const contentId = useId();
29
- if (portalRoot) {
30
- portalRoot.setAttribute('id', contentId);
31
- }
32
- useEffect(() => {
33
- const onClickBody = (e) => {
34
- // ignore events from events within DropdownTrigger and DropdownContent
35
- if (!isEventFromChild(e, triggerElementRef.current) && !isChildPortal(e.target)) {
36
- setActive(false);
37
- }
38
- };
39
- document.body.addEventListener('click', onClickBody, false);
40
- return () => {
41
- document.body.removeEventListener('click', onClickBody, false);
42
- };
43
- }, [isChildPortal, portalRoot]);
29
+ const unstableRef = useRef({
30
+ active,
31
+ isPortalRootMounted,
32
+ onOpen,
33
+ onClose,
34
+ createPortal,
35
+ });
36
+ unstableRef.current = {
37
+ active,
38
+ isPortalRootMounted,
39
+ onOpen,
40
+ onClose,
41
+ createPortal,
42
+ };
44
43
  // This is the root container of a dropdown content located in outside the DOM tree
45
44
  const DropdownContentRoot = useMemo(() => {
46
- const result = (props) => active ? createPortal(props.children) : null;
45
+ const result = (props) => unstableRef.current.active ? unstableRef.current.createPortal(props.children) : null;
47
46
  // set the displayName explicit for DevTools
48
47
  result.displayName = 'DropdownContentRoot';
49
48
  return result;
50
- }, [active, createPortal]);
51
- const togglerRef = useRef({
52
- isPortalRootMounted,
53
- onOpen,
54
- onClose,
55
- });
56
- useEffect(() => {
57
- togglerRef.current = {
58
- isPortalRootMounted,
59
- onOpen,
60
- onClose,
61
- };
62
- }, [isPortalRootMounted, onOpen, onClose]);
63
- useEffect(() => {
64
- if (togglerRef.current.isPortalRootMounted()) {
65
- togglerRef.current[active ? 'onOpen' : 'onClose']?.();
66
- }
67
- }, [active]);
49
+ }, []);
68
50
  const memoizedOnClickTrigger = useCallback((rect) => {
69
51
  setActive((current) => {
70
52
  const newActive = !current;
@@ -79,6 +61,26 @@ const Dropdown = ({ onOpen, onClose, children }) => {
79
61
  // return focus to the Trigger
80
62
  getFirstTabbable(triggerElementRef)?.focus();
81
63
  }, []);
64
+ useEffect(() => {
65
+ if (portalRoot) {
66
+ portalRoot.setAttribute('id', contentId);
67
+ }
68
+ const onClickBody = (e) => {
69
+ // ignore events from events within DropdownTrigger and DropdownContent
70
+ if (!isEventFromChild(e, triggerElementRef.current) && !isChildPortal(e.target)) {
71
+ setActive(false);
72
+ }
73
+ };
74
+ document.body.addEventListener('click', onClickBody, false);
75
+ return () => {
76
+ document.body.removeEventListener('click', onClickBody, false);
77
+ };
78
+ }, [isChildPortal, portalRoot, contentId]);
79
+ useEffect(() => {
80
+ if (unstableRef.current.isPortalRootMounted()) {
81
+ unstableRef.current[active ? 'onOpen' : 'onClose']?.();
82
+ }
83
+ }, [active]);
82
84
  return (jsx(PortalParentProvider, { children: jsx(DropdownContext.Provider, { value: {
83
85
  active,
84
86
  triggerRect,
@@ -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 useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\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 memoizedOnClickTrigger: (rect: Rect) => void\n onClickCloser: () => 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 memoizedOnClickTrigger: () => {\n /* noop */\n },\n onClickCloser: () => {\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 const { createPortal, portalRoot, isPortalRootMounted, isChildPortal, PortalParentProvider } =\n usePortal()\n\n const triggerElementRef = useRef<HTMLDivElement>(null)\n const contentId = useId()\n\n if (portalRoot) {\n portalRoot.setAttribute('id', contentId)\n }\n\n useEffect(() => {\n const onClickBody = (e: any) => {\n // ignore events from events within DropdownTrigger and DropdownContent\n if (!isEventFromChild(e, triggerElementRef.current) && !isChildPortal(e.target)) {\n setActive(false)\n }\n }\n\n document.body.addEventListener('click', onClickBody, false)\n\n return () => {\n document.body.removeEventListener('click', onClickBody, false)\n }\n }, [isChildPortal, portalRoot])\n\n // This is the root container of a dropdown content located in outside the DOM tree\n const DropdownContentRoot = useMemo<FC<{ children: ReactNode }>>(() => {\n const result: FC<{ children: ReactNode }> = (props) =>\n active ? createPortal(props.children) : null\n\n // set the displayName explicit for DevTools\n result.displayName = 'DropdownContentRoot'\n\n return result\n }, [active, createPortal])\n\n const togglerRef = useRef({\n isPortalRootMounted,\n onOpen,\n onClose,\n })\n useEffect(() => {\n togglerRef.current = {\n isPortalRootMounted,\n onOpen,\n onClose,\n }\n }, [isPortalRootMounted, onOpen, onClose])\n\n useEffect(() => {\n if (togglerRef.current.isPortalRootMounted()) {\n togglerRef.current[active ? 'onOpen' : 'onClose']?.()\n }\n }, [active])\n\n const memoizedOnClickTrigger = useCallback((rect: Rect) => {\n setActive((current) => {\n const newActive = !current\n\n if (newActive) {\n setTriggerRect(rect)\n }\n\n return newActive\n })\n }, [])\n\n const onClickCloser = useCallback(() => {\n setActive(false)\n\n // return focus to the Trigger\n getFirstTabbable(triggerElementRef)?.focus()\n }, [])\n\n return (\n <PortalParentProvider>\n <DropdownContext.Provider\n value={{\n active,\n triggerRect,\n triggerElementRef,\n rootTriggerRef: rootTriggerRef || triggerElementRef || null,\n memoizedOnClickTrigger,\n onClickCloser,\n 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;;;;AAKL;AAGA;AACA;;AAGE;;;AAIA;;AAEE;;;AAGF;;AAIA;;AAEA;AACF;;AAGA;;;AAKE;AAEA;AACF;;;;;AAMC;;;;;;;;;AAUC;AACE;;AAEJ;AAEA;AACE;AACE;;;;AAMA;AACF;;AAGF;;;AAIE;;;;;;AAUM;;;;;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 useCallback,\n useContext,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\n\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 memoizedOnClickTrigger: (rect: Rect) => void\n onClickCloser: () => 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 memoizedOnClickTrigger: () => {\n /* noop */\n },\n onClickCloser: () => {\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 const { createPortal, portalRoot, isPortalRootMounted, isChildPortal, PortalParentProvider } =\n usePortal()\n\n const triggerElementRef = useRef<HTMLDivElement>(null)\n const contentId = useId()\n\n const unstableRef = useRef({\n active,\n isPortalRootMounted,\n onOpen,\n onClose,\n createPortal,\n })\n unstableRef.current = {\n active,\n isPortalRootMounted,\n onOpen,\n onClose,\n createPortal,\n }\n\n // This is the root container of a dropdown content located in outside the DOM tree\n const DropdownContentRoot = useMemo<FC<{ children: ReactNode }>>(() => {\n const result: FC<{ children: ReactNode }> = (props) =>\n unstableRef.current.active ? unstableRef.current.createPortal(props.children) : null\n\n // set the displayName explicit for DevTools\n result.displayName = 'DropdownContentRoot'\n\n return result\n }, [])\n\n const memoizedOnClickTrigger = useCallback((rect: Rect) => {\n setActive((current) => {\n const newActive = !current\n\n if (newActive) {\n setTriggerRect(rect)\n }\n\n return newActive\n })\n }, [])\n\n const onClickCloser = useCallback(() => {\n setActive(false)\n\n // return focus to the Trigger\n getFirstTabbable(triggerElementRef)?.focus()\n }, [])\n\n useEffect(() => {\n if (portalRoot) {\n portalRoot.setAttribute('id', contentId)\n }\n\n const onClickBody = (e: any) => {\n // ignore events from events within DropdownTrigger and DropdownContent\n if (!isEventFromChild(e, triggerElementRef.current) && !isChildPortal(e.target)) {\n setActive(false)\n }\n }\n\n document.body.addEventListener('click', onClickBody, false)\n\n return () => {\n document.body.removeEventListener('click', onClickBody, false)\n }\n }, [isChildPortal, portalRoot, contentId])\n\n useEffect(() => {\n if (unstableRef.current.isPortalRootMounted()) {\n unstableRef.current[active ? 'onOpen' : 'onClose']?.()\n }\n }, [active])\n\n return (\n <PortalParentProvider>\n <DropdownContext.Provider\n value={{\n active,\n triggerRect,\n triggerElementRef,\n rootTriggerRef: rootTriggerRef || triggerElementRef || null,\n memoizedOnClickTrigger,\n onClickCloser,\n 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;;;;AAKL;AAGA;AACA;;;;;;;AAQC;;;;;;;;;AAUD;AACE;;AAIA;AAEA;;AAGF;AACE;AACE;;;;AAMA;AACF;;AAGF;;;AAIE;;;;AAKE;;AAGF;;AAEE;;;AAGF;;AAIA;;AAEA;;;AAIA;AACE;;AAEJ;;;;;AASQ;;;;;AAKD;AAMT;;"}
@@ -3,12 +3,11 @@
3
3
 
4
4
  var jsxRuntime = require('react/jsx-runtime');
5
5
  var React = require('react');
6
- var index$1 = require('../../../_virtual/index3.cjs');
7
6
  var index = require('./../../../vendor/.pnpm/tailwind-variants@0.3.1_tailwindcss@3.4.19_ts-node@10.9.2_@swc_core@1.15.17_@types_node@20.19.35_typescript@5.9.3__/vendor/tailwind-variants/dist/index.cjs');
8
7
  var hooks_useObjectAttributes = require('../../../hooks/useObjectAttributes.cjs');
9
8
  require('../../../intl/IntlProvider.cjs');
10
9
  var intl_useIntl = require('../../../intl/useIntl.cjs');
11
- require('react-intl');
10
+ require('../../../intl/Localizer.cjs');
12
11
  require('../../../_virtual/dayjs.min.cjs');
13
12
  require('../../../intl/TimeFormatter.cjs');
14
13
  var components_Button_Button = require('../../Button/Button.cjs');
@@ -78,7 +77,7 @@ const TriggerLabelText = React.memo(({ children, onlyIconTrigger }) => {
78
77
  return children;
79
78
  }
80
79
  const Icon = (typeof onlyIconTrigger === 'object' && onlyIconTrigger.component) || components_Icon_FaIcon.FaEllipsisIcon;
81
- return jsxRuntime.jsx(Icon, { alt: typeof children === 'string' ? children : index$1(children) });
80
+ return jsxRuntime.jsx(Icon, { alt: children });
82
81
  });
83
82
  const renderButtonList = (children) => React.Children.map(children, (item) => {
84
83
  if (!item || !React.isValidElement(item)) {
@@ -111,6 +110,9 @@ const ButtonListItem = ({ children }) => {
111
110
  observer.observe(listItem, {
112
111
  childList: true,
113
112
  subtree: true,
113
+ // button要素の disabled / aria-disabled が動的に変化した場合も検知してリスナーを貼り直す
114
+ attributes: true,
115
+ attributeFilter: ['disabled', 'aria-disabled'],
114
116
  });
115
117
  return () => {
116
118
  observer.disconnect();
@@ -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 innerText from 'react-innertext'\nimport { tv } from 'tailwind-variants'\n\nimport { useObjectAttributes } from '../../../hooks/useObjectAttributes'\nimport { useIntl } from '../../../intl'\nimport { type AnchorButton, Button, type AbstractProps 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 AbstractProps = {\n /** 引き金となるボタン */\n trigger: ReactNode | ObjectTriggerType\n /** 操作群 */\n children: Actions\n /** ドロップダウンメニューが開かれた際のイベント */\n onOpen?: () => void\n /** ドロップダウンメニューが閉じられた際のイベント */\n onClose?: () => void\n}\ntype ElementProps = Omit<ComponentPropsWithRef<'button'>, keyof AbstractProps>\ntype Props = AbstractProps & 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 { localize } = useIntl()\n\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 ? localize({\n id: 'smarthr-ui/DropdownMenuButton/triggerActive',\n defaultText: '候補を閉じる',\n })\n : localize({\n id: 'smarthr-ui/DropdownMenuButton/triggerInactive',\n defaultText: '候補を開く',\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={typeof children === 'string' ? children : innerText(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 })\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":";;;;;;;;;;;;;;;;;;;;;;;;;;AAsEA;AACE;AACD;AAED;AACE;AACE;AACA;AAEA;;;AAGE;;;;;AAKC;AACF;AACD;;;;AAIC;AACF;AACF;AAED;;;AAmBE;;AAIA;AAEI;;;AAGD;AAIH;AAiBF;AAEA;AAWE;;AAIA;;AAaoB;AACA;;;AAGA;AACA;;AAatB;AAEA;;AAKI;;AAGF;;AAGF;AAEO;;AAGD;;AAGF;AACE;;AAEA;AACE;;AAGJ;AACF;AAEF;AACE;;AAGE;;;;;;;AASI;AACA;;AAKJ;AAEA;AAEA;AACA;AACE;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 { useIntl } from '../../../intl'\nimport { type AnchorButton, Button, type AbstractProps 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 AbstractProps = {\n /** 引き金となるボタン */\n trigger: ReactNode | ObjectTriggerType\n /** 操作群 */\n children: Actions\n /** ドロップダウンメニューが開かれた際のイベント */\n onOpen?: () => void\n /** ドロップダウンメニューが閉じられた際のイベント */\n onClose?: () => void\n}\ntype ElementProps = Omit<ComponentPropsWithRef<'button'>, keyof AbstractProps>\ntype Props = AbstractProps & 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 { localize } = useIntl()\n\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 ? localize({\n id: 'smarthr-ui/DropdownMenuButton/triggerActive',\n defaultText: '候補を閉じる',\n })\n : localize({\n id: 'smarthr-ui/DropdownMenuButton/triggerInactive',\n defaultText: '候補を開く',\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;AAWE;;AAIA;;AAaoB;AACA;;;AAGA;AACA;;AAatB;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,12 +1,11 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
3
  import { memo, useContext, useRef, useMemo, Children, isValidElement, Fragment, useEffect } from 'react';
4
- import innerText from '../../../_virtual/index3.js';
5
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.17_@types_node@20.19.35_typescript@5.9.3__/vendor/tailwind-variants/dist/index.js';
6
5
  import { useObjectAttributes } from '../../../hooks/useObjectAttributes.js';
7
6
  import '../../../intl/IntlProvider.js';
8
7
  import { useIntl } from '../../../intl/useIntl.js';
9
- import 'react-intl';
8
+ import '../../../intl/Localizer.js';
10
9
  import '../../../_virtual/dayjs.min.js';
11
10
  import '../../../intl/TimeFormatter.js';
12
11
  import { Button } from '../../Button/Button.js';
@@ -76,7 +75,7 @@ const TriggerLabelText = memo(({ children, onlyIconTrigger }) => {
76
75
  return children;
77
76
  }
78
77
  const Icon = (typeof onlyIconTrigger === 'object' && onlyIconTrigger.component) || FaEllipsisIcon;
79
- return jsx(Icon, { alt: typeof children === 'string' ? children : innerText(children) });
78
+ return jsx(Icon, { alt: children });
80
79
  });
81
80
  const renderButtonList = (children) => Children.map(children, (item) => {
82
81
  if (!item || !isValidElement(item)) {
@@ -109,6 +108,9 @@ const ButtonListItem = ({ children }) => {
109
108
  observer.observe(listItem, {
110
109
  childList: true,
111
110
  subtree: true,
111
+ // button要素の disabled / aria-disabled が動的に変化した場合も検知してリスナーを貼り直す
112
+ attributes: true,
113
+ attributeFilter: ['disabled', 'aria-disabled'],
112
114
  });
113
115
  return () => {
114
116
  observer.disconnect();
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenuButton.js","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 innerText from 'react-innertext'\nimport { tv } from 'tailwind-variants'\n\nimport { useObjectAttributes } from '../../../hooks/useObjectAttributes'\nimport { useIntl } from '../../../intl'\nimport { type AnchorButton, Button, type AbstractProps 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 AbstractProps = {\n /** 引き金となるボタン */\n trigger: ReactNode | ObjectTriggerType\n /** 操作群 */\n children: Actions\n /** ドロップダウンメニューが開かれた際のイベント */\n onOpen?: () => void\n /** ドロップダウンメニューが閉じられた際のイベント */\n onClose?: () => void\n}\ntype ElementProps = Omit<ComponentPropsWithRef<'button'>, keyof AbstractProps>\ntype Props = AbstractProps & 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 { localize } = useIntl()\n\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 ? localize({\n id: 'smarthr-ui/DropdownMenuButton/triggerActive',\n defaultText: '候補を閉じる',\n })\n : localize({\n id: 'smarthr-ui/DropdownMenuButton/triggerInactive',\n defaultText: '候補を開く',\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={typeof children === 'string' ? children : innerText(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 })\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":";;;;;;;;;;;;;;;;;;;;;;;;AAsEA;AACE;AACD;AAED;AACE;AACE;AACA;AAEA;;;AAGE;;;;;AAKC;AACF;AACD;;;;AAIC;AACF;AACF;AAED;;;AAmBE;;AAIA;AAEI;;;AAGD;AAIH;AAiBF;AAEA;AAWE;;AAIA;;AAaoB;AACA;;;AAGA;AACA;;AAatB;AAEA;;AAKI;;AAGF;;AAGF;AAEO;;AAGD;;AAGF;AACE;;AAEA;AACE;;AAGJ;AACF;AAEF;AACE;;AAGE;;;;;;;AASI;AACA;;AAKJ;AAEA;AAEA;AACA;AACE;AACA;AACD;AAED;;AAEA;;AAGF;AAKF;;"}
1
+ {"version":3,"file":"DropdownMenuButton.js","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 { useIntl } from '../../../intl'\nimport { type AnchorButton, Button, type AbstractProps 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 AbstractProps = {\n /** 引き金となるボタン */\n trigger: ReactNode | ObjectTriggerType\n /** 操作群 */\n children: Actions\n /** ドロップダウンメニューが開かれた際のイベント */\n onOpen?: () => void\n /** ドロップダウンメニューが閉じられた際のイベント */\n onClose?: () => void\n}\ntype ElementProps = Omit<ComponentPropsWithRef<'button'>, keyof AbstractProps>\ntype Props = AbstractProps & 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 { localize } = useIntl()\n\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 ? localize({\n id: 'smarthr-ui/DropdownMenuButton/triggerActive',\n defaultText: '候補を閉じる',\n })\n : localize({\n id: 'smarthr-ui/DropdownMenuButton/triggerInactive',\n defaultText: '候補を開く',\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;AAWE;;AAIA;;AAaoB;AACA;;;AAGA;AACA;;AAatB;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;;"}
@@ -63,6 +63,9 @@ const DropdownTrigger = ({ children, className, tooltip }) => {
63
63
  observer.observe(triggerElement, {
64
64
  childList: true,
65
65
  subtree: true,
66
+ // button要素の disabled / aria-disabled が動的に変化した場合も検知してリスナーを貼り直す
67
+ attributes: true,
68
+ attributeFilter: ['disabled', 'aria-disabled'],
66
69
  });
67
70
  return () => {
68
71
  currentCleanup?.();
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownTrigger.cjs","sources":["../../../src/components/Dropdown/DropdownTrigger.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentProps,\n type FC,\n type PropsWithChildren,\n type ReactNode,\n useContext,\n useEffect,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { tabbable } from '../../libs/tabbable'\nimport { Tooltip } from '../Tooltip'\n\nimport { DropdownContext } from './Dropdown'\n\ntype ConditionalWrapperProps = {\n shouldWrapContent?: boolean\n wrapper: FC<PropsWithChildren>\n}\n\nconst CAPTURE_OPTION = {\n capture: true,\n}\n\n/**\n * 条件付きでラッパをレンダリングする\n */\nconst ConditionalWrapper: FC<PropsWithChildren<ConditionalWrapperProps>> = ({\n shouldWrapContent,\n wrapper,\n children,\n}) => (shouldWrapContent ? wrapper({ children }) : children)\n\ntype Props = PropsWithChildren<ComponentProps<'div'>> & {\n tooltip?: { message: ReactNode; show?: boolean }\n}\n\nconst classNameGenerator = tv({\n base: 'smarthr-ui-Dropdown shr-inline-block',\n})\n\nexport const DropdownTrigger: FC<Props> = ({ children, className, tooltip }) => {\n const { active, memoizedOnClickTrigger, contentId, triggerElementRef } =\n useContext(DropdownContext)\n const actualClassName = useMemo(() => classNameGenerator({ className }), [className])\n\n useEffect(() => {\n if (!triggerElementRef.current) {\n return\n }\n\n // apply ARIA to all focusable elements in trigger\n const triggers = tabbable(triggerElementRef.current, { shouldIgnoreVisibility: true })\n\n triggers.forEach((trigger) => {\n trigger.setAttribute('aria-expanded', active.toString())\n trigger.setAttribute('aria-controls', contentId)\n })\n }, [active, triggerElementRef, contentId])\n\n useEffect(() => {\n const triggerElement = triggerElementRef.current\n if (!triggerElement) {\n return\n }\n\n let currentCleanup: (() => void) | undefined\n\n const setupButton = () => {\n // 既存のクリーンアップを実行\n currentCleanup?.()\n currentCleanup = undefined\n\n const button = triggerElement.querySelector<HTMLButtonElement>('button')\n\n // 引き金となる要素が disabled な場合、処理を差し込む必要がないため、そのまま出力する\n if (!button || button.disabled || button.getAttribute('aria-disabled') === 'true') {\n return\n }\n\n // HINT: Trigger要素自体にonClickが設定されている場合、先にDropdownを開いた状態で処理を行いたい\n // そのためcaptureで開く処理を実行する\n const callback = (e: MouseEvent) => {\n memoizedOnClickTrigger((e.currentTarget! as HTMLButtonElement).getBoundingClientRect())\n }\n\n button.addEventListener('click', callback, CAPTURE_OPTION)\n\n currentCleanup = () => {\n button.removeEventListener('click', callback, CAPTURE_OPTION)\n }\n }\n\n setupButton()\n\n const observer = new MutationObserver(setupButton)\n\n observer.observe(triggerElement, {\n childList: true,\n subtree: true,\n })\n\n return () => {\n currentCleanup?.()\n observer.disconnect()\n }\n }, [memoizedOnClickTrigger, triggerElementRef])\n\n return (\n <div ref={triggerElementRef} className={actualClassName}>\n {/* eslint-disable-next-line smarthr/a11y-scroller-has-tabindex */}\n <ConditionalWrapper\n shouldWrapContent={tooltip?.show}\n wrapper={({ children: currentChildren }) =>\n tooltip?.message ? (\n // eslint-disable-next-line smarthr/a11y-scroller-has-tabindex\n <Tooltip message={tooltip?.message} triggerType=\"icon\" tabIndex={-1}>\n {currentChildren}\n </Tooltip>\n ) : (\n currentChildren\n )\n }\n >\n {children}\n </ConditionalWrapper>\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAuBA;AACE;;AAGF;;AAEG;AACH;AAUA;AACE;AACD;AAEM;AACL;AAEA;;AAGE;;;;AAKA;AAEA;;AAEE;AACF;;;AAIA;;;;AAKA;;;;;;;AAUE;;;;;AAMA;;AAEA;;;;AAMA;AACF;AAEA;AAEA;AAEA;AACE;AACA;AACD;AAED;;;AAGA;AACF;AAEA;;AAQU;AAYZ;;"}
1
+ {"version":3,"file":"DropdownTrigger.cjs","sources":["../../../src/components/Dropdown/DropdownTrigger.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentProps,\n type FC,\n type PropsWithChildren,\n type ReactNode,\n useContext,\n useEffect,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { tabbable } from '../../libs/tabbable'\nimport { Tooltip } from '../Tooltip'\n\nimport { DropdownContext } from './Dropdown'\n\ntype ConditionalWrapperProps = {\n shouldWrapContent?: boolean\n wrapper: FC<PropsWithChildren>\n}\n\nconst CAPTURE_OPTION = {\n capture: true,\n}\n\n/**\n * 条件付きでラッパをレンダリングする\n */\nconst ConditionalWrapper: FC<PropsWithChildren<ConditionalWrapperProps>> = ({\n shouldWrapContent,\n wrapper,\n children,\n}) => (shouldWrapContent ? wrapper({ children }) : children)\n\ntype Props = PropsWithChildren<ComponentProps<'div'>> & {\n tooltip?: { message: ReactNode; show?: boolean }\n}\n\nconst classNameGenerator = tv({\n base: 'smarthr-ui-Dropdown shr-inline-block',\n})\n\nexport const DropdownTrigger: FC<Props> = ({ children, className, tooltip }) => {\n const { active, memoizedOnClickTrigger, contentId, triggerElementRef } =\n useContext(DropdownContext)\n const actualClassName = useMemo(() => classNameGenerator({ className }), [className])\n\n useEffect(() => {\n if (!triggerElementRef.current) {\n return\n }\n\n // apply ARIA to all focusable elements in trigger\n const triggers = tabbable(triggerElementRef.current, { shouldIgnoreVisibility: true })\n\n triggers.forEach((trigger) => {\n trigger.setAttribute('aria-expanded', active.toString())\n trigger.setAttribute('aria-controls', contentId)\n })\n }, [active, triggerElementRef, contentId])\n\n useEffect(() => {\n const triggerElement = triggerElementRef.current\n if (!triggerElement) {\n return\n }\n\n let currentCleanup: (() => void) | undefined\n\n const setupButton = () => {\n // 既存のクリーンアップを実行\n currentCleanup?.()\n currentCleanup = undefined\n\n const button = triggerElement.querySelector<HTMLButtonElement>('button')\n\n // 引き金となる要素が disabled な場合、処理を差し込む必要がないため、そのまま出力する\n if (!button || button.disabled || button.getAttribute('aria-disabled') === 'true') {\n return\n }\n\n // HINT: Trigger要素自体にonClickが設定されている場合、先にDropdownを開いた状態で処理を行いたい\n // そのためcaptureで開く処理を実行する\n const callback = (e: MouseEvent) => {\n memoizedOnClickTrigger((e.currentTarget! as HTMLButtonElement).getBoundingClientRect())\n }\n\n button.addEventListener('click', callback, CAPTURE_OPTION)\n\n currentCleanup = () => {\n button.removeEventListener('click', callback, CAPTURE_OPTION)\n }\n }\n\n setupButton()\n\n const observer = new MutationObserver(setupButton)\n\n observer.observe(triggerElement, {\n childList: true,\n subtree: true,\n // button要素の disabled / aria-disabled が動的に変化した場合も検知してリスナーを貼り直す\n attributes: true,\n attributeFilter: ['disabled', 'aria-disabled'],\n })\n\n return () => {\n currentCleanup?.()\n observer.disconnect()\n }\n }, [memoizedOnClickTrigger, triggerElementRef])\n\n return (\n <div ref={triggerElementRef} className={actualClassName}>\n {/* eslint-disable-next-line smarthr/a11y-scroller-has-tabindex */}\n <ConditionalWrapper\n shouldWrapContent={tooltip?.show}\n wrapper={({ children: currentChildren }) =>\n tooltip?.message ? (\n // eslint-disable-next-line smarthr/a11y-scroller-has-tabindex\n <Tooltip message={tooltip?.message} triggerType=\"icon\" tabIndex={-1}>\n {currentChildren}\n </Tooltip>\n ) : (\n currentChildren\n )\n }\n >\n {children}\n </ConditionalWrapper>\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAuBA;AACE;;AAGF;;AAEG;AACH;AAUA;AACE;AACD;AAEM;AACL;AAEA;;AAGE;;;;AAKA;AAEA;;AAEE;AACF;;;AAIA;;;;AAKA;;;;;;;AAUE;;;;;AAMA;;AAEA;;;;AAMA;AACF;AAEA;AAEA;AAEA;AACE;AACA;;AAEA;AACA;AACD;AAED;;;AAGA;AACF;AAEA;;AAQU;AAYZ;;"}
@@ -61,6 +61,9 @@ const DropdownTrigger = ({ children, className, tooltip }) => {
61
61
  observer.observe(triggerElement, {
62
62
  childList: true,
63
63
  subtree: true,
64
+ // button要素の disabled / aria-disabled が動的に変化した場合も検知してリスナーを貼り直す
65
+ attributes: true,
66
+ attributeFilter: ['disabled', 'aria-disabled'],
64
67
  });
65
68
  return () => {
66
69
  currentCleanup?.();
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownTrigger.js","sources":["../../../src/components/Dropdown/DropdownTrigger.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentProps,\n type FC,\n type PropsWithChildren,\n type ReactNode,\n useContext,\n useEffect,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { tabbable } from '../../libs/tabbable'\nimport { Tooltip } from '../Tooltip'\n\nimport { DropdownContext } from './Dropdown'\n\ntype ConditionalWrapperProps = {\n shouldWrapContent?: boolean\n wrapper: FC<PropsWithChildren>\n}\n\nconst CAPTURE_OPTION = {\n capture: true,\n}\n\n/**\n * 条件付きでラッパをレンダリングする\n */\nconst ConditionalWrapper: FC<PropsWithChildren<ConditionalWrapperProps>> = ({\n shouldWrapContent,\n wrapper,\n children,\n}) => (shouldWrapContent ? wrapper({ children }) : children)\n\ntype Props = PropsWithChildren<ComponentProps<'div'>> & {\n tooltip?: { message: ReactNode; show?: boolean }\n}\n\nconst classNameGenerator = tv({\n base: 'smarthr-ui-Dropdown shr-inline-block',\n})\n\nexport const DropdownTrigger: FC<Props> = ({ children, className, tooltip }) => {\n const { active, memoizedOnClickTrigger, contentId, triggerElementRef } =\n useContext(DropdownContext)\n const actualClassName = useMemo(() => classNameGenerator({ className }), [className])\n\n useEffect(() => {\n if (!triggerElementRef.current) {\n return\n }\n\n // apply ARIA to all focusable elements in trigger\n const triggers = tabbable(triggerElementRef.current, { shouldIgnoreVisibility: true })\n\n triggers.forEach((trigger) => {\n trigger.setAttribute('aria-expanded', active.toString())\n trigger.setAttribute('aria-controls', contentId)\n })\n }, [active, triggerElementRef, contentId])\n\n useEffect(() => {\n const triggerElement = triggerElementRef.current\n if (!triggerElement) {\n return\n }\n\n let currentCleanup: (() => void) | undefined\n\n const setupButton = () => {\n // 既存のクリーンアップを実行\n currentCleanup?.()\n currentCleanup = undefined\n\n const button = triggerElement.querySelector<HTMLButtonElement>('button')\n\n // 引き金となる要素が disabled な場合、処理を差し込む必要がないため、そのまま出力する\n if (!button || button.disabled || button.getAttribute('aria-disabled') === 'true') {\n return\n }\n\n // HINT: Trigger要素自体にonClickが設定されている場合、先にDropdownを開いた状態で処理を行いたい\n // そのためcaptureで開く処理を実行する\n const callback = (e: MouseEvent) => {\n memoizedOnClickTrigger((e.currentTarget! as HTMLButtonElement).getBoundingClientRect())\n }\n\n button.addEventListener('click', callback, CAPTURE_OPTION)\n\n currentCleanup = () => {\n button.removeEventListener('click', callback, CAPTURE_OPTION)\n }\n }\n\n setupButton()\n\n const observer = new MutationObserver(setupButton)\n\n observer.observe(triggerElement, {\n childList: true,\n subtree: true,\n })\n\n return () => {\n currentCleanup?.()\n observer.disconnect()\n }\n }, [memoizedOnClickTrigger, triggerElementRef])\n\n return (\n <div ref={triggerElementRef} className={actualClassName}>\n {/* eslint-disable-next-line smarthr/a11y-scroller-has-tabindex */}\n <ConditionalWrapper\n shouldWrapContent={tooltip?.show}\n wrapper={({ children: currentChildren }) =>\n tooltip?.message ? (\n // eslint-disable-next-line smarthr/a11y-scroller-has-tabindex\n <Tooltip message={tooltip?.message} triggerType=\"icon\" tabIndex={-1}>\n {currentChildren}\n </Tooltip>\n ) : (\n currentChildren\n )\n }\n >\n {children}\n </ConditionalWrapper>\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;AAuBA;AACE;;AAGF;;AAEG;AACH;AAUA;AACE;AACD;AAEM;AACL;AAEA;;AAGE;;;;AAKA;AAEA;;AAEE;AACF;;;AAIA;;;;AAKA;;;;;;;AAUE;;;;;AAMA;;AAEA;;;;AAMA;AACF;AAEA;AAEA;AAEA;AACE;AACA;AACD;AAED;;;AAGA;AACF;AAEA;;AAQU;AAYZ;;"}
1
+ {"version":3,"file":"DropdownTrigger.js","sources":["../../../src/components/Dropdown/DropdownTrigger.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ComponentProps,\n type FC,\n type PropsWithChildren,\n type ReactNode,\n useContext,\n useEffect,\n useMemo,\n} from 'react'\nimport { tv } from 'tailwind-variants'\n\nimport { tabbable } from '../../libs/tabbable'\nimport { Tooltip } from '../Tooltip'\n\nimport { DropdownContext } from './Dropdown'\n\ntype ConditionalWrapperProps = {\n shouldWrapContent?: boolean\n wrapper: FC<PropsWithChildren>\n}\n\nconst CAPTURE_OPTION = {\n capture: true,\n}\n\n/**\n * 条件付きでラッパをレンダリングする\n */\nconst ConditionalWrapper: FC<PropsWithChildren<ConditionalWrapperProps>> = ({\n shouldWrapContent,\n wrapper,\n children,\n}) => (shouldWrapContent ? wrapper({ children }) : children)\n\ntype Props = PropsWithChildren<ComponentProps<'div'>> & {\n tooltip?: { message: ReactNode; show?: boolean }\n}\n\nconst classNameGenerator = tv({\n base: 'smarthr-ui-Dropdown shr-inline-block',\n})\n\nexport const DropdownTrigger: FC<Props> = ({ children, className, tooltip }) => {\n const { active, memoizedOnClickTrigger, contentId, triggerElementRef } =\n useContext(DropdownContext)\n const actualClassName = useMemo(() => classNameGenerator({ className }), [className])\n\n useEffect(() => {\n if (!triggerElementRef.current) {\n return\n }\n\n // apply ARIA to all focusable elements in trigger\n const triggers = tabbable(triggerElementRef.current, { shouldIgnoreVisibility: true })\n\n triggers.forEach((trigger) => {\n trigger.setAttribute('aria-expanded', active.toString())\n trigger.setAttribute('aria-controls', contentId)\n })\n }, [active, triggerElementRef, contentId])\n\n useEffect(() => {\n const triggerElement = triggerElementRef.current\n if (!triggerElement) {\n return\n }\n\n let currentCleanup: (() => void) | undefined\n\n const setupButton = () => {\n // 既存のクリーンアップを実行\n currentCleanup?.()\n currentCleanup = undefined\n\n const button = triggerElement.querySelector<HTMLButtonElement>('button')\n\n // 引き金となる要素が disabled な場合、処理を差し込む必要がないため、そのまま出力する\n if (!button || button.disabled || button.getAttribute('aria-disabled') === 'true') {\n return\n }\n\n // HINT: Trigger要素自体にonClickが設定されている場合、先にDropdownを開いた状態で処理を行いたい\n // そのためcaptureで開く処理を実行する\n const callback = (e: MouseEvent) => {\n memoizedOnClickTrigger((e.currentTarget! as HTMLButtonElement).getBoundingClientRect())\n }\n\n button.addEventListener('click', callback, CAPTURE_OPTION)\n\n currentCleanup = () => {\n button.removeEventListener('click', callback, CAPTURE_OPTION)\n }\n }\n\n setupButton()\n\n const observer = new MutationObserver(setupButton)\n\n observer.observe(triggerElement, {\n childList: true,\n subtree: true,\n // button要素の disabled / aria-disabled が動的に変化した場合も検知してリスナーを貼り直す\n attributes: true,\n attributeFilter: ['disabled', 'aria-disabled'],\n })\n\n return () => {\n currentCleanup?.()\n observer.disconnect()\n }\n }, [memoizedOnClickTrigger, triggerElementRef])\n\n return (\n <div ref={triggerElementRef} className={actualClassName}>\n {/* eslint-disable-next-line smarthr/a11y-scroller-has-tabindex */}\n <ConditionalWrapper\n shouldWrapContent={tooltip?.show}\n wrapper={({ children: currentChildren }) =>\n tooltip?.message ? (\n // eslint-disable-next-line smarthr/a11y-scroller-has-tabindex\n <Tooltip message={tooltip?.message} triggerType=\"icon\" tabIndex={-1}>\n {currentChildren}\n </Tooltip>\n ) : (\n currentChildren\n )\n }\n >\n {children}\n </ConditionalWrapper>\n </div>\n )\n}\n"],"names":[],"mappings":";;;;;;;;;AAuBA;AACE;;AAGF;;AAEG;AACH;AAUA;AACE;AACD;AAEM;AACL;AAEA;;AAGE;;;;AAKA;AAEA;;AAEE;AACF;;;AAIA;;;;AAKA;;;;;;;AAUE;;;;;AAMA;;AAEA;;;;AAMA;AACF;AAEA;AAEA;AAEA;AACE;AACA;;AAEA;AACA;AACD;AAED;;;AAGA;AACF;AAEA;;AAQU;AAYZ;;"}