smarthr-ui 97.0.0 → 98.1.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 (293) 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/ItemButton.cjs +27 -26
  46. package/lib/components/Combobox/ItemButton.cjs.map +1 -1
  47. package/lib/components/Combobox/ItemButton.js +28 -27
  48. package/lib/components/Combobox/ItemButton.js.map +1 -1
  49. package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs +122 -134
  50. package/lib/components/Combobox/MultiCombobox/MultiCombobox.cjs.map +1 -1
  51. package/lib/components/Combobox/MultiCombobox/MultiCombobox.js +123 -135
  52. package/lib/components/Combobox/MultiCombobox/MultiCombobox.js.map +1 -1
  53. package/lib/components/Combobox/MultiCombobox/MultiSelectedItem.cjs +1 -1
  54. package/lib/components/Combobox/MultiCombobox/MultiSelectedItem.js +1 -1
  55. package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs +79 -46
  56. package/lib/components/Combobox/SingleCombobox/SingleCombobox.cjs.map +1 -1
  57. package/lib/components/Combobox/SingleCombobox/SingleCombobox.js +81 -48
  58. package/lib/components/Combobox/SingleCombobox/SingleCombobox.js.map +1 -1
  59. package/lib/components/Combobox/useListbox.cjs +1 -1
  60. package/lib/components/Combobox/useListbox.js +1 -1
  61. package/lib/components/Combobox/useOptions.cjs +3 -1
  62. package/lib/components/Combobox/useOptions.cjs.map +1 -1
  63. package/lib/components/Combobox/useOptions.js +4 -2
  64. package/lib/components/Combobox/useOptions.js.map +1 -1
  65. package/lib/components/Dialog/ControlledActionDialog/ActionDialogContentInner.cjs +3 -3
  66. package/lib/components/Dialog/ControlledActionDialog/ActionDialogContentInner.cjs.map +1 -1
  67. package/lib/components/Dialog/ControlledActionDialog/ActionDialogContentInner.js +3 -3
  68. package/lib/components/Dialog/ControlledActionDialog/ActionDialogContentInner.js.map +1 -1
  69. package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.cjs +3 -3
  70. package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.cjs.map +1 -1
  71. package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.js +3 -3
  72. package/lib/components/Dialog/ControlledFormDialog/FormDialogContentInner.js.map +1 -1
  73. package/lib/components/Dialog/ControlledMessageDialog/MessageDialogContentInner.cjs +1 -1
  74. package/lib/components/Dialog/ControlledMessageDialog/MessageDialogContentInner.js +1 -1
  75. package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.cjs +1 -1
  76. package/lib/components/Dialog/ControlledStepFormDialog/ControlledStepFormDialog.js +1 -1
  77. package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.cjs +2 -2
  78. package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.cjs.map +1 -1
  79. package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.js +2 -2
  80. package/lib/components/Dialog/ControlledStepFormDialog/StepFormDialogContentInner.js.map +1 -1
  81. package/lib/components/Dialog/DialogContentResponseStatusMessage.cjs +3 -8
  82. package/lib/components/Dialog/DialogContentResponseStatusMessage.cjs.map +1 -1
  83. package/lib/components/Dialog/DialogContentResponseStatusMessage.d.ts +1 -1
  84. package/lib/components/Dialog/DialogContentResponseStatusMessage.js +3 -8
  85. package/lib/components/Dialog/DialogContentResponseStatusMessage.js.map +1 -1
  86. package/lib/components/Dialog/FocusTrap.cjs +4 -1
  87. package/lib/components/Dialog/FocusTrap.cjs.map +1 -1
  88. package/lib/components/Dialog/FocusTrap.js +4 -1
  89. package/lib/components/Dialog/FocusTrap.js.map +1 -1
  90. package/lib/components/Dialog/ModelessDialog/ModelessDialog.cjs +1 -1
  91. package/lib/components/Dialog/ModelessDialog/ModelessDialog.js +1 -1
  92. package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.cjs +9 -3
  93. package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.cjs.map +1 -1
  94. package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.js +9 -3
  95. package/lib/components/Dialog/RemoteDialogTrigger/RemoteDialogTrigger.js.map +1 -1
  96. package/lib/components/Disclosure/DisclosureTrigger.cjs +8 -4
  97. package/lib/components/Disclosure/DisclosureTrigger.cjs.map +1 -1
  98. package/lib/components/Disclosure/DisclosureTrigger.js +8 -4
  99. package/lib/components/Disclosure/DisclosureTrigger.js.map +1 -1
  100. package/lib/components/DropZone/DropZone.cjs +1 -1
  101. package/lib/components/DropZone/DropZone.js +1 -1
  102. package/lib/components/Dropdown/Dropdown.cjs +36 -34
  103. package/lib/components/Dropdown/Dropdown.cjs.map +1 -1
  104. package/lib/components/Dropdown/Dropdown.js +37 -35
  105. package/lib/components/Dropdown/Dropdown.js.map +1 -1
  106. package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.cjs +1 -1
  107. package/lib/components/Dropdown/DropdownMenuButton/DropdownMenuButton.js +1 -1
  108. package/lib/components/Dropdown/FilterDropdown/FilterDropdown.cjs +3 -5
  109. package/lib/components/Dropdown/FilterDropdown/FilterDropdown.cjs.map +1 -1
  110. package/lib/components/Dropdown/FilterDropdown/FilterDropdown.d.ts +1 -1
  111. package/lib/components/Dropdown/FilterDropdown/FilterDropdown.js +3 -5
  112. package/lib/components/Dropdown/FilterDropdown/FilterDropdown.js.map +1 -1
  113. package/lib/components/Dropdown/SortDropdown/useSortDropdown.cjs +1 -1
  114. package/lib/components/Dropdown/SortDropdown/useSortDropdown.js +1 -1
  115. package/lib/components/ErrorScreen/AuthErrorScreen.cjs +1 -1
  116. package/lib/components/ErrorScreen/AuthErrorScreen.js +1 -1
  117. package/lib/components/ErrorScreen/ForbiddenErrorScreen.cjs +1 -1
  118. package/lib/components/ErrorScreen/ForbiddenErrorScreen.js +1 -1
  119. package/lib/components/ErrorScreen/NotFoundErrorScreen.cjs +1 -1
  120. package/lib/components/ErrorScreen/NotFoundErrorScreen.js +1 -1
  121. package/lib/components/ErrorScreen/UnauthorizedErrorScreen.cjs +1 -1
  122. package/lib/components/ErrorScreen/UnauthorizedErrorScreen.js +1 -1
  123. package/lib/components/FileViewer/FileViewer.cjs +35 -2
  124. package/lib/components/FileViewer/FileViewer.cjs.map +1 -1
  125. package/lib/components/FileViewer/FileViewer.js +37 -4
  126. package/lib/components/FileViewer/FileViewer.js.map +1 -1
  127. package/lib/components/FileViewer/PDFViewer.cjs +59 -2
  128. package/lib/components/FileViewer/PDFViewer.cjs.map +1 -1
  129. package/lib/components/FileViewer/PDFViewer.d.ts +6 -1
  130. package/lib/components/FileViewer/PDFViewer.js +60 -3
  131. package/lib/components/FileViewer/PDFViewer.js.map +1 -1
  132. package/lib/components/FileViewer/SearchController.cjs +105 -0
  133. package/lib/components/FileViewer/SearchController.cjs.map +1 -0
  134. package/lib/components/FileViewer/SearchController.d.ts +7 -0
  135. package/lib/components/FileViewer/SearchController.js +103 -0
  136. package/lib/components/FileViewer/SearchController.js.map +1 -0
  137. package/lib/components/FileViewer/buildCustomTextRenderer.cjs +55 -0
  138. package/lib/components/FileViewer/buildCustomTextRenderer.cjs.map +1 -0
  139. package/lib/components/FileViewer/buildCustomTextRenderer.d.ts +9 -0
  140. package/lib/components/FileViewer/buildCustomTextRenderer.js +50 -0
  141. package/lib/components/FileViewer/buildCustomTextRenderer.js.map +1 -0
  142. package/lib/components/FileViewer/types.d.ts +7 -0
  143. package/lib/components/FileViewer/usePDFSearch.cjs +148 -0
  144. package/lib/components/FileViewer/usePDFSearch.cjs.map +1 -0
  145. package/lib/components/FileViewer/usePDFSearch.d.ts +19 -0
  146. package/lib/components/FileViewer/usePDFSearch.js +143 -0
  147. package/lib/components/FileViewer/usePDFSearch.js.map +1 -0
  148. package/lib/components/FormControl/FormControl.cjs +2 -22
  149. package/lib/components/FormControl/FormControl.cjs.map +1 -1
  150. package/lib/components/FormControl/FormControl.js +2 -22
  151. package/lib/components/FormControl/FormControl.js.map +1 -1
  152. package/lib/components/Header/AppLauncher/AppLauncher.cjs +1 -1
  153. package/lib/components/Header/AppLauncher/AppLauncher.js +1 -1
  154. package/lib/components/Header/LanguageSwitcher/LanguageSwitcher.cjs +1 -1
  155. package/lib/components/Header/LanguageSwitcher/LanguageSwitcher.js +1 -1
  156. package/lib/components/Icon/FaIcon.js +1 -1
  157. package/lib/components/Icon/OpenInNewTabIcon.cjs +1 -1
  158. package/lib/components/Icon/OpenInNewTabIcon.js +1 -1
  159. package/lib/components/InformationPanel/InformationPanel.cjs +1 -1
  160. package/lib/components/InformationPanel/InformationPanel.js +1 -1
  161. package/lib/components/Input/SearchInput/SearchInputIcon.cjs +1 -1
  162. package/lib/components/Input/SearchInput/SearchInputIcon.js +1 -1
  163. package/lib/components/InputFile/InputFileMultiplyAppendable.cjs +1 -1
  164. package/lib/components/InputFile/InputFileMultiplyAppendable.js +1 -1
  165. package/lib/components/InputFile/InputFileNative.cjs +1 -1
  166. package/lib/components/InputFile/InputFileNative.js +1 -1
  167. package/lib/components/Layout/Cluster/Cluster.cjs +0 -1
  168. package/lib/components/Layout/Cluster/Cluster.cjs.map +1 -1
  169. package/lib/components/Layout/Cluster/Cluster.js +0 -1
  170. package/lib/components/Layout/Cluster/Cluster.js.map +1 -1
  171. package/lib/components/Layout/Container/Container.cjs +1 -5
  172. package/lib/components/Layout/Container/Container.cjs.map +1 -1
  173. package/lib/components/Layout/Container/Container.js +1 -5
  174. package/lib/components/Layout/Container/Container.js.map +1 -1
  175. package/lib/components/Layout/Stack/Stack.cjs +22 -22
  176. package/lib/components/Layout/Stack/Stack.cjs.map +1 -1
  177. package/lib/components/Layout/Stack/Stack.js +22 -22
  178. package/lib/components/Layout/Stack/Stack.js.map +1 -1
  179. package/lib/components/Loader/LoaderSpinner.cjs +1 -1
  180. package/lib/components/Loader/LoaderSpinner.js +1 -1
  181. package/lib/components/Pagination/Pagination.cjs +1 -1
  182. package/lib/components/Pagination/Pagination.js +1 -1
  183. package/lib/components/Pagination/PaginationItemButton.cjs +1 -1
  184. package/lib/components/Pagination/PaginationItemButton.js +1 -1
  185. package/lib/components/SideNav/SideNav.cjs +3 -22
  186. package/lib/components/SideNav/SideNav.cjs.map +1 -1
  187. package/lib/components/SideNav/SideNav.d.ts +2 -9
  188. package/lib/components/SideNav/SideNav.js +4 -23
  189. package/lib/components/SideNav/SideNav.js.map +1 -1
  190. package/lib/components/SideNav/SideNavContext.cjs +11 -0
  191. package/lib/components/SideNav/SideNavContext.cjs.map +1 -0
  192. package/lib/components/SideNav/SideNavContext.d.ts +7 -0
  193. package/lib/components/SideNav/SideNavContext.js +8 -0
  194. package/lib/components/SideNav/SideNavContext.js.map +1 -0
  195. package/lib/components/SideNav/SideNavItemButton.cjs +12 -7
  196. package/lib/components/SideNav/SideNavItemButton.cjs.map +1 -1
  197. package/lib/components/SideNav/SideNavItemButton.d.ts +5 -11
  198. package/lib/components/SideNav/SideNavItemButton.js +12 -7
  199. package/lib/components/SideNav/SideNavItemButton.js.map +1 -1
  200. package/lib/components/Table/Th.cjs +2 -2
  201. package/lib/components/Table/Th.cjs.map +1 -1
  202. package/lib/components/Table/Th.d.ts +0 -2
  203. package/lib/components/Table/Th.js +2 -2
  204. package/lib/components/Table/Th.js.map +1 -1
  205. package/lib/components/Table/ThCheckbox.cjs +1 -1
  206. package/lib/components/Table/ThCheckbox.js +1 -1
  207. package/lib/components/Table/ThSortButton.cjs +5 -6
  208. package/lib/components/Table/ThSortButton.cjs.map +1 -1
  209. package/lib/components/Table/ThSortButton.d.ts +1 -6
  210. package/lib/components/Table/ThSortButton.js +5 -6
  211. package/lib/components/Table/ThSortButton.js.map +1 -1
  212. package/lib/components/WarekiPicker/WarekiPicker.cjs +1 -1
  213. package/lib/components/WarekiPicker/WarekiPicker.js +1 -1
  214. package/lib/hooks/useLatest.cjs +33 -0
  215. package/lib/hooks/useLatest.cjs.map +1 -0
  216. package/lib/hooks/useLatest.d.ts +19 -0
  217. package/lib/hooks/useLatest.js +31 -0
  218. package/lib/hooks/useLatest.js.map +1 -0
  219. package/lib/index.cjs +1 -6
  220. package/lib/index.cjs.map +1 -1
  221. package/lib/index.d.ts +0 -1
  222. package/lib/index.js +1 -4
  223. package/lib/index.js.map +1 -1
  224. package/lib/intl/Localizer.cjs +5 -1
  225. package/lib/intl/Localizer.cjs.map +1 -1
  226. package/lib/intl/Localizer.d.ts +1 -1
  227. package/lib/intl/Localizer.js +5 -1
  228. package/lib/intl/Localizer.js.map +1 -1
  229. package/lib/intl/locales/en_us.json.cjs +3 -0
  230. package/lib/intl/locales/en_us.json.cjs.map +1 -1
  231. package/lib/intl/locales/en_us.json.js +3 -0
  232. package/lib/intl/locales/en_us.json.js.map +1 -1
  233. package/lib/intl/locales/id_id.json.cjs +3 -0
  234. package/lib/intl/locales/id_id.json.cjs.map +1 -1
  235. package/lib/intl/locales/id_id.json.js +3 -0
  236. package/lib/intl/locales/id_id.json.js.map +1 -1
  237. package/lib/intl/locales/index.d.ts +27 -0
  238. package/lib/intl/locales/ja.cjs +3 -0
  239. package/lib/intl/locales/ja.cjs.map +1 -1
  240. package/lib/intl/locales/ja.d.ts +3 -0
  241. package/lib/intl/locales/ja.js +3 -0
  242. package/lib/intl/locales/ja.js.map +1 -1
  243. package/lib/intl/locales/ja.json.cjs +3 -0
  244. package/lib/intl/locales/ja.json.cjs.map +1 -1
  245. package/lib/intl/locales/ja.json.js +3 -0
  246. package/lib/intl/locales/ja.json.js.map +1 -1
  247. package/lib/intl/locales/ja_easy.json.cjs +3 -0
  248. package/lib/intl/locales/ja_easy.json.cjs.map +1 -1
  249. package/lib/intl/locales/ja_easy.json.js +3 -0
  250. package/lib/intl/locales/ja_easy.json.js.map +1 -1
  251. package/lib/intl/locales/ko_kr.json.cjs +3 -0
  252. package/lib/intl/locales/ko_kr.json.cjs.map +1 -1
  253. package/lib/intl/locales/ko_kr.json.js +3 -0
  254. package/lib/intl/locales/ko_kr.json.js.map +1 -1
  255. package/lib/intl/locales/pt_br.json.cjs +3 -0
  256. package/lib/intl/locales/pt_br.json.cjs.map +1 -1
  257. package/lib/intl/locales/pt_br.json.js +3 -0
  258. package/lib/intl/locales/pt_br.json.js.map +1 -1
  259. package/lib/intl/locales/vi_vn.json.cjs +3 -0
  260. package/lib/intl/locales/vi_vn.json.cjs.map +1 -1
  261. package/lib/intl/locales/vi_vn.json.js +3 -0
  262. package/lib/intl/locales/vi_vn.json.js.map +1 -1
  263. package/lib/intl/locales/zh_hans_cn.json.cjs +3 -0
  264. package/lib/intl/locales/zh_hans_cn.json.cjs.map +1 -1
  265. package/lib/intl/locales/zh_hans_cn.json.js +3 -0
  266. package/lib/intl/locales/zh_hans_cn.json.js.map +1 -1
  267. package/lib/intl/locales/zh_hant_tw.json.cjs +3 -0
  268. package/lib/intl/locales/zh_hant_tw.json.cjs.map +1 -1
  269. package/lib/intl/locales/zh_hant_tw.json.js +3 -0
  270. package/lib/intl/locales/zh_hant_tw.json.js.map +1 -1
  271. package/metadata.json +1 -1
  272. package/package.json +1 -1
  273. package/smarthr-ui.css +35 -98
  274. package/lib/hooks/useDecorators.cjs +0 -18
  275. package/lib/hooks/useDecorators.cjs.map +0 -1
  276. package/lib/hooks/useDecorators.d.ts +0 -6
  277. package/lib/hooks/useDecorators.js +0 -16
  278. package/lib/hooks/useDecorators.js.map +0 -1
  279. package/lib/hooks/useDevice/DeviceProvider.cjs +0 -37
  280. package/lib/hooks/useDevice/DeviceProvider.cjs.map +0 -1
  281. package/lib/hooks/useDevice/DeviceProvider.d.ts +0 -4
  282. package/lib/hooks/useDevice/DeviceProvider.js +0 -35
  283. package/lib/hooks/useDevice/DeviceProvider.js.map +0 -1
  284. package/lib/hooks/useDevice/index.cjs +0 -10
  285. package/lib/hooks/useDevice/index.cjs.map +0 -1
  286. package/lib/hooks/useDevice/index.d.ts +0 -2
  287. package/lib/hooks/useDevice/index.js +0 -3
  288. package/lib/hooks/useDevice/index.js.map +0 -1
  289. package/lib/hooks/useDevice/useDevice.cjs +0 -11
  290. package/lib/hooks/useDevice/useDevice.cjs.map +0 -1
  291. package/lib/hooks/useDevice/useDevice.d.ts +0 -4
  292. package/lib/hooks/useDevice/useDevice.js +0 -8
  293. package/lib/hooks/useDevice/useDevice.js.map +0 -1
