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":"MultiCombobox.cjs","sources":["../../../../src/components/Combobox/MultiCombobox/MultiCombobox.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n memo,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { useId } from 'react'\nimport innerText from 'react-innertext'\nimport { tv } from 'tailwind-variants'\n\nimport { useOuterClick } from '../../../hooks/useOuterClick'\nimport { useTheme } from '../../../hooks/useTheme'\nimport { useIntl } from '../../../intl'\nimport { genericsForwardRef } from '../../../libs/util'\nimport { FaCaretDownIcon } from '../../Icon'\nimport { Scroller } from '../../Scroller'\nimport { areItemsEqual } from '../helper'\nimport { useFocusControl } from '../useFocusControl'\nimport { useListbox } from '../useListbox'\nimport { useMultiOptions } from '../useOptions'\n\nimport { MultiSelectedItem } from './MultiSelectedItem'\n\nimport type { ComboboxItem, AbstractProps as ComboboxProps } from '../types'\n\ntype AbstractProps<T> = ComboboxProps<T> & {\n /**\n * 選択されているアイテムのリスト\n */\n selectedItems: Array<ComboboxItem<T> & { deletable?: boolean }>\n /**\n * 選択されているアイテムのラベルを省略表示するかどうか\n */\n selectedItemEllipsis?: boolean\n /**\n * テキストボックスの `value` 属性の値。\n * `onChangeInput` と併せて設定することで、テキストボックスの挙動が制御可能になる。\n */\n inputValue?: string\n /**\n * 選択されているアイテムの削除ボタンがクリックされた時に発火するコールバック関数\n */\n onDelete?: (item: ComboboxItem<T>) => void\n /**\n * 選択されているアイテムのリストが変わった時に発火するコールバック関数\n */\n onChangeSelected?: (selectedItems: Array<ComboboxItem<T>>) => void\n /**\n * コンポーネントがフォーカスされたときに発火するコールバック関数\n */\n onFocus?: () => void\n /**\n * コンポーネントからフォーカスが外れた時に発火するコールバック関数\n */\n onBlur?: () => void\n /**\n * アイテムが選択されたときに選択済みかどうかを判定するコールバック関数/\n */\n isItemSelected?: (targetItem: ComboboxItem<T>, selectedItems: Array<ComboboxItem<T>>) => boolean\n /**\n * 検索結果が0件の時に表示するコンテンツ\n */\n noResultText?: ReactNode\n}\ntype Props<T> = AbstractProps<T> &\n Omit<ComponentPropsWithoutRef<'input'>, keyof AbstractProps<unknown>>\n\nconst NOOP = () => undefined\n\nconst preventDefaultWithPressEnter = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n }\n}\n\nconst ESCAPE_KEY_REGEX = /^Esc(ape)?$/\nconst ARROW_LEFT_KEY_REGEX = /^(Arrow)?Left$/\nconst ARROW_RIGHT_KEY_REGEX = /^(Arrow)?Right/\nconst ARROW_UP_AND_DOWN_KEY_REGEX = /^(Arrow)?(Up|Down)$/\n\nconst EMPTY_INPUT_CHANGE_EVENT = {\n currentTarget: { value: '' },\n target: { value: '' },\n} as ChangeEvent<HTMLInputElement>\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-MultiCombobox',\n 'shr-box-border shr-inline-flex shr-min-w-[15em] shr-rounded-m shr-border shr-border-solid shr-px-0.5 shr-py-0.25 shr-align-bottom',\n 'contrast-more:shr-border-high-contrast',\n 'has-[[aria-invalid]]:shr-border-danger',\n ],\n inputArea: 'shr-flex shr-flex-1 shr-flex-wrap shr-gap-0.5',\n selectedList:\n 'smarthr-ui-MultiCombobox-selectedList shr-contents shr-list-none [&_li]:shr-min-w-0',\n inputWrapper: 'shr-flex shr-flex-1 shr-items-center',\n input: [\n 'smarthr-ui-MultiCombobox-input',\n 'shr-w-full shr-min-w-[5em] shr-border-none shr-text-base shr-text-black shr-outline-none shr-outline-0',\n 'disabled:shr-hidden',\n ],\n placeholderEl: 'smarthr-ui-MultiCombobox-placeholder shr-my-0 shr-self-center',\n suffixWrapper: [\n 'shr-relative -shr-me-0.5 shr-ms-0.5 shr-p-0.5',\n 'before:shr-absolute before:shr-inset-x-0 before:shr-inset-y-0.25 before:shr-w-0 before:shr-border-0 before:shr-border-l before:shr-border-solid before:shr-border-default before:shr-content-[\"\"]',\n ],\n suffixIcon: 'shr-block',\n },\n variants: {\n focused: {\n true: {\n wrapper: 'shr-focus-indicator',\n },\n },\n disabled: {\n true: {\n wrapper:\n 'shr-cursor-not-allowed shr-border-default/50 shr-bg-white-darken shr-text-disabled',\n },\n false: {\n wrapper: 'shr-cursor-text shr-bg-white',\n },\n },\n hidden: {\n true: {\n inputWrapper: 'shr-pointer-events-none shr-absolute shr-opacity-0',\n },\n },\n },\n compoundVariants: [\n {\n disabled: false,\n className: {\n wrapper: 'shr-border-default',\n },\n },\n ],\n})\n\nconst ActualMultiCombobox = <T,>(\n {\n items,\n selectedItems,\n name,\n disabled = false,\n required = false,\n error = false,\n creatable = false,\n placeholder = '',\n autoComplete,\n dropdownHelpMessage,\n isLoading,\n selectedItemEllipsis,\n width,\n dropdownWidth = 'auto',\n inputValue: controlledInputValue,\n className,\n onChange,\n onChangeInput,\n onAdd,\n onDelete,\n onSelect,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n isItemSelected,\n noResultText,\n style,\n ...rest\n }: Props<T>,\n ref: Ref<HTMLInputElement>,\n) => {\n const { localize } = useIntl()\n const outerRef = useRef<HTMLDivElement>(null)\n const [isFocused, setIsFocused] = useState(false)\n const [highlighted, setHighlighted] = useState(false)\n const isInputControlled = controlledInputValue !== undefined\n const [uncontrolledInputValue, setUncontrolledInputValue] = useState('')\n const inputValue = isInputControlled ? controlledInputValue : uncontrolledInputValue\n const [isComposing, setIsComposing] = useState(false)\n const { options } = useMultiOptions({\n items,\n selected: selectedItems,\n creatable,\n inputValue,\n isItemSelected,\n })\n const setInputValueIfUncontrolled = isInputControlled ? NOOP : setUncontrolledInputValue\n const actualOnDelete = useMemo(() => {\n const handlers: Array<(item: ComboboxItem<T>) => void> = []\n\n if (onDelete) {\n handlers.push((item: ComboboxItem<T>) => onDelete(item))\n }\n if (onChangeSelected) {\n handlers.push((item: ComboboxItem<T>) =>\n onChangeSelected(selectedItems.filter((selected) => !areItemsEqual(selected, item))),\n )\n }\n\n if (handlers.length === 0) {\n return NOOP\n }\n\n return (item: ComboboxItem<T>) => {\n // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう\n // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする\n requestAnimationFrame(() => {\n handlers.forEach((h) => h(item))\n })\n }\n }, [selectedItems, onChangeSelected, onDelete])\n const actualOnSelect = useCallback(\n (selected: ComboboxItem<T>) => {\n // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう\n // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする\n requestAnimationFrame(() => {\n const matchedSelectedItem = selectedItems.find((item) => areItemsEqual(item, selected))\n\n if (matchedSelectedItem === undefined) {\n onSelect?.(selected)\n onChangeSelected?.(selectedItems.concat(selected))\n\n // 制御コンポーネントの場合に親側でinputValueを更新できるように、選択時にonChangeInputを空文字で発火する\n onChangeInput?.(EMPTY_INPUT_CHANGE_EVENT)\n } else if (matchedSelectedItem.deletable !== false) {\n actualOnDelete(selected)\n }\n })\n },\n [selectedItems, actualOnDelete, onChangeSelected, onSelect, onChangeInput],\n )\n\n const { renderListBox, activeOption, onKeyDownListBox, listBoxId, listBoxRef } = useListbox({\n options,\n dropdownHelpMessage,\n dropdownWidth,\n onAdd,\n onSelect: actualOnSelect,\n isExpanded: isFocused,\n isLoading,\n triggerRef: outerRef,\n noResultText,\n })\n\n const {\n deletionButtonRefs,\n inputRef,\n focusPrevDeletionButton,\n focusNextDeletionButton,\n resetDeletionButtonFocus,\n } = useFocusControl(selectedItems.length)\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(ref, () => inputRef.current)\n\n const focus = useMemo(() => {\n const baseAction = () => {\n setIsFocused(true)\n }\n\n if (onFocus) {\n return () => {\n onFocus()\n baseAction()\n }\n }\n\n return baseAction\n }, [onFocus])\n const blur = useMemo(() => {\n if (!isFocused) {\n return NOOP\n }\n\n const baseAction = () => {\n setIsFocused(false)\n resetDeletionButtonFocus()\n }\n\n if (onBlur) {\n return () => {\n onBlur()\n baseAction()\n }\n }\n\n return baseAction\n }, [isFocused, onBlur, resetDeletionButtonFocus])\n\n const outerClickRef = useMemo(() => [outerRef, listBoxRef], [outerRef, listBoxRef])\n useOuterClick(outerClickRef, blur)\n\n const highlightedRef = useRef(highlighted)\n\n useEffect(() => {\n highlightedRef.current = highlighted\n }, [highlighted])\n\n useEffect(() => {\n if (highlightedRef.current) {\n setHighlighted(false)\n inputRef.current?.select()\n } else {\n setInputValueIfUncontrolled('')\n }\n }, [selectedItems, inputRef, setInputValueIfUncontrolled])\n\n useEffect(() => {\n if (isFocused) {\n inputRef.current?.focus()\n }\n }, [inputRef, isFocused, setInputValueIfUncontrolled, selectedItems])\n\n const onDelegateKeyDown = useMemo(\n () =>\n isComposing\n ? undefined\n : (e: KeyboardEvent<HTMLDivElement>) => {\n if (ESCAPE_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n blur()\n } else if (e.key === 'Tab') {\n if (isFocused) {\n // フォーカスがコンポーネントを抜けるように先に input をフォーカスしておく\n inputRef.current?.focus()\n }\n\n blur()\n } else if (ARROW_LEFT_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n focusPrevDeletionButton()\n } else if (ARROW_RIGHT_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n focusNextDeletionButton()\n } else if (\n e.key === 'Backspace' &&\n !inputValue &&\n selectedItems.length > 0 &&\n selectedItems[selectedItems.length - 1].deletable !== false\n ) {\n e.preventDefault()\n e.stopPropagation()\n\n const lastItem = selectedItems[selectedItems.length - 1]\n\n actualOnDelete(lastItem)\n setHighlighted(true)\n setInputValueIfUncontrolled(innerText(lastItem.label))\n } else {\n e.stopPropagation()\n inputRef.current?.focus()\n resetDeletionButtonFocus()\n }\n\n onKeyDownListBox(e)\n },\n [\n blur,\n focusNextDeletionButton,\n focusPrevDeletionButton,\n onKeyDownListBox,\n inputRef,\n isComposing,\n isFocused,\n resetDeletionButtonFocus,\n actualOnDelete,\n inputValue,\n selectedItems,\n setInputValueIfUncontrolled,\n ],\n )\n\n const onDelegateClick = useMemo(\n () =>\n disabled || isFocused\n ? undefined\n : (e: MouseEvent<HTMLElement>) => {\n if (!(e.target as HTMLElement).closest('.smarthr-ui-MultiCombobox-deleteButton')) {\n focus()\n }\n },\n [isFocused, disabled, focus],\n )\n const actualOnChangeInput = useMemo(() => {\n const handlers = [onChange, onChangeInput].filter((h) => !!h)\n const onSetValue = (e: ChangeEvent<HTMLInputElement>) => {\n setInputValueIfUncontrolled(e.currentTarget.value)\n }\n\n if (handlers.length === 0) {\n return onSetValue\n }\n\n return (e: ChangeEvent<HTMLInputElement>) => {\n handlers.forEach((h) => h(e))\n onSetValue(e)\n }\n }, [onChange, onChangeInput, setInputValueIfUncontrolled])\n const onFocusInput = useMemo(\n () =>\n isFocused\n ? resetDeletionButtonFocus\n : () => {\n resetDeletionButtonFocus()\n focus()\n },\n [isFocused, focus, resetDeletionButtonFocus],\n )\n const onCompositionStartInput = useCallback(() => setIsComposing(true), [])\n const onCompositionEndInput = useCallback(() => setIsComposing(false), [])\n const onKeyDownInput = useCallback((e: KeyboardEvent<HTMLInputElement>) => {\n if (ARROW_UP_AND_DOWN_KEY_REGEX.test(e.key)) {\n // 上下キー入力はリストボックスの activeDescendant の移動に用いるため、input 内では作用させない\n e.preventDefault()\n }\n }, [])\n\n // HINT: form内にcomboboxを設置 & 検索inputにfocusした状態で\n // アイテムをキーボードで選択し、Enterを押すとinput上でEnterを押したことになるため、\n // submitイベントが発生し、formが送信される場合がある\n const onDelegateKeyPress = useMemo(\n () =>\n onKeyPress\n ? (e: KeyboardEvent<HTMLInputElement>) => {\n preventDefaultWithPressEnter(e)\n onKeyPress(e)\n }\n : preventDefaultWithPressEnter,\n [onKeyPress],\n )\n\n const selectedListId = useId()\n\n const wrapperStyle = useMemo(\n () => ({\n ...style,\n width: typeof width === 'number' ? `${width}px` : width,\n }),\n [style, width],\n )\n const classNames = useMemo(() => {\n const {\n wrapper,\n inputArea,\n selectedList,\n inputWrapper,\n input,\n placeholderEl,\n suffixWrapper,\n suffixIcon,\n } = classNameGenerator()\n\n return {\n wrapper: wrapper({ focused: isFocused, disabled, className }),\n inputArea: inputArea(),\n selectedList: selectedList(),\n inputWrapper: inputWrapper({ hidden: !isFocused }),\n input: input(),\n placeholder: placeholderEl(),\n suffixWrapper: suffixWrapper({ disabled }),\n suffixIcon: suffixIcon(),\n }\n }, [isFocused, disabled, className])\n\n const selectedListAriaLabel = useMemo(\n () =>\n localize({\n id: 'smarthr-ui/MultiCombobox/selectedListAriaLabel',\n defaultText: '選択済みアイテム',\n }),\n [localize],\n )\n\n return (\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions\n <div\n ref={outerRef}\n role=\"group\"\n onClick={onDelegateClick}\n onKeyDown={onDelegateKeyDown}\n onKeyPress={onDelegateKeyPress}\n className={classNames.wrapper}\n style={wrapperStyle}\n >\n <Scroller className={classNames.inputArea}>\n <ul\n id={selectedListId}\n aria-label={selectedListAriaLabel}\n className={classNames.selectedList}\n >\n {selectedItems.map((selectedItem, i) => (\n <li key={`${selectedItem.label}-${innerText(selectedItem.value)}`}>\n <MultiSelectedItem\n item={selectedItem}\n disabled={disabled}\n onDelete={actualOnDelete}\n enableEllipsis={selectedItemEllipsis}\n buttonRef={deletionButtonRefs[i]}\n />\n </li>\n ))}\n </ul>\n\n <div className={classNames.inputWrapper}>\n <input\n {...rest}\n data-smarthr-ui-input=\"true\"\n type=\"text\"\n name={name}\n value={inputValue}\n disabled={disabled}\n required={required && selectedItems.length === 0}\n ref={inputRef}\n onChange={actualOnChangeInput}\n onFocus={onFocusInput}\n onCompositionStart={onCompositionStartInput}\n onCompositionEnd={onCompositionEndInput}\n onKeyDown={onKeyDownInput}\n autoComplete={autoComplete ?? 'off'}\n tabIndex={0}\n role=\"combobox\"\n aria-activedescendant={activeOption?.id}\n aria-controls={`${listBoxId} ${selectedListId}`}\n aria-haspopup=\"listbox\"\n aria-expanded={isFocused}\n aria-invalid={error || undefined}\n aria-disabled={disabled}\n aria-autocomplete=\"list\"\n className={classNames.input}\n />\n </div>\n\n {selectedItems.length === 0 && placeholder && !isFocused && (\n <p className={classNames.placeholder}>{placeholder}</p>\n )}\n </Scroller>\n\n <MemoizedCaretDown\n disabled={disabled}\n isFocused={isFocused}\n className={classNames.suffixWrapper}\n iconStyle={classNames.suffixIcon}\n />\n\n {renderListBox()}\n </div>\n )\n}\n\nexport const MultiCombobox = genericsForwardRef(ActualMultiCombobox)\n\nconst MemoizedCaretDown = memo<{\n className: string\n iconStyle: string\n disabled: boolean\n isFocused: boolean\n}>(({ className, iconStyle, disabled, isFocused }) => {\n const theme = useTheme()\n const caretIconColor = useMemo(() => {\n if (isFocused) return theme.textColor.black\n if (disabled) return theme.textColor.disabled\n\n return theme.textColor.grey\n }, [disabled, isFocused, theme.textColor])\n\n return (\n <div className={className}>\n <FaCaretDownIcon color={caretIconColor} className={iconStyle} />\n </div>\n )\n})\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA8EA;AAEA;AACE;;;AAGF;AAEA;AACA;AACA;AACA;AAEA;AACE;AACA;;AAGF;AACE;AACE;;;;;AAKC;AACD;AACA;AAEA;AACA;;;;AAIC;AACD;AACA;;;AAGC;AACD;AACD;AACD;AACE;AACE;AACE;AACD;AACF;AACD;AACE;AACE;AAED;AACD;AACE;AACD;AACF;AACD;AACE;AACE;AACD;AACF;AACF;AACD;AACE;AACE;AACA;AACE;AACD;AACF;AACF;AACF;AAED;AAkCE;AACA;;;AAGA;;;;AAIA;;AAEE;;;;AAID;;AAED;;;AAII;;;AAGA;;AAKF;AACE;;;;;;AAOE;AACF;AACF;;AAEF;;;;AAKM;AAEA;AACE;;;AAIA;;AACK;;;AAGT;AACF;AAIF;;;;;AAKE;AACA;;AAEA;;AAED;AAED;;AAUA;;;AAGE;;AAGE;AACE;AACA;AACF;;AAGF;AACF;AACA;;AAEI;;;;AAKA;AACF;;AAGE;AACE;AACA;AACF;;AAGF;;AAGF;AACA;AAEA;;AAGE;AACF;;AAGE;;AAEE;;;;;;;;AAQA;;;AAIJ;AAGM;AACA;;;AAGM;;AACK;;;AAGH;;AAGF;;;;AAGA;;;;AAGA;;AACK;AAEL;;AAEA;;;;;;;;;;AAYA;AACA;;;AAIJ;;;;;;;;;;;;;AAcL;;AAMG;AACA;;AAEM;;;AAKZ;AACE;AACA;AACE;AACF;AAEA;AACE;;;AAIA;;AAEF;;AAEF;AAGM;;AAEI;AACA;;AAIV;AACA;AACA;;;;;;;;;AAUA;AAGM;;;;AAIA;AAIN;AAEA;AAEI;AACA;AACD;AAGH;;;AAaI;;;;;;AAMA;;;;;AAQE;AACA;AACD;;;AAMH;AAwEJ;;AAIA;AAME;AACA;AACE;AAAe;AACf;AAAc;AAEd;;AAGF;AAKF;;"}
1
+ {"version":3,"file":"MultiCombobox.cjs","sources":["../../../../src/components/Combobox/MultiCombobox/MultiCombobox.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n memo,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { useId } from 'react'\nimport innerText from 'react-innertext'\nimport { tv } from 'tailwind-variants'\n\nimport { useOuterClick } from '../../../hooks/useOuterClick'\nimport { useTheme } from '../../../hooks/useTheme'\nimport { useIntl } from '../../../intl'\nimport { genericsForwardRef } from '../../../libs/util'\nimport { FaCaretDownIcon } from '../../Icon'\nimport { Scroller } from '../../Scroller'\nimport { areItemsEqual } from '../helper'\nimport { useFocusControl } from '../useFocusControl'\nimport { useListbox } from '../useListbox'\nimport { useMultiOptions } from '../useOptions'\n\nimport { MultiSelectedItem } from './MultiSelectedItem'\n\nimport type { ComboboxItem, AbstractProps as ComboboxProps } from '../types'\n\ntype AbstractProps<T> = ComboboxProps<T> & {\n /**\n * 選択されているアイテムのリスト\n */\n selectedItems: Array<ComboboxItem<T> & { deletable?: boolean }>\n /**\n * 選択されているアイテムのラベルを省略表示するかどうか\n */\n selectedItemEllipsis?: boolean\n /**\n * テキストボックスの `value` 属性の値。\n * `onChangeInput` と併せて設定することで、テキストボックスの挙動が制御可能になる。\n */\n inputValue?: string\n /**\n * 選択されているアイテムの削除ボタンがクリックされた時に発火するコールバック関数\n */\n onDelete?: (item: ComboboxItem<T>) => void\n /**\n * 選択されているアイテムのリストが変わった時に発火するコールバック関数\n */\n onChangeSelected?: (selectedItems: Array<ComboboxItem<T>>) => void\n /**\n * コンポーネントがフォーカスされたときに発火するコールバック関数\n */\n onFocus?: () => void\n /**\n * コンポーネントからフォーカスが外れた時に発火するコールバック関数\n */\n onBlur?: () => void\n /**\n * アイテムが選択されたときに選択済みかどうかを判定するコールバック関数/\n */\n isItemSelected?: (targetItem: ComboboxItem<T>, selectedItems: Array<ComboboxItem<T>>) => boolean\n /**\n * 検索結果が0件の時に表示するコンテンツ\n */\n noResultText?: ReactNode\n}\ntype Props<T> = AbstractProps<T> &\n Omit<ComponentPropsWithoutRef<'input'>, keyof AbstractProps<unknown>>\n\nconst NOOP = () => undefined\n\nconst preventDefaultWithPressEnter = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n }\n}\n\nconst ESCAPE_KEY_REGEX = /^Esc(ape)?$/\nconst ARROW_LEFT_KEY_REGEX = /^(Arrow)?Left$/\nconst ARROW_RIGHT_KEY_REGEX = /^(Arrow)?Right/\nconst ARROW_UP_AND_DOWN_KEY_REGEX = /^(Arrow)?(Up|Down)$/\n\nconst EMPTY_INPUT_CHANGE_EVENT = {\n currentTarget: { value: '' },\n target: { value: '' },\n} as ChangeEvent<HTMLInputElement>\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-MultiCombobox',\n 'shr-box-border shr-inline-flex shr-min-w-[15em] shr-rounded-m shr-border shr-border-solid shr-px-0.5 shr-py-0.25 shr-align-bottom',\n 'contrast-more:shr-border-high-contrast',\n 'has-[[aria-invalid]]:shr-border-danger',\n ],\n inputArea: 'shr-flex shr-flex-1 shr-flex-wrap shr-gap-0.5',\n selectedList:\n 'smarthr-ui-MultiCombobox-selectedList shr-contents shr-list-none [&_li]:shr-min-w-0',\n inputWrapper: 'shr-flex shr-flex-1 shr-items-center',\n input: [\n 'smarthr-ui-MultiCombobox-input',\n 'shr-w-full shr-min-w-[5em] shr-border-none shr-text-base shr-text-black shr-outline-none shr-outline-0',\n 'disabled:shr-hidden',\n ],\n placeholderEl: 'smarthr-ui-MultiCombobox-placeholder shr-my-0 shr-self-center',\n suffixWrapper: [\n 'shr-relative -shr-me-0.5 shr-ms-0.5 shr-p-0.5',\n 'before:shr-absolute before:shr-inset-x-0 before:shr-inset-y-0.25 before:shr-w-0 before:shr-border-0 before:shr-border-l before:shr-border-solid before:shr-border-default before:shr-content-[\"\"]',\n ],\n suffixIcon: 'shr-block',\n },\n variants: {\n focused: {\n true: {\n wrapper: 'shr-focus-indicator',\n },\n },\n disabled: {\n true: {\n wrapper:\n 'shr-cursor-not-allowed shr-border-default/50 shr-bg-white-darken shr-text-disabled',\n },\n false: {\n wrapper: 'shr-cursor-text shr-bg-white',\n },\n },\n hidden: {\n true: {\n inputWrapper: 'shr-pointer-events-none shr-absolute shr-opacity-0',\n },\n },\n },\n compoundVariants: [\n {\n disabled: false,\n className: {\n wrapper: 'shr-border-default',\n },\n },\n ],\n})\n\nconst ActualMultiCombobox = <T,>(\n {\n items,\n selectedItems,\n name,\n disabled = false,\n required = false,\n error = false,\n creatable = false,\n placeholder = '',\n autoComplete,\n dropdownHelpMessage,\n isLoading,\n selectedItemEllipsis,\n width,\n dropdownWidth = 'auto',\n inputValue: controlledInputValue,\n className,\n onChange,\n onChangeInput,\n onAdd,\n onDelete,\n onSelect,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n isItemSelected,\n noResultText,\n style,\n ...rest\n }: Props<T>,\n ref: Ref<HTMLInputElement>,\n) => {\n const { localize } = useIntl()\n const outerRef = useRef<HTMLDivElement>(null)\n const [isFocused, setIsFocused] = useState(false)\n const [highlighted, setHighlighted] = useState(false)\n const isInputControlled = controlledInputValue !== undefined\n const [uncontrolledInputValue, setUncontrolledInputValue] = useState('')\n const inputValue = isInputControlled ? controlledInputValue : uncontrolledInputValue\n const [isComposing, setIsComposing] = useState(false)\n\n const unstableRef = useRef({\n onChange,\n onChangeInput,\n onAdd,\n onSelect,\n onDelete,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n isItemSelected,\n selectedItems,\n isFocused,\n highlighted,\n isComposing,\n })\n unstableRef.current = {\n onChange,\n onChangeInput,\n onAdd,\n onSelect,\n onDelete,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n isItemSelected,\n selectedItems,\n isFocused,\n highlighted,\n isComposing,\n }\n const { options } = useMultiOptions({\n items,\n selected: selectedItems,\n creatable,\n inputValue,\n isItemSelected,\n })\n const setInputValueIfUncontrolled = isInputControlled ? NOOP : setUncontrolledInputValue\n const actualOnDelete = useCallback((item: ComboboxItem<T>) => {\n const handlers: Array<(deletingItem: ComboboxItem<T>) => void> = []\n\n if (unstableRef.current.onDelete) {\n handlers.push((deletingItem: ComboboxItem<T>) => unstableRef.current.onDelete!(deletingItem))\n }\n if (unstableRef.current.onChangeSelected) {\n handlers.push((deletingItem: ComboboxItem<T>) =>\n unstableRef.current.onChangeSelected!(\n unstableRef.current.selectedItems.filter(\n (selected) => !areItemsEqual(selected, deletingItem),\n ),\n ),\n )\n }\n\n if (handlers.length > 0) {\n // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう\n // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする\n requestAnimationFrame(() => {\n handlers.forEach((h) => h(item))\n })\n }\n }, [])\n const actualOnSelect = useCallback(\n (selected: ComboboxItem<T>) => {\n // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう\n // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする\n requestAnimationFrame(() => {\n const matchedSelectedItem = unstableRef.current.selectedItems.find((item) =>\n areItemsEqual(item, selected),\n )\n\n if (matchedSelectedItem === undefined) {\n unstableRef.current.onSelect?.(selected)\n unstableRef.current.onChangeSelected?.(unstableRef.current.selectedItems.concat(selected))\n\n // 制御コンポーネントの場合に親側でinputValueを更新できるように、選択時にonChangeInputを空文字で発火する\n unstableRef.current.onChangeInput?.(EMPTY_INPUT_CHANGE_EVENT)\n } else if (matchedSelectedItem.deletable !== false) {\n actualOnDelete(selected)\n }\n })\n },\n [actualOnDelete],\n )\n\n const { renderListBox, activeOption, onKeyDownListBox, listBoxId, listBoxRef } = useListbox({\n options,\n dropdownHelpMessage,\n dropdownWidth,\n onAdd,\n onSelect: actualOnSelect,\n isExpanded: isFocused,\n isLoading,\n triggerRef: outerRef,\n noResultText,\n })\n\n const {\n deletionButtonRefs,\n inputRef,\n focusPrevDeletionButton,\n focusNextDeletionButton,\n resetDeletionButtonFocus,\n } = useFocusControl(selectedItems.length)\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(ref, () => inputRef.current)\n\n const focus = useCallback(() => {\n unstableRef.current.onFocus?.()\n setIsFocused(true)\n }, [])\n\n const blur = useCallback(() => {\n if (unstableRef.current.isFocused) {\n unstableRef.current.onBlur?.()\n setIsFocused(false)\n resetDeletionButtonFocus()\n }\n }, [resetDeletionButtonFocus])\n\n const outerClickRef = useMemo(() => [outerRef, listBoxRef], [listBoxRef])\n useOuterClick(outerClickRef, blur)\n\n useEffect(() => {\n if (unstableRef.current.highlighted) {\n setHighlighted(false)\n inputRef.current?.select()\n } else {\n setInputValueIfUncontrolled('')\n }\n }, [selectedItems, setInputValueIfUncontrolled, inputRef])\n\n useEffect(() => {\n if (isFocused) {\n inputRef.current?.focus()\n }\n }, [isFocused, setInputValueIfUncontrolled, selectedItems, inputRef])\n\n const isInputEmpty = !inputValue\n\n const onDelegateKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (unstableRef.current.isComposing) return\n\n if (ESCAPE_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n blur()\n } else if (e.key === 'Tab') {\n if (unstableRef.current.isFocused) {\n // フォーカスがコンポーネントを抜けるように先に input をフォーカスしておく\n inputRef.current?.focus()\n }\n\n blur()\n } else if (ARROW_LEFT_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n focusPrevDeletionButton()\n } else if (ARROW_RIGHT_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n focusNextDeletionButton()\n } else if (\n e.key === 'Backspace' &&\n isInputEmpty &&\n unstableRef.current.selectedItems.length > 0 &&\n unstableRef.current.selectedItems[unstableRef.current.selectedItems.length - 1].deletable !==\n false\n ) {\n e.preventDefault()\n e.stopPropagation()\n\n const lastItem =\n unstableRef.current.selectedItems[unstableRef.current.selectedItems.length - 1]\n\n actualOnDelete(lastItem)\n setHighlighted(true)\n setInputValueIfUncontrolled(innerText(lastItem.label))\n } else {\n e.stopPropagation()\n inputRef.current?.focus()\n resetDeletionButtonFocus()\n }\n\n onKeyDownListBox(e)\n }\n\n const onDelegateClick = useCallback(\n (e: MouseEvent<HTMLElement>) => {\n if (!disabled && !unstableRef.current.isFocused) {\n if (!(e.target as HTMLElement).closest('.smarthr-ui-MultiCombobox-deleteButton')) {\n focus()\n }\n }\n },\n [disabled, focus],\n )\n const actualOnChangeInput = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const handlers = [unstableRef.current.onChange, unstableRef.current.onChangeInput].filter(\n (h) => !!h,\n )\n\n handlers.forEach((h) => h(e))\n setInputValueIfUncontrolled(e.currentTarget.value)\n },\n [setInputValueIfUncontrolled],\n )\n const onFocusInput = useCallback(() => {\n if (unstableRef.current.isFocused) {\n resetDeletionButtonFocus()\n } else {\n resetDeletionButtonFocus()\n focus()\n }\n }, [resetDeletionButtonFocus, focus])\n const onCompositionStartInput = useCallback(() => setIsComposing(true), [])\n const onCompositionEndInput = useCallback(() => setIsComposing(false), [])\n const onKeyDownInput = useCallback((e: KeyboardEvent<HTMLInputElement>) => {\n if (ARROW_UP_AND_DOWN_KEY_REGEX.test(e.key)) {\n // 上下キー入力はリストボックスの activeDescendant の移動に用いるため、input 内では作用させない\n e.preventDefault()\n }\n }, [])\n\n // HINT: form内にcomboboxを設置 & 検索inputにfocusした状態で\n // アイテムをキーボードで選択し、Enterを押すとinput上でEnterを押したことになるため、\n // submitイベントが発生し、formが送信される場合がある\n const onDelegateKeyPress = useCallback((e: KeyboardEvent<HTMLInputElement>) => {\n preventDefaultWithPressEnter(e)\n unstableRef.current.onKeyPress?.(e)\n }, [])\n\n const selectedListId = useId()\n\n const wrapperStyle = useMemo(\n () => ({\n ...style,\n width: typeof width === 'number' ? `${width}px` : width,\n }),\n [style, width],\n )\n const classNames = useMemo(() => {\n const {\n wrapper,\n inputArea,\n selectedList,\n inputWrapper,\n input,\n placeholderEl,\n suffixWrapper,\n suffixIcon,\n } = classNameGenerator()\n\n return {\n wrapper: wrapper({ focused: isFocused, disabled, className }),\n inputArea: inputArea(),\n selectedList: selectedList(),\n inputWrapper: inputWrapper({ hidden: !isFocused }),\n input: input(),\n placeholder: placeholderEl(),\n suffixWrapper: suffixWrapper({ disabled }),\n suffixIcon: suffixIcon(),\n }\n }, [isFocused, disabled, className])\n\n const selectedListAriaLabel = useMemo(\n () =>\n localize({\n id: 'smarthr-ui/MultiCombobox/selectedListAriaLabel',\n defaultText: '選択済みアイテム',\n }),\n [localize],\n )\n\n return (\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions\n <div\n ref={outerRef}\n role=\"group\"\n onClick={onDelegateClick}\n onKeyDown={onDelegateKeyDown}\n onKeyPress={onDelegateKeyPress}\n className={classNames.wrapper}\n style={wrapperStyle}\n >\n <Scroller className={classNames.inputArea}>\n <ul\n id={selectedListId}\n aria-label={selectedListAriaLabel}\n className={classNames.selectedList}\n >\n {selectedItems.map((selectedItem, i) => (\n <li key={`${selectedItem.label}-${innerText(selectedItem.value)}`}>\n <MultiSelectedItem\n item={selectedItem}\n disabled={disabled}\n onDelete={actualOnDelete}\n enableEllipsis={selectedItemEllipsis}\n buttonRef={deletionButtonRefs[i]}\n />\n </li>\n ))}\n </ul>\n\n <div className={classNames.inputWrapper}>\n <input\n {...rest}\n data-smarthr-ui-input=\"true\"\n type=\"text\"\n name={name}\n value={inputValue}\n disabled={disabled}\n required={required && selectedItems.length === 0}\n ref={inputRef}\n onChange={actualOnChangeInput}\n onFocus={onFocusInput}\n onCompositionStart={onCompositionStartInput}\n onCompositionEnd={onCompositionEndInput}\n onKeyDown={onKeyDownInput}\n autoComplete={autoComplete ?? 'off'}\n tabIndex={0}\n role=\"combobox\"\n aria-activedescendant={activeOption?.id}\n aria-controls={`${listBoxId} ${selectedListId}`}\n aria-haspopup=\"listbox\"\n aria-expanded={isFocused}\n aria-invalid={error || undefined}\n aria-disabled={disabled}\n aria-autocomplete=\"list\"\n className={classNames.input}\n />\n </div>\n\n {selectedItems.length === 0 && placeholder && !isFocused && (\n <p className={classNames.placeholder}>{placeholder}</p>\n )}\n </Scroller>\n\n <MemoizedCaretDown\n disabled={disabled}\n isFocused={isFocused}\n className={classNames.suffixWrapper}\n iconStyle={classNames.suffixIcon}\n />\n\n {renderListBox()}\n </div>\n )\n}\n\nexport const MultiCombobox = genericsForwardRef(ActualMultiCombobox)\n\nconst MemoizedCaretDown = memo<{\n className: string\n iconStyle: string\n disabled: boolean\n isFocused: boolean\n}>(({ className, iconStyle, disabled, isFocused }) => {\n const theme = useTheme()\n const caretIconColor = isFocused\n ? theme.textColor.black\n : disabled\n ? theme.textColor.disabled\n : theme.textColor.grey\n\n return (\n <div className={className}>\n <FaCaretDownIcon color={caretIconColor} className={iconStyle} />\n </div>\n )\n})\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA8EA;AAEA;AACE;;;AAGF;AAEA;AACA;AACA;AACA;AAEA;AACE;AACA;;AAGF;AACE;AACE;;;;;AAKC;AACD;AACA;AAEA;AACA;;;;AAIC;AACD;AACA;;;AAGC;AACD;AACD;AACD;AACE;AACE;AACE;AACD;AACF;AACD;AACE;AACE;AAED;AACD;AACE;AACD;AACF;AACD;AACE;AACE;AACD;AACF;AACF;AACD;AACE;AACE;AACA;AACE;AACD;AACF;AACF;AACF;AAED;AAkCE;AACA;;;AAGA;;;;;;;;;;;;;;;;;;;AAoBC;;;;;;;;;;;;;;;;;AAiBD;;AAEE;;;;AAID;;AAED;;AAGE;AACE;;AAEF;AACE;;AASF;;;;AAII;AACF;;;AAGJ;;;;;AASM;;AAEE;;;;AAIK;;;AAGT;AACF;AAIF;;;;;AAKE;AACA;;AAEA;;AAED;AAED;;AAUA;AACE;;;AAIF;AACE;AACE;;AAEA;;AAEJ;AAEA;AACA;;AAGE;;AAEE;;;;;;;;AAQA;;;AAIJ;AAEA;AACE;;;;AAIE;;AACK;AACL;;AAEE;;AAGF;;;;AAGA;;;;AAGA;;AACK;;AAGL;AACA;AACE;;;AAKF;;;;;;;AAQA;AACA;;;AAIJ;AAEA;;;AAIQ;;;AAGN;AAGF;;AAMI;AACA;AACF;AAGF;AACE;AACE;;;AAEA;AACA;;AAEJ;AACA;AACA;AACA;;;;;;;;;AAUA;;;;AAKA;AAEA;AAEI;AACA;AACD;AAGH;;;AAaI;;;;;;AAMA;;;;;AAQE;AACA;AACD;;;AAMH;AAwEJ;;AAIA;AAME;;AAEE;AACA;AACE;AACA;AAEJ;AAKF;;"}
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
- import { memo, useMemo, useRef, useState, useCallback, useImperativeHandle, useEffect, useId } from 'react';
3
+ import { memo, useRef, useState, useCallback, useImperativeHandle, useMemo, useEffect, useId } from 'react';
4
4
  import innerText from '../../../_virtual/index3.js';
5
5
  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
6
  import { useOuterClick } from '../../../hooks/useOuterClick.js';
7
7
  import { useTheme } from '../../../hooks/useTheme.js';
8
8
  import '../../../intl/IntlProvider.js';
9
9
  import { useIntl } from '../../../intl/useIntl.js';
10
- import 'react-intl';
10
+ import '../../../intl/Localizer.js';
11
11
  import '../../../_virtual/dayjs.min.js';
12
12
  import '../../../intl/TimeFormatter.js';
13
13
  import { genericsForwardRef } from '../../../libs/util.js';
@@ -96,6 +96,38 @@ const ActualMultiCombobox = ({ items, selectedItems, name, disabled = false, req
96
96
  const [uncontrolledInputValue, setUncontrolledInputValue] = useState('');
97
97
  const inputValue = isInputControlled ? controlledInputValue : uncontrolledInputValue;
98
98
  const [isComposing, setIsComposing] = useState(false);
99
+ const unstableRef = useRef({
100
+ onChange,
101
+ onChangeInput,
102
+ onAdd,
103
+ onSelect,
104
+ onDelete,
105
+ onChangeSelected,
106
+ onFocus,
107
+ onBlur,
108
+ onKeyPress,
109
+ isItemSelected,
110
+ selectedItems,
111
+ isFocused,
112
+ highlighted,
113
+ isComposing,
114
+ });
115
+ unstableRef.current = {
116
+ onChange,
117
+ onChangeInput,
118
+ onAdd,
119
+ onSelect,
120
+ onDelete,
121
+ onChangeSelected,
122
+ onFocus,
123
+ onBlur,
124
+ onKeyPress,
125
+ isItemSelected,
126
+ selectedItems,
127
+ isFocused,
128
+ highlighted,
129
+ isComposing,
130
+ };
99
131
  const { options } = useMultiOptions({
100
132
  items,
101
133
  selected: selectedItems,
@@ -104,41 +136,38 @@ const ActualMultiCombobox = ({ items, selectedItems, name, disabled = false, req
104
136
  isItemSelected,
105
137
  });
106
138
  const setInputValueIfUncontrolled = isInputControlled ? NOOP : setUncontrolledInputValue;
107
- const actualOnDelete = useMemo(() => {
139
+ const actualOnDelete = useCallback((item) => {
108
140
  const handlers = [];
109
- if (onDelete) {
110
- handlers.push((item) => onDelete(item));
111
- }
112
- if (onChangeSelected) {
113
- handlers.push((item) => onChangeSelected(selectedItems.filter((selected) => !areItemsEqual(selected, item))));
141
+ if (unstableRef.current.onDelete) {
142
+ handlers.push((deletingItem) => unstableRef.current.onDelete(deletingItem));
114
143
  }
115
- if (handlers.length === 0) {
116
- return NOOP;
144
+ if (unstableRef.current.onChangeSelected) {
145
+ handlers.push((deletingItem) => unstableRef.current.onChangeSelected(unstableRef.current.selectedItems.filter((selected) => !areItemsEqual(selected, deletingItem))));
117
146
  }
118
- return (item) => {
147
+ if (handlers.length > 0) {
119
148
  // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう
120
149
  // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする
121
150
  requestAnimationFrame(() => {
122
151
  handlers.forEach((h) => h(item));
123
152
  });
124
- };
125
- }, [selectedItems, onChangeSelected, onDelete]);
153
+ }
154
+ }, []);
126
155
  const actualOnSelect = useCallback((selected) => {
127
156
  // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう
128
157
  // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする
129
158
  requestAnimationFrame(() => {
130
- const matchedSelectedItem = selectedItems.find((item) => areItemsEqual(item, selected));
159
+ const matchedSelectedItem = unstableRef.current.selectedItems.find((item) => areItemsEqual(item, selected));
131
160
  if (matchedSelectedItem === undefined) {
132
- onSelect?.(selected);
133
- onChangeSelected?.(selectedItems.concat(selected));
161
+ unstableRef.current.onSelect?.(selected);
162
+ unstableRef.current.onChangeSelected?.(unstableRef.current.selectedItems.concat(selected));
134
163
  // 制御コンポーネントの場合に親側でinputValueを更新できるように、選択時にonChangeInputを空文字で発火する
135
- onChangeInput?.(EMPTY_INPUT_CHANGE_EVENT);
164
+ unstableRef.current.onChangeInput?.(EMPTY_INPUT_CHANGE_EVENT);
136
165
  }
137
166
  else if (matchedSelectedItem.deletable !== false) {
138
167
  actualOnDelete(selected);
139
168
  }
140
169
  });
141
- }, [selectedItems, actualOnDelete, onChangeSelected, onSelect, onChangeInput]);
170
+ }, [actualOnDelete]);
142
171
  const { renderListBox, activeOption, onKeyDownListBox, listBoxId, listBoxRef } = useListbox({
143
172
  options,
144
173
  dropdownHelpMessage,
@@ -152,133 +181,96 @@ const ActualMultiCombobox = ({ items, selectedItems, name, disabled = false, req
152
181
  });
153
182
  const { deletionButtonRefs, inputRef, focusPrevDeletionButton, focusNextDeletionButton, resetDeletionButtonFocus, } = useFocusControl(selectedItems.length);
154
183
  useImperativeHandle(ref, () => inputRef.current);
155
- const focus = useMemo(() => {
156
- const baseAction = () => {
157
- setIsFocused(true);
158
- };
159
- if (onFocus) {
160
- return () => {
161
- onFocus();
162
- baseAction();
163
- };
164
- }
165
- return baseAction;
166
- }, [onFocus]);
167
- const blur = useMemo(() => {
168
- if (!isFocused) {
169
- return NOOP;
170
- }
171
- const baseAction = () => {
184
+ const focus = useCallback(() => {
185
+ unstableRef.current.onFocus?.();
186
+ setIsFocused(true);
187
+ }, []);
188
+ const blur = useCallback(() => {
189
+ if (unstableRef.current.isFocused) {
190
+ unstableRef.current.onBlur?.();
172
191
  setIsFocused(false);
173
192
  resetDeletionButtonFocus();
174
- };
175
- if (onBlur) {
176
- return () => {
177
- onBlur();
178
- baseAction();
179
- };
180
193
  }
181
- return baseAction;
182
- }, [isFocused, onBlur, resetDeletionButtonFocus]);
183
- const outerClickRef = useMemo(() => [outerRef, listBoxRef], [outerRef, listBoxRef]);
194
+ }, [resetDeletionButtonFocus]);
195
+ const outerClickRef = useMemo(() => [outerRef, listBoxRef], [listBoxRef]);
184
196
  useOuterClick(outerClickRef, blur);
185
- const highlightedRef = useRef(highlighted);
186
- useEffect(() => {
187
- highlightedRef.current = highlighted;
188
- }, [highlighted]);
189
197
  useEffect(() => {
190
- if (highlightedRef.current) {
198
+ if (unstableRef.current.highlighted) {
191
199
  setHighlighted(false);
192
200
  inputRef.current?.select();
193
201
  }
194
202
  else {
195
203
  setInputValueIfUncontrolled('');
196
204
  }
197
- }, [selectedItems, inputRef, setInputValueIfUncontrolled]);
205
+ }, [selectedItems, setInputValueIfUncontrolled, inputRef]);
198
206
  useEffect(() => {
199
207
  if (isFocused) {
200
208
  inputRef.current?.focus();
201
209
  }
202
- }, [inputRef, isFocused, setInputValueIfUncontrolled, selectedItems]);
203
- const onDelegateKeyDown = useMemo(() => isComposing
204
- ? undefined
205
- : (e) => {
206
- if (ESCAPE_KEY_REGEX.test(e.key)) {
207
- e.stopPropagation();
208
- blur();
209
- }
210
- else if (e.key === 'Tab') {
211
- if (isFocused) {
212
- // フォーカスがコンポーネントを抜けるように先に input をフォーカスしておく
213
- inputRef.current?.focus();
214
- }
215
- blur();
216
- }
217
- else if (ARROW_LEFT_KEY_REGEX.test(e.key)) {
218
- e.stopPropagation();
219
- focusPrevDeletionButton();
220
- }
221
- else if (ARROW_RIGHT_KEY_REGEX.test(e.key)) {
222
- e.stopPropagation();
223
- focusNextDeletionButton();
224
- }
225
- else if (e.key === 'Backspace' &&
226
- !inputValue &&
227
- selectedItems.length > 0 &&
228
- selectedItems[selectedItems.length - 1].deletable !== false) {
229
- e.preventDefault();
230
- e.stopPropagation();
231
- const lastItem = selectedItems[selectedItems.length - 1];
232
- actualOnDelete(lastItem);
233
- setHighlighted(true);
234
- setInputValueIfUncontrolled(innerText(lastItem.label));
235
- }
236
- else {
237
- e.stopPropagation();
210
+ }, [isFocused, setInputValueIfUncontrolled, selectedItems, inputRef]);
211
+ const isInputEmpty = !inputValue;
212
+ const onDelegateKeyDown = (e) => {
213
+ if (unstableRef.current.isComposing)
214
+ return;
215
+ if (ESCAPE_KEY_REGEX.test(e.key)) {
216
+ e.stopPropagation();
217
+ blur();
218
+ }
219
+ else if (e.key === 'Tab') {
220
+ if (unstableRef.current.isFocused) {
221
+ // フォーカスがコンポーネントを抜けるように先に input をフォーカスしておく
238
222
  inputRef.current?.focus();
239
- resetDeletionButtonFocus();
240
223
  }
241
- onKeyDownListBox(e);
242
- }, [
243
- blur,
244
- focusNextDeletionButton,
245
- focusPrevDeletionButton,
246
- onKeyDownListBox,
247
- inputRef,
248
- isComposing,
249
- isFocused,
250
- resetDeletionButtonFocus,
251
- actualOnDelete,
252
- inputValue,
253
- selectedItems,
254
- setInputValueIfUncontrolled,
255
- ]);
256
- const onDelegateClick = useMemo(() => disabled || isFocused
257
- ? undefined
258
- : (e) => {
224
+ blur();
225
+ }
226
+ else if (ARROW_LEFT_KEY_REGEX.test(e.key)) {
227
+ e.stopPropagation();
228
+ focusPrevDeletionButton();
229
+ }
230
+ else if (ARROW_RIGHT_KEY_REGEX.test(e.key)) {
231
+ e.stopPropagation();
232
+ focusNextDeletionButton();
233
+ }
234
+ else if (e.key === 'Backspace' &&
235
+ isInputEmpty &&
236
+ unstableRef.current.selectedItems.length > 0 &&
237
+ unstableRef.current.selectedItems[unstableRef.current.selectedItems.length - 1].deletable !==
238
+ false) {
239
+ e.preventDefault();
240
+ e.stopPropagation();
241
+ const lastItem = unstableRef.current.selectedItems[unstableRef.current.selectedItems.length - 1];
242
+ actualOnDelete(lastItem);
243
+ setHighlighted(true);
244
+ setInputValueIfUncontrolled(innerText(lastItem.label));
245
+ }
246
+ else {
247
+ e.stopPropagation();
248
+ inputRef.current?.focus();
249
+ resetDeletionButtonFocus();
250
+ }
251
+ onKeyDownListBox(e);
252
+ };
253
+ const onDelegateClick = useCallback((e) => {
254
+ if (!disabled && !unstableRef.current.isFocused) {
259
255
  if (!e.target.closest('.smarthr-ui-MultiCombobox-deleteButton')) {
260
256
  focus();
261
257
  }
262
- }, [isFocused, disabled, focus]);
263
- const actualOnChangeInput = useMemo(() => {
264
- const handlers = [onChange, onChangeInput].filter((h) => !!h);
265
- const onSetValue = (e) => {
266
- setInputValueIfUncontrolled(e.currentTarget.value);
267
- };
268
- if (handlers.length === 0) {
269
- return onSetValue;
270
258
  }
271
- return (e) => {
272
- handlers.forEach((h) => h(e));
273
- onSetValue(e);
274
- };
275
- }, [onChange, onChangeInput, setInputValueIfUncontrolled]);
276
- const onFocusInput = useMemo(() => isFocused
277
- ? resetDeletionButtonFocus
278
- : () => {
259
+ }, [disabled, focus]);
260
+ const actualOnChangeInput = useCallback((e) => {
261
+ const handlers = [unstableRef.current.onChange, unstableRef.current.onChangeInput].filter((h) => !!h);
262
+ handlers.forEach((h) => h(e));
263
+ setInputValueIfUncontrolled(e.currentTarget.value);
264
+ }, [setInputValueIfUncontrolled]);
265
+ const onFocusInput = useCallback(() => {
266
+ if (unstableRef.current.isFocused) {
267
+ resetDeletionButtonFocus();
268
+ }
269
+ else {
279
270
  resetDeletionButtonFocus();
280
271
  focus();
281
- }, [isFocused, focus, resetDeletionButtonFocus]);
272
+ }
273
+ }, [resetDeletionButtonFocus, focus]);
282
274
  const onCompositionStartInput = useCallback(() => setIsComposing(true), []);
283
275
  const onCompositionEndInput = useCallback(() => setIsComposing(false), []);
284
276
  const onKeyDownInput = useCallback((e) => {
@@ -290,12 +282,10 @@ const ActualMultiCombobox = ({ items, selectedItems, name, disabled = false, req
290
282
  // HINT: form内にcomboboxを設置 & 検索inputにfocusした状態で
291
283
  // アイテムをキーボードで選択し、Enterを押すとinput上でEnterを押したことになるため、
292
284
  // submitイベントが発生し、formが送信される場合がある
293
- const onDelegateKeyPress = useMemo(() => onKeyPress
294
- ? (e) => {
295
- preventDefaultWithPressEnter(e);
296
- onKeyPress(e);
297
- }
298
- : preventDefaultWithPressEnter, [onKeyPress]);
285
+ const onDelegateKeyPress = useCallback((e) => {
286
+ preventDefaultWithPressEnter(e);
287
+ unstableRef.current.onKeyPress?.(e);
288
+ }, []);
299
289
  const selectedListId = useId();
300
290
  const wrapperStyle = useMemo(() => ({
301
291
  ...style,
@@ -325,13 +315,11 @@ const ActualMultiCombobox = ({ items, selectedItems, name, disabled = false, req
325
315
  const MultiCombobox = genericsForwardRef(ActualMultiCombobox);
326
316
  const MemoizedCaretDown = memo(({ className, iconStyle, disabled, isFocused }) => {
327
317
  const theme = useTheme();
328
- const caretIconColor = useMemo(() => {
329
- if (isFocused)
330
- return theme.textColor.black;
331
- if (disabled)
332
- return theme.textColor.disabled;
333
- return theme.textColor.grey;
334
- }, [disabled, isFocused, theme.textColor]);
318
+ const caretIconColor = isFocused
319
+ ? theme.textColor.black
320
+ : disabled
321
+ ? theme.textColor.disabled
322
+ : theme.textColor.grey;
335
323
  return (jsx("div", { className: className, children: jsx(FaCaretDownIcon, { color: caretIconColor, className: iconStyle }) }));
336
324
  });
337
325
 
@@ -1 +1 @@
1
- {"version":3,"file":"MultiCombobox.js","sources":["../../../../src/components/Combobox/MultiCombobox/MultiCombobox.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n memo,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { useId } from 'react'\nimport innerText from 'react-innertext'\nimport { tv } from 'tailwind-variants'\n\nimport { useOuterClick } from '../../../hooks/useOuterClick'\nimport { useTheme } from '../../../hooks/useTheme'\nimport { useIntl } from '../../../intl'\nimport { genericsForwardRef } from '../../../libs/util'\nimport { FaCaretDownIcon } from '../../Icon'\nimport { Scroller } from '../../Scroller'\nimport { areItemsEqual } from '../helper'\nimport { useFocusControl } from '../useFocusControl'\nimport { useListbox } from '../useListbox'\nimport { useMultiOptions } from '../useOptions'\n\nimport { MultiSelectedItem } from './MultiSelectedItem'\n\nimport type { ComboboxItem, AbstractProps as ComboboxProps } from '../types'\n\ntype AbstractProps<T> = ComboboxProps<T> & {\n /**\n * 選択されているアイテムのリスト\n */\n selectedItems: Array<ComboboxItem<T> & { deletable?: boolean }>\n /**\n * 選択されているアイテムのラベルを省略表示するかどうか\n */\n selectedItemEllipsis?: boolean\n /**\n * テキストボックスの `value` 属性の値。\n * `onChangeInput` と併せて設定することで、テキストボックスの挙動が制御可能になる。\n */\n inputValue?: string\n /**\n * 選択されているアイテムの削除ボタンがクリックされた時に発火するコールバック関数\n */\n onDelete?: (item: ComboboxItem<T>) => void\n /**\n * 選択されているアイテムのリストが変わった時に発火するコールバック関数\n */\n onChangeSelected?: (selectedItems: Array<ComboboxItem<T>>) => void\n /**\n * コンポーネントがフォーカスされたときに発火するコールバック関数\n */\n onFocus?: () => void\n /**\n * コンポーネントからフォーカスが外れた時に発火するコールバック関数\n */\n onBlur?: () => void\n /**\n * アイテムが選択されたときに選択済みかどうかを判定するコールバック関数/\n */\n isItemSelected?: (targetItem: ComboboxItem<T>, selectedItems: Array<ComboboxItem<T>>) => boolean\n /**\n * 検索結果が0件の時に表示するコンテンツ\n */\n noResultText?: ReactNode\n}\ntype Props<T> = AbstractProps<T> &\n Omit<ComponentPropsWithoutRef<'input'>, keyof AbstractProps<unknown>>\n\nconst NOOP = () => undefined\n\nconst preventDefaultWithPressEnter = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n }\n}\n\nconst ESCAPE_KEY_REGEX = /^Esc(ape)?$/\nconst ARROW_LEFT_KEY_REGEX = /^(Arrow)?Left$/\nconst ARROW_RIGHT_KEY_REGEX = /^(Arrow)?Right/\nconst ARROW_UP_AND_DOWN_KEY_REGEX = /^(Arrow)?(Up|Down)$/\n\nconst EMPTY_INPUT_CHANGE_EVENT = {\n currentTarget: { value: '' },\n target: { value: '' },\n} as ChangeEvent<HTMLInputElement>\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-MultiCombobox',\n 'shr-box-border shr-inline-flex shr-min-w-[15em] shr-rounded-m shr-border shr-border-solid shr-px-0.5 shr-py-0.25 shr-align-bottom',\n 'contrast-more:shr-border-high-contrast',\n 'has-[[aria-invalid]]:shr-border-danger',\n ],\n inputArea: 'shr-flex shr-flex-1 shr-flex-wrap shr-gap-0.5',\n selectedList:\n 'smarthr-ui-MultiCombobox-selectedList shr-contents shr-list-none [&_li]:shr-min-w-0',\n inputWrapper: 'shr-flex shr-flex-1 shr-items-center',\n input: [\n 'smarthr-ui-MultiCombobox-input',\n 'shr-w-full shr-min-w-[5em] shr-border-none shr-text-base shr-text-black shr-outline-none shr-outline-0',\n 'disabled:shr-hidden',\n ],\n placeholderEl: 'smarthr-ui-MultiCombobox-placeholder shr-my-0 shr-self-center',\n suffixWrapper: [\n 'shr-relative -shr-me-0.5 shr-ms-0.5 shr-p-0.5',\n 'before:shr-absolute before:shr-inset-x-0 before:shr-inset-y-0.25 before:shr-w-0 before:shr-border-0 before:shr-border-l before:shr-border-solid before:shr-border-default before:shr-content-[\"\"]',\n ],\n suffixIcon: 'shr-block',\n },\n variants: {\n focused: {\n true: {\n wrapper: 'shr-focus-indicator',\n },\n },\n disabled: {\n true: {\n wrapper:\n 'shr-cursor-not-allowed shr-border-default/50 shr-bg-white-darken shr-text-disabled',\n },\n false: {\n wrapper: 'shr-cursor-text shr-bg-white',\n },\n },\n hidden: {\n true: {\n inputWrapper: 'shr-pointer-events-none shr-absolute shr-opacity-0',\n },\n },\n },\n compoundVariants: [\n {\n disabled: false,\n className: {\n wrapper: 'shr-border-default',\n },\n },\n ],\n})\n\nconst ActualMultiCombobox = <T,>(\n {\n items,\n selectedItems,\n name,\n disabled = false,\n required = false,\n error = false,\n creatable = false,\n placeholder = '',\n autoComplete,\n dropdownHelpMessage,\n isLoading,\n selectedItemEllipsis,\n width,\n dropdownWidth = 'auto',\n inputValue: controlledInputValue,\n className,\n onChange,\n onChangeInput,\n onAdd,\n onDelete,\n onSelect,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n isItemSelected,\n noResultText,\n style,\n ...rest\n }: Props<T>,\n ref: Ref<HTMLInputElement>,\n) => {\n const { localize } = useIntl()\n const outerRef = useRef<HTMLDivElement>(null)\n const [isFocused, setIsFocused] = useState(false)\n const [highlighted, setHighlighted] = useState(false)\n const isInputControlled = controlledInputValue !== undefined\n const [uncontrolledInputValue, setUncontrolledInputValue] = useState('')\n const inputValue = isInputControlled ? controlledInputValue : uncontrolledInputValue\n const [isComposing, setIsComposing] = useState(false)\n const { options } = useMultiOptions({\n items,\n selected: selectedItems,\n creatable,\n inputValue,\n isItemSelected,\n })\n const setInputValueIfUncontrolled = isInputControlled ? NOOP : setUncontrolledInputValue\n const actualOnDelete = useMemo(() => {\n const handlers: Array<(item: ComboboxItem<T>) => void> = []\n\n if (onDelete) {\n handlers.push((item: ComboboxItem<T>) => onDelete(item))\n }\n if (onChangeSelected) {\n handlers.push((item: ComboboxItem<T>) =>\n onChangeSelected(selectedItems.filter((selected) => !areItemsEqual(selected, item))),\n )\n }\n\n if (handlers.length === 0) {\n return NOOP\n }\n\n return (item: ComboboxItem<T>) => {\n // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう\n // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする\n requestAnimationFrame(() => {\n handlers.forEach((h) => h(item))\n })\n }\n }, [selectedItems, onChangeSelected, onDelete])\n const actualOnSelect = useCallback(\n (selected: ComboboxItem<T>) => {\n // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう\n // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする\n requestAnimationFrame(() => {\n const matchedSelectedItem = selectedItems.find((item) => areItemsEqual(item, selected))\n\n if (matchedSelectedItem === undefined) {\n onSelect?.(selected)\n onChangeSelected?.(selectedItems.concat(selected))\n\n // 制御コンポーネントの場合に親側でinputValueを更新できるように、選択時にonChangeInputを空文字で発火する\n onChangeInput?.(EMPTY_INPUT_CHANGE_EVENT)\n } else if (matchedSelectedItem.deletable !== false) {\n actualOnDelete(selected)\n }\n })\n },\n [selectedItems, actualOnDelete, onChangeSelected, onSelect, onChangeInput],\n )\n\n const { renderListBox, activeOption, onKeyDownListBox, listBoxId, listBoxRef } = useListbox({\n options,\n dropdownHelpMessage,\n dropdownWidth,\n onAdd,\n onSelect: actualOnSelect,\n isExpanded: isFocused,\n isLoading,\n triggerRef: outerRef,\n noResultText,\n })\n\n const {\n deletionButtonRefs,\n inputRef,\n focusPrevDeletionButton,\n focusNextDeletionButton,\n resetDeletionButtonFocus,\n } = useFocusControl(selectedItems.length)\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(ref, () => inputRef.current)\n\n const focus = useMemo(() => {\n const baseAction = () => {\n setIsFocused(true)\n }\n\n if (onFocus) {\n return () => {\n onFocus()\n baseAction()\n }\n }\n\n return baseAction\n }, [onFocus])\n const blur = useMemo(() => {\n if (!isFocused) {\n return NOOP\n }\n\n const baseAction = () => {\n setIsFocused(false)\n resetDeletionButtonFocus()\n }\n\n if (onBlur) {\n return () => {\n onBlur()\n baseAction()\n }\n }\n\n return baseAction\n }, [isFocused, onBlur, resetDeletionButtonFocus])\n\n const outerClickRef = useMemo(() => [outerRef, listBoxRef], [outerRef, listBoxRef])\n useOuterClick(outerClickRef, blur)\n\n const highlightedRef = useRef(highlighted)\n\n useEffect(() => {\n highlightedRef.current = highlighted\n }, [highlighted])\n\n useEffect(() => {\n if (highlightedRef.current) {\n setHighlighted(false)\n inputRef.current?.select()\n } else {\n setInputValueIfUncontrolled('')\n }\n }, [selectedItems, inputRef, setInputValueIfUncontrolled])\n\n useEffect(() => {\n if (isFocused) {\n inputRef.current?.focus()\n }\n }, [inputRef, isFocused, setInputValueIfUncontrolled, selectedItems])\n\n const onDelegateKeyDown = useMemo(\n () =>\n isComposing\n ? undefined\n : (e: KeyboardEvent<HTMLDivElement>) => {\n if (ESCAPE_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n blur()\n } else if (e.key === 'Tab') {\n if (isFocused) {\n // フォーカスがコンポーネントを抜けるように先に input をフォーカスしておく\n inputRef.current?.focus()\n }\n\n blur()\n } else if (ARROW_LEFT_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n focusPrevDeletionButton()\n } else if (ARROW_RIGHT_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n focusNextDeletionButton()\n } else if (\n e.key === 'Backspace' &&\n !inputValue &&\n selectedItems.length > 0 &&\n selectedItems[selectedItems.length - 1].deletable !== false\n ) {\n e.preventDefault()\n e.stopPropagation()\n\n const lastItem = selectedItems[selectedItems.length - 1]\n\n actualOnDelete(lastItem)\n setHighlighted(true)\n setInputValueIfUncontrolled(innerText(lastItem.label))\n } else {\n e.stopPropagation()\n inputRef.current?.focus()\n resetDeletionButtonFocus()\n }\n\n onKeyDownListBox(e)\n },\n [\n blur,\n focusNextDeletionButton,\n focusPrevDeletionButton,\n onKeyDownListBox,\n inputRef,\n isComposing,\n isFocused,\n resetDeletionButtonFocus,\n actualOnDelete,\n inputValue,\n selectedItems,\n setInputValueIfUncontrolled,\n ],\n )\n\n const onDelegateClick = useMemo(\n () =>\n disabled || isFocused\n ? undefined\n : (e: MouseEvent<HTMLElement>) => {\n if (!(e.target as HTMLElement).closest('.smarthr-ui-MultiCombobox-deleteButton')) {\n focus()\n }\n },\n [isFocused, disabled, focus],\n )\n const actualOnChangeInput = useMemo(() => {\n const handlers = [onChange, onChangeInput].filter((h) => !!h)\n const onSetValue = (e: ChangeEvent<HTMLInputElement>) => {\n setInputValueIfUncontrolled(e.currentTarget.value)\n }\n\n if (handlers.length === 0) {\n return onSetValue\n }\n\n return (e: ChangeEvent<HTMLInputElement>) => {\n handlers.forEach((h) => h(e))\n onSetValue(e)\n }\n }, [onChange, onChangeInput, setInputValueIfUncontrolled])\n const onFocusInput = useMemo(\n () =>\n isFocused\n ? resetDeletionButtonFocus\n : () => {\n resetDeletionButtonFocus()\n focus()\n },\n [isFocused, focus, resetDeletionButtonFocus],\n )\n const onCompositionStartInput = useCallback(() => setIsComposing(true), [])\n const onCompositionEndInput = useCallback(() => setIsComposing(false), [])\n const onKeyDownInput = useCallback((e: KeyboardEvent<HTMLInputElement>) => {\n if (ARROW_UP_AND_DOWN_KEY_REGEX.test(e.key)) {\n // 上下キー入力はリストボックスの activeDescendant の移動に用いるため、input 内では作用させない\n e.preventDefault()\n }\n }, [])\n\n // HINT: form内にcomboboxを設置 & 検索inputにfocusした状態で\n // アイテムをキーボードで選択し、Enterを押すとinput上でEnterを押したことになるため、\n // submitイベントが発生し、formが送信される場合がある\n const onDelegateKeyPress = useMemo(\n () =>\n onKeyPress\n ? (e: KeyboardEvent<HTMLInputElement>) => {\n preventDefaultWithPressEnter(e)\n onKeyPress(e)\n }\n : preventDefaultWithPressEnter,\n [onKeyPress],\n )\n\n const selectedListId = useId()\n\n const wrapperStyle = useMemo(\n () => ({\n ...style,\n width: typeof width === 'number' ? `${width}px` : width,\n }),\n [style, width],\n )\n const classNames = useMemo(() => {\n const {\n wrapper,\n inputArea,\n selectedList,\n inputWrapper,\n input,\n placeholderEl,\n suffixWrapper,\n suffixIcon,\n } = classNameGenerator()\n\n return {\n wrapper: wrapper({ focused: isFocused, disabled, className }),\n inputArea: inputArea(),\n selectedList: selectedList(),\n inputWrapper: inputWrapper({ hidden: !isFocused }),\n input: input(),\n placeholder: placeholderEl(),\n suffixWrapper: suffixWrapper({ disabled }),\n suffixIcon: suffixIcon(),\n }\n }, [isFocused, disabled, className])\n\n const selectedListAriaLabel = useMemo(\n () =>\n localize({\n id: 'smarthr-ui/MultiCombobox/selectedListAriaLabel',\n defaultText: '選択済みアイテム',\n }),\n [localize],\n )\n\n return (\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions\n <div\n ref={outerRef}\n role=\"group\"\n onClick={onDelegateClick}\n onKeyDown={onDelegateKeyDown}\n onKeyPress={onDelegateKeyPress}\n className={classNames.wrapper}\n style={wrapperStyle}\n >\n <Scroller className={classNames.inputArea}>\n <ul\n id={selectedListId}\n aria-label={selectedListAriaLabel}\n className={classNames.selectedList}\n >\n {selectedItems.map((selectedItem, i) => (\n <li key={`${selectedItem.label}-${innerText(selectedItem.value)}`}>\n <MultiSelectedItem\n item={selectedItem}\n disabled={disabled}\n onDelete={actualOnDelete}\n enableEllipsis={selectedItemEllipsis}\n buttonRef={deletionButtonRefs[i]}\n />\n </li>\n ))}\n </ul>\n\n <div className={classNames.inputWrapper}>\n <input\n {...rest}\n data-smarthr-ui-input=\"true\"\n type=\"text\"\n name={name}\n value={inputValue}\n disabled={disabled}\n required={required && selectedItems.length === 0}\n ref={inputRef}\n onChange={actualOnChangeInput}\n onFocus={onFocusInput}\n onCompositionStart={onCompositionStartInput}\n onCompositionEnd={onCompositionEndInput}\n onKeyDown={onKeyDownInput}\n autoComplete={autoComplete ?? 'off'}\n tabIndex={0}\n role=\"combobox\"\n aria-activedescendant={activeOption?.id}\n aria-controls={`${listBoxId} ${selectedListId}`}\n aria-haspopup=\"listbox\"\n aria-expanded={isFocused}\n aria-invalid={error || undefined}\n aria-disabled={disabled}\n aria-autocomplete=\"list\"\n className={classNames.input}\n />\n </div>\n\n {selectedItems.length === 0 && placeholder && !isFocused && (\n <p className={classNames.placeholder}>{placeholder}</p>\n )}\n </Scroller>\n\n <MemoizedCaretDown\n disabled={disabled}\n isFocused={isFocused}\n className={classNames.suffixWrapper}\n iconStyle={classNames.suffixIcon}\n />\n\n {renderListBox()}\n </div>\n )\n}\n\nexport const MultiCombobox = genericsForwardRef(ActualMultiCombobox)\n\nconst MemoizedCaretDown = memo<{\n className: string\n iconStyle: string\n disabled: boolean\n isFocused: boolean\n}>(({ className, iconStyle, disabled, isFocused }) => {\n const theme = useTheme()\n const caretIconColor = useMemo(() => {\n if (isFocused) return theme.textColor.black\n if (disabled) return theme.textColor.disabled\n\n return theme.textColor.grey\n }, [disabled, isFocused, theme.textColor])\n\n return (\n <div className={className}>\n <FaCaretDownIcon color={caretIconColor} className={iconStyle} />\n </div>\n )\n})\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA8EA;AAEA;AACE;;;AAGF;AAEA;AACA;AACA;AACA;AAEA;AACE;AACA;;AAGF;AACE;AACE;;;;;AAKC;AACD;AACA;AAEA;AACA;;;;AAIC;AACD;AACA;;;AAGC;AACD;AACD;AACD;AACE;AACE;AACE;AACD;AACF;AACD;AACE;AACE;AAED;AACD;AACE;AACD;AACF;AACD;AACE;AACE;AACD;AACF;AACF;AACD;AACE;AACE;AACA;AACE;AACD;AACF;AACF;AACF;AAED;AAkCE;AACA;;;AAGA;;;;AAIA;;AAEE;;;;AAID;;AAED;;;AAII;;;AAGA;;AAKF;AACE;;;;;;AAOE;AACF;AACF;;AAEF;;;;AAKM;AAEA;AACE;;;AAIA;;AACK;;;AAGT;AACF;AAIF;;;;;AAKE;AACA;;AAEA;;AAED;AAED;;AAUA;;;AAGE;;AAGE;AACE;AACA;AACF;;AAGF;AACF;AACA;;AAEI;;;;AAKA;AACF;;AAGE;AACE;AACA;AACF;;AAGF;;AAGF;AACA;AAEA;;AAGE;AACF;;AAGE;;AAEE;;;;;;;;AAQA;;;AAIJ;AAGM;AACA;;;AAGM;;AACK;;;AAGH;;AAGF;;;;AAGA;;;;AAGA;;AACK;AAEL;;AAEA;;;;;;;;;;AAYA;AACA;;;AAIJ;;;;;;;;;;;;;AAcL;;AAMG;AACA;;AAEM;;;AAKZ;AACE;AACA;AACE;AACF;AAEA;AACE;;;AAIA;;AAEF;;AAEF;AAGM;;AAEI;AACA;;AAIV;AACA;AACA;;;;;;;;;AAUA;AAGM;;;;AAIA;AAIN;AAEA;AAEI;AACA;AACD;AAGH;;;AAaI;;;;;;AAMA;;;;;AAQE;AACA;AACD;;;AAMH;AAwEJ;;AAIA;AAME;AACA;AACE;AAAe;AACf;AAAc;AAEd;;AAGF;AAKF;;"}
1
+ {"version":3,"file":"MultiCombobox.js","sources":["../../../../src/components/Combobox/MultiCombobox/MultiCombobox.tsx"],"sourcesContent":["'use client'\n\nimport {\n type ChangeEvent,\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n memo,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport { useId } from 'react'\nimport innerText from 'react-innertext'\nimport { tv } from 'tailwind-variants'\n\nimport { useOuterClick } from '../../../hooks/useOuterClick'\nimport { useTheme } from '../../../hooks/useTheme'\nimport { useIntl } from '../../../intl'\nimport { genericsForwardRef } from '../../../libs/util'\nimport { FaCaretDownIcon } from '../../Icon'\nimport { Scroller } from '../../Scroller'\nimport { areItemsEqual } from '../helper'\nimport { useFocusControl } from '../useFocusControl'\nimport { useListbox } from '../useListbox'\nimport { useMultiOptions } from '../useOptions'\n\nimport { MultiSelectedItem } from './MultiSelectedItem'\n\nimport type { ComboboxItem, AbstractProps as ComboboxProps } from '../types'\n\ntype AbstractProps<T> = ComboboxProps<T> & {\n /**\n * 選択されているアイテムのリスト\n */\n selectedItems: Array<ComboboxItem<T> & { deletable?: boolean }>\n /**\n * 選択されているアイテムのラベルを省略表示するかどうか\n */\n selectedItemEllipsis?: boolean\n /**\n * テキストボックスの `value` 属性の値。\n * `onChangeInput` と併せて設定することで、テキストボックスの挙動が制御可能になる。\n */\n inputValue?: string\n /**\n * 選択されているアイテムの削除ボタンがクリックされた時に発火するコールバック関数\n */\n onDelete?: (item: ComboboxItem<T>) => void\n /**\n * 選択されているアイテムのリストが変わった時に発火するコールバック関数\n */\n onChangeSelected?: (selectedItems: Array<ComboboxItem<T>>) => void\n /**\n * コンポーネントがフォーカスされたときに発火するコールバック関数\n */\n onFocus?: () => void\n /**\n * コンポーネントからフォーカスが外れた時に発火するコールバック関数\n */\n onBlur?: () => void\n /**\n * アイテムが選択されたときに選択済みかどうかを判定するコールバック関数/\n */\n isItemSelected?: (targetItem: ComboboxItem<T>, selectedItems: Array<ComboboxItem<T>>) => boolean\n /**\n * 検索結果が0件の時に表示するコンテンツ\n */\n noResultText?: ReactNode\n}\ntype Props<T> = AbstractProps<T> &\n Omit<ComponentPropsWithoutRef<'input'>, keyof AbstractProps<unknown>>\n\nconst NOOP = () => undefined\n\nconst preventDefaultWithPressEnter = (e: KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n }\n}\n\nconst ESCAPE_KEY_REGEX = /^Esc(ape)?$/\nconst ARROW_LEFT_KEY_REGEX = /^(Arrow)?Left$/\nconst ARROW_RIGHT_KEY_REGEX = /^(Arrow)?Right/\nconst ARROW_UP_AND_DOWN_KEY_REGEX = /^(Arrow)?(Up|Down)$/\n\nconst EMPTY_INPUT_CHANGE_EVENT = {\n currentTarget: { value: '' },\n target: { value: '' },\n} as ChangeEvent<HTMLInputElement>\n\nconst classNameGenerator = tv({\n slots: {\n wrapper: [\n 'smarthr-ui-MultiCombobox',\n 'shr-box-border shr-inline-flex shr-min-w-[15em] shr-rounded-m shr-border shr-border-solid shr-px-0.5 shr-py-0.25 shr-align-bottom',\n 'contrast-more:shr-border-high-contrast',\n 'has-[[aria-invalid]]:shr-border-danger',\n ],\n inputArea: 'shr-flex shr-flex-1 shr-flex-wrap shr-gap-0.5',\n selectedList:\n 'smarthr-ui-MultiCombobox-selectedList shr-contents shr-list-none [&_li]:shr-min-w-0',\n inputWrapper: 'shr-flex shr-flex-1 shr-items-center',\n input: [\n 'smarthr-ui-MultiCombobox-input',\n 'shr-w-full shr-min-w-[5em] shr-border-none shr-text-base shr-text-black shr-outline-none shr-outline-0',\n 'disabled:shr-hidden',\n ],\n placeholderEl: 'smarthr-ui-MultiCombobox-placeholder shr-my-0 shr-self-center',\n suffixWrapper: [\n 'shr-relative -shr-me-0.5 shr-ms-0.5 shr-p-0.5',\n 'before:shr-absolute before:shr-inset-x-0 before:shr-inset-y-0.25 before:shr-w-0 before:shr-border-0 before:shr-border-l before:shr-border-solid before:shr-border-default before:shr-content-[\"\"]',\n ],\n suffixIcon: 'shr-block',\n },\n variants: {\n focused: {\n true: {\n wrapper: 'shr-focus-indicator',\n },\n },\n disabled: {\n true: {\n wrapper:\n 'shr-cursor-not-allowed shr-border-default/50 shr-bg-white-darken shr-text-disabled',\n },\n false: {\n wrapper: 'shr-cursor-text shr-bg-white',\n },\n },\n hidden: {\n true: {\n inputWrapper: 'shr-pointer-events-none shr-absolute shr-opacity-0',\n },\n },\n },\n compoundVariants: [\n {\n disabled: false,\n className: {\n wrapper: 'shr-border-default',\n },\n },\n ],\n})\n\nconst ActualMultiCombobox = <T,>(\n {\n items,\n selectedItems,\n name,\n disabled = false,\n required = false,\n error = false,\n creatable = false,\n placeholder = '',\n autoComplete,\n dropdownHelpMessage,\n isLoading,\n selectedItemEllipsis,\n width,\n dropdownWidth = 'auto',\n inputValue: controlledInputValue,\n className,\n onChange,\n onChangeInput,\n onAdd,\n onDelete,\n onSelect,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n isItemSelected,\n noResultText,\n style,\n ...rest\n }: Props<T>,\n ref: Ref<HTMLInputElement>,\n) => {\n const { localize } = useIntl()\n const outerRef = useRef<HTMLDivElement>(null)\n const [isFocused, setIsFocused] = useState(false)\n const [highlighted, setHighlighted] = useState(false)\n const isInputControlled = controlledInputValue !== undefined\n const [uncontrolledInputValue, setUncontrolledInputValue] = useState('')\n const inputValue = isInputControlled ? controlledInputValue : uncontrolledInputValue\n const [isComposing, setIsComposing] = useState(false)\n\n const unstableRef = useRef({\n onChange,\n onChangeInput,\n onAdd,\n onSelect,\n onDelete,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n isItemSelected,\n selectedItems,\n isFocused,\n highlighted,\n isComposing,\n })\n unstableRef.current = {\n onChange,\n onChangeInput,\n onAdd,\n onSelect,\n onDelete,\n onChangeSelected,\n onFocus,\n onBlur,\n onKeyPress,\n isItemSelected,\n selectedItems,\n isFocused,\n highlighted,\n isComposing,\n }\n const { options } = useMultiOptions({\n items,\n selected: selectedItems,\n creatable,\n inputValue,\n isItemSelected,\n })\n const setInputValueIfUncontrolled = isInputControlled ? NOOP : setUncontrolledInputValue\n const actualOnDelete = useCallback((item: ComboboxItem<T>) => {\n const handlers: Array<(deletingItem: ComboboxItem<T>) => void> = []\n\n if (unstableRef.current.onDelete) {\n handlers.push((deletingItem: ComboboxItem<T>) => unstableRef.current.onDelete!(deletingItem))\n }\n if (unstableRef.current.onChangeSelected) {\n handlers.push((deletingItem: ComboboxItem<T>) =>\n unstableRef.current.onChangeSelected!(\n unstableRef.current.selectedItems.filter(\n (selected) => !areItemsEqual(selected, deletingItem),\n ),\n ),\n )\n }\n\n if (handlers.length > 0) {\n // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう\n // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする\n requestAnimationFrame(() => {\n handlers.forEach((h) => h(item))\n })\n }\n }, [])\n const actualOnSelect = useCallback(\n (selected: ComboboxItem<T>) => {\n // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう\n // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする\n requestAnimationFrame(() => {\n const matchedSelectedItem = unstableRef.current.selectedItems.find((item) =>\n areItemsEqual(item, selected),\n )\n\n if (matchedSelectedItem === undefined) {\n unstableRef.current.onSelect?.(selected)\n unstableRef.current.onChangeSelected?.(unstableRef.current.selectedItems.concat(selected))\n\n // 制御コンポーネントの場合に親側でinputValueを更新できるように、選択時にonChangeInputを空文字で発火する\n unstableRef.current.onChangeInput?.(EMPTY_INPUT_CHANGE_EVENT)\n } else if (matchedSelectedItem.deletable !== false) {\n actualOnDelete(selected)\n }\n })\n },\n [actualOnDelete],\n )\n\n const { renderListBox, activeOption, onKeyDownListBox, listBoxId, listBoxRef } = useListbox({\n options,\n dropdownHelpMessage,\n dropdownWidth,\n onAdd,\n onSelect: actualOnSelect,\n isExpanded: isFocused,\n isLoading,\n triggerRef: outerRef,\n noResultText,\n })\n\n const {\n deletionButtonRefs,\n inputRef,\n focusPrevDeletionButton,\n focusNextDeletionButton,\n resetDeletionButtonFocus,\n } = useFocusControl(selectedItems.length)\n\n useImperativeHandle<HTMLInputElement | null, HTMLInputElement | null>(ref, () => inputRef.current)\n\n const focus = useCallback(() => {\n unstableRef.current.onFocus?.()\n setIsFocused(true)\n }, [])\n\n const blur = useCallback(() => {\n if (unstableRef.current.isFocused) {\n unstableRef.current.onBlur?.()\n setIsFocused(false)\n resetDeletionButtonFocus()\n }\n }, [resetDeletionButtonFocus])\n\n const outerClickRef = useMemo(() => [outerRef, listBoxRef], [listBoxRef])\n useOuterClick(outerClickRef, blur)\n\n useEffect(() => {\n if (unstableRef.current.highlighted) {\n setHighlighted(false)\n inputRef.current?.select()\n } else {\n setInputValueIfUncontrolled('')\n }\n }, [selectedItems, setInputValueIfUncontrolled, inputRef])\n\n useEffect(() => {\n if (isFocused) {\n inputRef.current?.focus()\n }\n }, [isFocused, setInputValueIfUncontrolled, selectedItems, inputRef])\n\n const isInputEmpty = !inputValue\n\n const onDelegateKeyDown = (e: KeyboardEvent<HTMLDivElement>) => {\n if (unstableRef.current.isComposing) return\n\n if (ESCAPE_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n blur()\n } else if (e.key === 'Tab') {\n if (unstableRef.current.isFocused) {\n // フォーカスがコンポーネントを抜けるように先に input をフォーカスしておく\n inputRef.current?.focus()\n }\n\n blur()\n } else if (ARROW_LEFT_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n focusPrevDeletionButton()\n } else if (ARROW_RIGHT_KEY_REGEX.test(e.key)) {\n e.stopPropagation()\n focusNextDeletionButton()\n } else if (\n e.key === 'Backspace' &&\n isInputEmpty &&\n unstableRef.current.selectedItems.length > 0 &&\n unstableRef.current.selectedItems[unstableRef.current.selectedItems.length - 1].deletable !==\n false\n ) {\n e.preventDefault()\n e.stopPropagation()\n\n const lastItem =\n unstableRef.current.selectedItems[unstableRef.current.selectedItems.length - 1]\n\n actualOnDelete(lastItem)\n setHighlighted(true)\n setInputValueIfUncontrolled(innerText(lastItem.label))\n } else {\n e.stopPropagation()\n inputRef.current?.focus()\n resetDeletionButtonFocus()\n }\n\n onKeyDownListBox(e)\n }\n\n const onDelegateClick = useCallback(\n (e: MouseEvent<HTMLElement>) => {\n if (!disabled && !unstableRef.current.isFocused) {\n if (!(e.target as HTMLElement).closest('.smarthr-ui-MultiCombobox-deleteButton')) {\n focus()\n }\n }\n },\n [disabled, focus],\n )\n const actualOnChangeInput = useCallback(\n (e: ChangeEvent<HTMLInputElement>) => {\n const handlers = [unstableRef.current.onChange, unstableRef.current.onChangeInput].filter(\n (h) => !!h,\n )\n\n handlers.forEach((h) => h(e))\n setInputValueIfUncontrolled(e.currentTarget.value)\n },\n [setInputValueIfUncontrolled],\n )\n const onFocusInput = useCallback(() => {\n if (unstableRef.current.isFocused) {\n resetDeletionButtonFocus()\n } else {\n resetDeletionButtonFocus()\n focus()\n }\n }, [resetDeletionButtonFocus, focus])\n const onCompositionStartInput = useCallback(() => setIsComposing(true), [])\n const onCompositionEndInput = useCallback(() => setIsComposing(false), [])\n const onKeyDownInput = useCallback((e: KeyboardEvent<HTMLInputElement>) => {\n if (ARROW_UP_AND_DOWN_KEY_REGEX.test(e.key)) {\n // 上下キー入力はリストボックスの activeDescendant の移動に用いるため、input 内では作用させない\n e.preventDefault()\n }\n }, [])\n\n // HINT: form内にcomboboxを設置 & 検索inputにfocusした状態で\n // アイテムをキーボードで選択し、Enterを押すとinput上でEnterを押したことになるため、\n // submitイベントが発生し、formが送信される場合がある\n const onDelegateKeyPress = useCallback((e: KeyboardEvent<HTMLInputElement>) => {\n preventDefaultWithPressEnter(e)\n unstableRef.current.onKeyPress?.(e)\n }, [])\n\n const selectedListId = useId()\n\n const wrapperStyle = useMemo(\n () => ({\n ...style,\n width: typeof width === 'number' ? `${width}px` : width,\n }),\n [style, width],\n )\n const classNames = useMemo(() => {\n const {\n wrapper,\n inputArea,\n selectedList,\n inputWrapper,\n input,\n placeholderEl,\n suffixWrapper,\n suffixIcon,\n } = classNameGenerator()\n\n return {\n wrapper: wrapper({ focused: isFocused, disabled, className }),\n inputArea: inputArea(),\n selectedList: selectedList(),\n inputWrapper: inputWrapper({ hidden: !isFocused }),\n input: input(),\n placeholder: placeholderEl(),\n suffixWrapper: suffixWrapper({ disabled }),\n suffixIcon: suffixIcon(),\n }\n }, [isFocused, disabled, className])\n\n const selectedListAriaLabel = useMemo(\n () =>\n localize({\n id: 'smarthr-ui/MultiCombobox/selectedListAriaLabel',\n defaultText: '選択済みアイテム',\n }),\n [localize],\n )\n\n return (\n // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions\n <div\n ref={outerRef}\n role=\"group\"\n onClick={onDelegateClick}\n onKeyDown={onDelegateKeyDown}\n onKeyPress={onDelegateKeyPress}\n className={classNames.wrapper}\n style={wrapperStyle}\n >\n <Scroller className={classNames.inputArea}>\n <ul\n id={selectedListId}\n aria-label={selectedListAriaLabel}\n className={classNames.selectedList}\n >\n {selectedItems.map((selectedItem, i) => (\n <li key={`${selectedItem.label}-${innerText(selectedItem.value)}`}>\n <MultiSelectedItem\n item={selectedItem}\n disabled={disabled}\n onDelete={actualOnDelete}\n enableEllipsis={selectedItemEllipsis}\n buttonRef={deletionButtonRefs[i]}\n />\n </li>\n ))}\n </ul>\n\n <div className={classNames.inputWrapper}>\n <input\n {...rest}\n data-smarthr-ui-input=\"true\"\n type=\"text\"\n name={name}\n value={inputValue}\n disabled={disabled}\n required={required && selectedItems.length === 0}\n ref={inputRef}\n onChange={actualOnChangeInput}\n onFocus={onFocusInput}\n onCompositionStart={onCompositionStartInput}\n onCompositionEnd={onCompositionEndInput}\n onKeyDown={onKeyDownInput}\n autoComplete={autoComplete ?? 'off'}\n tabIndex={0}\n role=\"combobox\"\n aria-activedescendant={activeOption?.id}\n aria-controls={`${listBoxId} ${selectedListId}`}\n aria-haspopup=\"listbox\"\n aria-expanded={isFocused}\n aria-invalid={error || undefined}\n aria-disabled={disabled}\n aria-autocomplete=\"list\"\n className={classNames.input}\n />\n </div>\n\n {selectedItems.length === 0 && placeholder && !isFocused && (\n <p className={classNames.placeholder}>{placeholder}</p>\n )}\n </Scroller>\n\n <MemoizedCaretDown\n disabled={disabled}\n isFocused={isFocused}\n className={classNames.suffixWrapper}\n iconStyle={classNames.suffixIcon}\n />\n\n {renderListBox()}\n </div>\n )\n}\n\nexport const MultiCombobox = genericsForwardRef(ActualMultiCombobox)\n\nconst MemoizedCaretDown = memo<{\n className: string\n iconStyle: string\n disabled: boolean\n isFocused: boolean\n}>(({ className, iconStyle, disabled, isFocused }) => {\n const theme = useTheme()\n const caretIconColor = isFocused\n ? theme.textColor.black\n : disabled\n ? theme.textColor.disabled\n : theme.textColor.grey\n\n return (\n <div className={className}>\n <FaCaretDownIcon color={caretIconColor} className={iconStyle} />\n </div>\n )\n})\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA8EA;AAEA;AACE;;;AAGF;AAEA;AACA;AACA;AACA;AAEA;AACE;AACA;;AAGF;AACE;AACE;;;;;AAKC;AACD;AACA;AAEA;AACA;;;;AAIC;AACD;AACA;;;AAGC;AACD;AACD;AACD;AACE;AACE;AACE;AACD;AACF;AACD;AACE;AACE;AAED;AACD;AACE;AACD;AACF;AACD;AACE;AACE;AACD;AACF;AACF;AACD;AACE;AACE;AACA;AACE;AACD;AACF;AACF;AACF;AAED;AAkCE;AACA;;;AAGA;;;;;;;;;;;;;;;;;;;AAoBC;;;;;;;;;;;;;;;;;AAiBD;;AAEE;;;;AAID;;AAED;;AAGE;AACE;;AAEF;AACE;;AASF;;;;AAII;AACF;;;AAGJ;;;;;AASM;;AAEE;;;;AAIK;;;AAGT;AACF;AAIF;;;;;AAKE;AACA;;AAEA;;AAED;AAED;;AAUA;AACE;;;AAIF;AACE;AACE;;AAEA;;AAEJ;AAEA;AACA;;AAGE;;AAEE;;;;;;;;AAQA;;;AAIJ;AAEA;AACE;;;;AAIE;;AACK;AACL;;AAEE;;AAGF;;;;AAGA;;;;AAGA;;AACK;;AAGL;AACA;AACE;;;AAKF;;;;;;;AAQA;AACA;;;AAIJ;AAEA;;;AAIQ;;;AAGN;AAGF;;AAMI;AACA;AACF;AAGF;AACE;AACE;;;AAEA;AACA;;AAEJ;AACA;AACA;AACA;;;;;;;;;AAUA;;;;AAKA;AAEA;AAEI;AACA;AACD;AAGH;;;AAaI;;;;;;AAMA;;;;;AAQE;AACA;AACD;;;AAMH;AAwEJ;;AAIA;AAME;;AAEE;AACA;AACE;AACA;AAEJ;AAKF;;"}
@@ -5,7 +5,7 @@ var React = require('react');
5
5
  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');
6
6
  require('../../../intl/IntlProvider.cjs');
7
7
  var intl_useIntl = require('../../../intl/useIntl.cjs');
8
- require('react-intl');
8
+ require('../../../intl/Localizer.cjs');
9
9
  require('../../../_virtual/dayjs.min.cjs');
10
10
  require('../../../intl/TimeFormatter.cjs');
11
11
  require('../../Button/Button.cjs');
@@ -3,7 +3,7 @@ import { memo, useRef, useEffect, useCallback, useMemo, useState, useId } from '
3
3
  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';
4
4
  import '../../../intl/IntlProvider.js';
5
5
  import { useIntl } from '../../../intl/useIntl.js';
6
- import 'react-intl';
6
+ import '../../../intl/Localizer.js';
7
7
  import '../../../_virtual/dayjs.min.js';
8
8
  import '../../../intl/TimeFormatter.js';
9
9
  import '../../Button/Button.js';