@@ -9,7 +9,7 @@ var hooks_useOuterClick = require('../../../hooks/useOuterClick.cjs');
9
9
  var hooks_useTheme = require('../../../hooks/useTheme.cjs');
10
10
  require('../../../intl/IntlProvider.cjs');
11
11
  var intl_useIntl = require('../../../intl/useIntl.cjs');
12
- require('react-intl');
12
+ require('../../../intl/Localizer.cjs');
13
13
  require('../../../_virtual/dayjs.min.cjs');
14
14
  require('../../../intl/TimeFormatter.cjs');
15
15
  var libs_util = require('../../../libs/util.cjs');
@@ -98,6 +98,38 @@ const ActualMultiCombobox = ({ items, selectedItems, name, disabled = false, req
98
98
  const [uncontrolledInputValue, setUncontrolledInputValue] = React.useState('');
99
99
  const inputValue = isInputControlled ? controlledInputValue : uncontrolledInputValue;
100
100
  const [isComposing, setIsComposing] = React.useState(false);
101
+ const unstableRef = React.useRef({
102
+ onChange,
103
+ onChangeInput,
104
+ onAdd,
105
+ onSelect,
106
+ onDelete,
107
+ onChangeSelected,
108
+ onFocus,
109
+ onBlur,
110
+ onKeyPress,
111
+ isItemSelected,
112
+ selectedItems,
113
+ isFocused,
114
+ highlighted,
115
+ isComposing,
116
+ });
117
+ unstableRef.current = {
118
+ onChange,
119
+ onChangeInput,
120
+ onAdd,
121
+ onSelect,
122
+ onDelete,
123
+ onChangeSelected,
124
+ onFocus,
125
+ onBlur,
126
+ onKeyPress,
127
+ isItemSelected,
128
+ selectedItems,
129
+ isFocused,
130
+ highlighted,
131
+ isComposing,
132
+ };
101
133
  const { options } = components_Combobox_useOptions.useMultiOptions({
102
134
  items,
103
135
  selected: selectedItems,
@@ -106,41 +138,38 @@ const ActualMultiCombobox = ({ items, selectedItems, name, disabled = false, req
106
138
  isItemSelected,
107
139
  });
108
140
  const setInputValueIfUncontrolled = isInputControlled ? NOOP : setUncontrolledInputValue;
109
- const actualOnDelete = React.useMemo(() => {
141
+ const actualOnDelete = React.useCallback((item) => {
110
142
  const handlers = [];
111
- if (onDelete) {
112
- handlers.push((item) => onDelete(item));
113
- }
114
- if (onChangeSelected) {
115
- handlers.push((item) => onChangeSelected(selectedItems.filter((selected) => !components_Combobox_helper.areItemsEqual(selected, item))));
143
+ if (unstableRef.current.onDelete) {
144
+ handlers.push((deletingItem) => unstableRef.current.onDelete(deletingItem));
116
145
  }
117
- if (handlers.length === 0) {
118
- return NOOP;
146
+ if (unstableRef.current.onChangeSelected) {
147
+ handlers.push((deletingItem) => unstableRef.current.onChangeSelected(unstableRef.current.selectedItems.filter((selected) => !components_Combobox_helper.areItemsEqual(selected, deletingItem))));
119
148
  }
120
- return (item) => {
149
+ if (handlers.length > 0) {
121
150
  // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう
122
151
  // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする
123
152
  requestAnimationFrame(() => {
124
153
  handlers.forEach((h) => h(item));
125
154
  });
126
- };
127
- }, [selectedItems, onChangeSelected, onDelete]);
155
+ }
156
+ }, []);
128
157
  const actualOnSelect = React.useCallback((selected) => {
129
158
  // HINT: Dropdown系コンポーネント内でComboboxを使うと、選択肢がportalで表現されている関係上Dropdownが閉じてしまう
130
159
  // requestAnimationFrameを追加、処理を遅延させることで正常に閉じる/閉じないの判定を行えるようにする
131
160
  requestAnimationFrame(() => {
132
- const matchedSelectedItem = selectedItems.find((item) => components_Combobox_helper.areItemsEqual(item, selected));
161
+ const matchedSelectedItem = unstableRef.current.selectedItems.find((item) => components_Combobox_helper.areItemsEqual(item, selected));
133
162
  if (matchedSelectedItem === undefined) {
134
- onSelect?.(selected);
135
- onChangeSelected?.(selectedItems.concat(selected));
163
+ unstableRef.current.onSelect?.(selected);
164
+ unstableRef.current.onChangeSelected?.(unstableRef.current.selectedItems.concat(selected));
136
165
  // 制御コンポーネントの場合に親側でinputValueを更新できるように、選択時にonChangeInputを空文字で発火する
137
- onChangeInput?.(EMPTY_INPUT_CHANGE_EVENT);
166
+ unstableRef.current.onChangeInput?.(EMPTY_INPUT_CHANGE_EVENT);
138
167
  }
139
168
  else if (matchedSelectedItem.deletable !== false) {
140
169
  actualOnDelete(selected);
141
170
  }
142
171
  });
143
- }, [selectedItems, actualOnDelete, onChangeSelected, onSelect, onChangeInput]);
172
+ }, [actualOnDelete]);
144
173
  const { renderListBox, activeOption, onKeyDownListBox, listBoxId, listBoxRef } = components_Combobox_useListbox.useListbox({
145
174
  options,
146
175
  dropdownHelpMessage,
@@ -154,133 +183,96 @@ const ActualMultiCombobox = ({ items, selectedItems, name, disabled = false, req
154
183
  });
155
184
  const { deletionButtonRefs, inputRef, focusPrevDeletionButton, focusNextDeletionButton, resetDeletionButtonFocus, } = components_Combobox_useFocusControl.useFocusControl(selectedItems.length);
156
185
  React.useImperativeHandle(ref, () => inputRef.current);
157
- const focus = React.useMemo(() => {
158
- const baseAction = () => {
159
- setIsFocused(true);
160
- };
161
- if (onFocus) {
162
- return () => {
163
- onFocus();
164
- baseAction();
165
- };
166
- }
167
- return baseAction;
168
- }, [onFocus]);
169
- const blur = React.useMemo(() => {
170
- if (!isFocused) {
171
- return NOOP;
172
- }
173
- const baseAction = () => {
186
+ const focus = React.useCallback(() => {
187
+ unstableRef.current.onFocus?.();
188
+ setIsFocused(true);
189
+ }, []);
190
+ const blur = React.useCallback(() => {
191
+ if (unstableRef.current.isFocused) {
192
+ unstableRef.current.onBlur?.();
174
193
  setIsFocused(false);
175
194
  resetDeletionButtonFocus();
176
- };
177
- if (onBlur) {
178
- return () => {
179
- onBlur();
180
- baseAction();
181
- };
182
195
  }
183
- return baseAction;
184
- }, [isFocused, onBlur, resetDeletionButtonFocus]);
185
- const outerClickRef = React.useMemo(() => [outerRef, listBoxRef], [outerRef, listBoxRef]);
196
+ }, [resetDeletionButtonFocus]);
197
+ const outerClickRef = React.useMemo(() => [outerRef, listBoxRef], [listBoxRef]);
186
198
  hooks_useOuterClick.useOuterClick(outerClickRef, blur);
187
- const highlightedRef = React.useRef(highlighted);
188
- React.useEffect(() => {
189
- highlightedRef.current = highlighted;
190
- }, [highlighted]);
191
199
  React.useEffect(() => {
192
- if (highlightedRef.current) {
200
+ if (unstableRef.current.highlighted) {
193
201
  setHighlighted(false);
194
202
  inputRef.current?.select();
195
203
  }
196
204
  else {
197
205
  setInputValueIfUncontrolled('');
198
206
  }
199
- }, [selectedItems, inputRef, setInputValueIfUncontrolled]);
207
+ }, [selectedItems, setInputValueIfUncontrolled, inputRef]);
200
208
  React.useEffect(() => {
201
209
  if (isFocused) {
202
210
  inputRef.current?.focus();
203
211
  }
204
- }, [inputRef, isFocused, setInputValueIfUncontrolled, selectedItems]);
205
- const onDelegateKeyDown = React.useMemo(() => isComposing
206
- ? undefined
207
- : (e) => {
208
- if (ESCAPE_KEY_REGEX.test(e.key)) {
209
- e.stopPropagation();
210
- blur();
211
- }
212
- else if (e.key === 'Tab') {
213
- if (isFocused) {
214
- // フォーカスがコンポーネントを抜けるように先に input をフォーカスしておく
215
- inputRef.current?.focus();
216
- }
217
- blur();
218
- }
219
- else if (ARROW_LEFT_KEY_REGEX.test(e.key)) {
220
- e.stopPropagation();
221
- focusPrevDeletionButton();
222
- }
223
- else if (ARROW_RIGHT_KEY_REGEX.test(e.key)) {
224
- e.stopPropagation();
225
- focusNextDeletionButton();
226
- }
227
- else if (e.key === 'Backspace' &&
228
- !inputValue &&
229
- selectedItems.length > 0 &&
230
- selectedItems[selectedItems.length - 1].deletable !== false) {
231
- e.preventDefault();
232
- e.stopPropagation();
233
- const lastItem = selectedItems[selectedItems.length - 1];
234
- actualOnDelete(lastItem);
235
- setHighlighted(true);
236
- setInputValueIfUncontrolled(index$1(lastItem.label));
237
- }
238
- else {
239
- e.stopPropagation();
212
+ }, [isFocused, setInputValueIfUncontrolled, selectedItems, inputRef]);
213
+ const isInputEmpty = !inputValue;
214
+ const onDelegateKeyDown = (e) => {
215
+ if (unstableRef.current.isComposing)
216
+ return;
217
+ if (ESCAPE_KEY_REGEX.test(e.key)) {
218
+ e.stopPropagation();
219
+ blur();
220
+ }
221
+ else if (e.key === 'Tab') {
222
+ if (unstableRef.current.isFocused) {
223
+ // フォーカスがコンポーネントを抜けるように先に input をフォーカスしておく
240
224
  inputRef.current?.focus();
241
- resetDeletionButtonFocus();
242
225
  }
243
- onKeyDownListBox(e);
244
- }, [
245
- blur,
246
- focusNextDeletionButton,
247
- focusPrevDeletionButton,
248
- onKeyDownListBox,
249
- inputRef,
250
- isComposing,
251
- isFocused,
252
- resetDeletionButtonFocus,
253
- actualOnDelete,
254
- inputValue,
255
- selectedItems,
256
- setInputValueIfUncontrolled,
257
- ]);
258
- const onDelegateClick = React.useMemo(() => disabled || isFocused
259
- ? undefined
260
- : (e) => {
226
+ blur();
227
+ }
228
+ else if (ARROW_LEFT_KEY_REGEX.test(e.key)) {
229
+ e.stopPropagation();
230
+ focusPrevDeletionButton();
231
+ }
232
+ else if (ARROW_RIGHT_KEY_REGEX.test(e.key)) {
233
+ e.stopPropagation();
234
+ focusNextDeletionButton();
235
+ }
236
+ else if (e.key === 'Backspace' &&
237
+ isInputEmpty &&
238
+ unstableRef.current.selectedItems.length > 0 &&
239
+ unstableRef.current.selectedItems[unstableRef.current.selectedItems.length - 1].deletable !==
240
+ false) {
241
+ e.preventDefault();
242
+ e.stopPropagation();
243
+ const lastItem = unstableRef.current.selectedItems[unstableRef.current.selectedItems.length - 1];
244
+ actualOnDelete(lastItem);
245
+ setHighlighted(true);
246
+ setInputValueIfUncontrolled(index$1(lastItem.label));
247
+ }
248
+ else {
249
+ e.stopPropagation();
250
+ inputRef.current?.focus();
251
+ resetDeletionButtonFocus();
252
+ }
253
+ onKeyDownListBox(e);
254
+ };
255
+ const onDelegateClick = React.useCallback((e) => {
256
+ if (!disabled && !unstableRef.current.isFocused) {
261
257
  if (!e.target.closest('.smarthr-ui-MultiCombobox-deleteButton')) {
262
258
  focus();
263
259
  }
264
- }, [isFocused, disabled, focus]);
265
- const actualOnChangeInput = React.useMemo(() => {
266
- const handlers = [onChange, onChangeInput].filter((h) => !!h);
267
- const onSetValue = (e) => {
268
- setInputValueIfUncontrolled(e.currentTarget.value);
269
- };
270
- if (handlers.length === 0) {
271
- return onSetValue;
272
260
  }
273
- return (e) => {
274
- handlers.forEach((h) => h(e));
275
- onSetValue(e);
276
- };
277
- }, [onChange, onChangeInput, setInputValueIfUncontrolled]);
278
- const onFocusInput = React.useMemo(() => isFocused
279
- ? resetDeletionButtonFocus
280
- : () => {
261
+ }, [disabled, focus]);
262
+ const actualOnChangeInput = React.useCallback((e) => {
263
+ const handlers = [unstableRef.current.onChange, unstableRef.current.onChangeInput].filter((h) => !!h);
264
+ handlers.forEach((h) => h(e));
265
+ setInputValueIfUncontrolled(e.currentTarget.value);
266
+ }, [setInputValueIfUncontrolled]);
267
+ const onFocusInput = React.useCallback(() => {
268
+ if (unstableRef.current.isFocused) {
269
+ resetDeletionButtonFocus();
270
+ }
271
+ else {
281
272
  resetDeletionButtonFocus();
282
273
  focus();
283
- }, [isFocused, focus, resetDeletionButtonFocus]);
274
+ }
275
+ }, [resetDeletionButtonFocus, focus]);
284
276
  const onCompositionStartInput = React.useCallback(() => setIsComposing(true), []);
285
277
  const onCompositionEndInput = React.useCallback(() => setIsComposing(false), []);
286
278
  const onKeyDownInput = React.useCallback((e) => {
@@ -292,12 +284,10 @@ const ActualMultiCombobox = ({ items, selectedItems, name, disabled = false, req
292
284
  // HINT: form内にcomboboxを設置 & 検索inputにfocusした状態で
293
285
  // アイテムをキーボードで選択し、Enterを押すとinput上でEnterを押したことになるため、
294
286
  // submitイベントが発生し、formが送信される場合がある
295
- const onDelegateKeyPress = React.useMemo(() => onKeyPress
296
- ? (e) => {
297
- preventDefaultWithPressEnter(e);
298
- onKeyPress(e);
299
- }
300
- : preventDefaultWithPressEnter, [onKeyPress]);
287
+ const onDelegateKeyPress = React.useCallback((e) => {
288
+ preventDefaultWithPressEnter(e);
289
+ unstableRef.current.onKeyPress?.(e);
290
+ }, []);
301
291
  const selectedListId = React.useId();
302
292
  const wrapperStyle = React.useMemo(() => ({
303
293
  ...style,
@@ -327,13 +317,11 @@ const ActualMultiCombobox = ({ items, selectedItems, name, disabled = false, req
327
317
  const MultiCombobox = libs_util.genericsForwardRef(ActualMultiCombobox);
328
318
  const MemoizedCaretDown = React.memo(({ className, iconStyle, disabled, isFocused }) => {
329
319
  const theme = hooks_useTheme.useTheme();
330
- const caretIconColor = React.useMemo(() => {
331
- if (isFocused)
332
- return theme.textColor.black;
333
- if (disabled)
334
- return theme.textColor.disabled;
335
- return theme.textColor.grey;
336
- }, [disabled, isFocused, theme.textColor]);
320
+ const caretIconColor = isFocused
321
+ ? theme.textColor.black
322
+ : disabled
323
+ ? theme.textColor.disabled
324
+ : theme.textColor.grey;
337
325
  return (jsxRuntime.jsx("div", { className: className, children: jsxRuntime.jsx(components_Icon_FaIcon.FaCaretDownIcon, { color: caretIconColor, className: iconStyle }) }));
338
326
  });
339
327
 
@@ -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;;"}