@patternfly/react-core 5.0.0-alpha.106 → 5.0.0-alpha.108

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 (328) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/esm/components/AboutModal/package.json +1 -1
  3. package/dist/esm/components/Accordion/package.json +1 -1
  4. package/dist/esm/components/ActionList/package.json +1 -1
  5. package/dist/esm/components/Alert/package.json +1 -1
  6. package/dist/esm/components/Avatar/package.json +1 -1
  7. package/dist/esm/components/BackToTop/package.json +1 -1
  8. package/dist/esm/components/Backdrop/package.json +1 -1
  9. package/dist/esm/components/BackgroundImage/package.json +1 -1
  10. package/dist/esm/components/Badge/package.json +1 -1
  11. package/dist/esm/components/Banner/package.json +1 -1
  12. package/dist/esm/components/Brand/package.json +1 -1
  13. package/dist/esm/components/Breadcrumb/package.json +1 -1
  14. package/dist/esm/components/Button/package.json +1 -1
  15. package/dist/esm/components/CalendarMonth/package.json +1 -1
  16. package/dist/esm/components/Card/package.json +1 -1
  17. package/dist/esm/components/Checkbox/package.json +1 -1
  18. package/dist/esm/components/Chip/package.json +1 -1
  19. package/dist/esm/components/ClipboardCopy/package.json +1 -1
  20. package/dist/esm/components/CodeBlock/package.json +1 -1
  21. package/dist/esm/components/DataList/package.json +1 -1
  22. package/dist/esm/components/DatePicker/package.json +1 -1
  23. package/dist/esm/components/DescriptionList/package.json +1 -1
  24. package/dist/esm/components/Divider/package.json +1 -1
  25. package/dist/esm/components/DragDrop/package.json +1 -1
  26. package/dist/esm/components/Drawer/package.json +1 -1
  27. package/dist/esm/components/Dropdown/Dropdown.d.ts +11 -3
  28. package/dist/esm/components/Dropdown/Dropdown.d.ts.map +1 -1
  29. package/dist/esm/components/Dropdown/Dropdown.js +11 -5
  30. package/dist/esm/components/Dropdown/Dropdown.js.map +1 -1
  31. package/dist/esm/components/Dropdown/package.json +1 -1
  32. package/dist/esm/components/DualListSelector/package.json +1 -1
  33. package/dist/esm/components/EmptyState/package.json +1 -1
  34. package/dist/esm/components/ExpandableSection/package.json +1 -1
  35. package/dist/esm/components/FileUpload/package.json +1 -1
  36. package/dist/esm/components/Form/package.json +1 -1
  37. package/dist/esm/components/FormSelect/package.json +1 -1
  38. package/dist/esm/components/HelperText/package.json +1 -1
  39. package/dist/esm/components/Hint/package.json +1 -1
  40. package/dist/esm/components/Icon/package.json +1 -1
  41. package/dist/esm/components/InputGroup/package.json +1 -1
  42. package/dist/esm/components/JumpLinks/package.json +1 -1
  43. package/dist/esm/components/Label/package.json +1 -1
  44. package/dist/esm/components/List/package.json +1 -1
  45. package/dist/esm/components/LoginPage/package.json +1 -1
  46. package/dist/esm/components/Masthead/package.json +1 -1
  47. package/dist/esm/components/Menu/MenuItem.d.ts +1 -1
  48. package/dist/esm/components/Menu/MenuItem.d.ts.map +1 -1
  49. package/dist/esm/components/Menu/package.json +1 -1
  50. package/dist/esm/components/MenuToggle/package.json +1 -1
  51. package/dist/esm/components/Modal/package.json +1 -1
  52. package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatusItem.d.ts +1 -1
  53. package/dist/esm/components/MultipleFileUpload/MultipleFileUploadStatusItem.d.ts.map +1 -1
  54. package/dist/esm/components/MultipleFileUpload/package.json +1 -1
  55. package/dist/esm/components/Nav/package.json +1 -1
  56. package/dist/esm/components/NotificationBadge/package.json +1 -1
  57. package/dist/esm/components/NotificationDrawer/package.json +1 -1
  58. package/dist/esm/components/NumberInput/package.json +1 -1
  59. package/dist/esm/components/OverflowMenu/package.json +1 -1
  60. package/dist/esm/components/Page/package.json +1 -1
  61. package/dist/esm/components/Pagination/package.json +1 -1
  62. package/dist/esm/components/Panel/package.json +1 -1
  63. package/dist/esm/components/Popover/package.json +1 -1
  64. package/dist/esm/components/Progress/Progress.d.ts +1 -1
  65. package/dist/esm/components/Progress/ProgressContainer.d.ts +1 -1
  66. package/dist/esm/components/Progress/package.json +1 -1
  67. package/dist/esm/components/ProgressStepper/package.json +1 -1
  68. package/dist/esm/components/Radio/package.json +1 -1
  69. package/dist/esm/components/SearchInput/package.json +1 -1
  70. package/dist/esm/components/Select/Select.d.ts +31 -5
  71. package/dist/esm/components/Select/Select.d.ts.map +1 -1
  72. package/dist/esm/components/Select/Select.js +16 -10
  73. package/dist/esm/components/Select/Select.js.map +1 -1
  74. package/dist/esm/components/Select/SelectGroup.d.ts +3 -0
  75. package/dist/esm/components/Select/SelectGroup.d.ts.map +1 -1
  76. package/dist/esm/components/Select/SelectGroup.js.map +1 -1
  77. package/dist/esm/components/Select/SelectOption.d.ts +14 -1
  78. package/dist/esm/components/Select/SelectOption.d.ts.map +1 -1
  79. package/dist/esm/components/Select/SelectOption.js +4 -3
  80. package/dist/esm/components/Select/SelectOption.js.map +1 -1
  81. package/dist/esm/components/Select/package.json +1 -1
  82. package/dist/esm/components/Sidebar/package.json +1 -1
  83. package/dist/esm/components/SimpleList/package.json +1 -1
  84. package/dist/esm/components/Skeleton/package.json +1 -1
  85. package/dist/esm/components/SkipToContent/package.json +1 -1
  86. package/dist/esm/components/Slider/package.json +1 -1
  87. package/dist/esm/components/Spinner/package.json +1 -1
  88. package/dist/esm/components/Switch/package.json +1 -1
  89. package/dist/esm/components/Tabs/Tab.d.ts +3 -3
  90. package/dist/esm/components/Tabs/Tab.d.ts.map +1 -1
  91. package/dist/esm/components/Tabs/Tabs.d.ts +1 -1
  92. package/dist/esm/components/Tabs/Tabs.d.ts.map +1 -1
  93. package/dist/esm/components/Tabs/package.json +1 -1
  94. package/dist/esm/components/Text/package.json +1 -1
  95. package/dist/esm/components/TextArea/package.json +1 -1
  96. package/dist/esm/components/TextInput/package.json +1 -1
  97. package/dist/esm/components/TextInputGroup/package.json +1 -1
  98. package/dist/esm/components/Tile/package.json +1 -1
  99. package/dist/esm/components/TimePicker/package.json +1 -1
  100. package/dist/esm/components/Timestamp/package.json +1 -1
  101. package/dist/esm/components/Title/package.json +1 -1
  102. package/dist/esm/components/ToggleGroup/package.json +1 -1
  103. package/dist/esm/components/Toolbar/package.json +1 -1
  104. package/dist/esm/components/Tooltip/package.json +1 -1
  105. package/dist/esm/components/TreeView/package.json +1 -1
  106. package/dist/esm/components/Truncate/package.json +1 -1
  107. package/dist/esm/components/Wizard/hooks/package.json +1 -1
  108. package/dist/esm/components/Wizard/package.json +1 -1
  109. package/dist/esm/components/package.json +1 -1
  110. package/dist/esm/deprecated/components/ApplicationLauncher/package.json +1 -1
  111. package/dist/esm/deprecated/components/ContextSelector/package.json +1 -1
  112. package/dist/esm/deprecated/components/Dropdown/DropdownToggleCheckbox.d.ts +3 -3
  113. package/dist/esm/deprecated/components/Dropdown/DropdownToggleCheckbox.d.ts.map +1 -1
  114. package/dist/esm/deprecated/components/Dropdown/package.json +1 -1
  115. package/dist/esm/deprecated/components/OptionsMenu/package.json +1 -1
  116. package/dist/esm/deprecated/components/PageHeader/package.json +1 -1
  117. package/dist/esm/deprecated/components/Select/package.json +1 -1
  118. package/dist/esm/deprecated/components/Wizard/package.json +1 -1
  119. package/dist/esm/deprecated/components/package.json +1 -1
  120. package/dist/esm/deprecated/package.json +1 -1
  121. package/dist/esm/helpers/Popper/Popper.d.ts +1 -1
  122. package/dist/esm/helpers/Popper/Popper.d.ts.map +1 -1
  123. package/dist/esm/helpers/Popper/thirdparty/popper-core/package.json +1 -1
  124. package/dist/esm/helpers/package.json +1 -1
  125. package/dist/esm/layouts/Bullseye/package.json +1 -1
  126. package/dist/esm/layouts/Flex/Flex.d.ts +27 -0
  127. package/dist/esm/layouts/Flex/Flex.d.ts.map +1 -1
  128. package/dist/esm/layouts/Flex/Flex.js +2 -2
  129. package/dist/esm/layouts/Flex/Flex.js.map +1 -1
  130. package/dist/esm/layouts/Flex/package.json +1 -1
  131. package/dist/esm/layouts/Gallery/package.json +1 -1
  132. package/dist/esm/layouts/Grid/package.json +1 -1
  133. package/dist/esm/layouts/Level/package.json +1 -1
  134. package/dist/esm/layouts/Split/package.json +1 -1
  135. package/dist/esm/layouts/Stack/package.json +1 -1
  136. package/dist/esm/layouts/package.json +1 -1
  137. package/dist/esm/next/components/package.json +1 -1
  138. package/dist/esm/next/package.json +1 -1
  139. package/dist/esm/package.json +1 -1
  140. package/dist/js/components/AboutModal/package.json +1 -1
  141. package/dist/js/components/Accordion/package.json +1 -1
  142. package/dist/js/components/ActionList/package.json +1 -1
  143. package/dist/js/components/Alert/package.json +1 -1
  144. package/dist/js/components/Avatar/package.json +1 -1
  145. package/dist/js/components/BackToTop/package.json +1 -1
  146. package/dist/js/components/Backdrop/package.json +1 -1
  147. package/dist/js/components/BackgroundImage/package.json +1 -1
  148. package/dist/js/components/Badge/package.json +1 -1
  149. package/dist/js/components/Banner/package.json +1 -1
  150. package/dist/js/components/Brand/package.json +1 -1
  151. package/dist/js/components/Breadcrumb/package.json +1 -1
  152. package/dist/js/components/Button/package.json +1 -1
  153. package/dist/js/components/CalendarMonth/package.json +1 -1
  154. package/dist/js/components/Card/package.json +1 -1
  155. package/dist/js/components/Checkbox/package.json +1 -1
  156. package/dist/js/components/Chip/package.json +1 -1
  157. package/dist/js/components/ClipboardCopy/package.json +1 -1
  158. package/dist/js/components/CodeBlock/package.json +1 -1
  159. package/dist/js/components/DataList/package.json +1 -1
  160. package/dist/js/components/DatePicker/package.json +1 -1
  161. package/dist/js/components/DescriptionList/package.json +1 -1
  162. package/dist/js/components/Divider/package.json +1 -1
  163. package/dist/js/components/DragDrop/package.json +1 -1
  164. package/dist/js/components/Drawer/package.json +1 -1
  165. package/dist/js/components/Dropdown/Dropdown.d.ts +11 -3
  166. package/dist/js/components/Dropdown/Dropdown.d.ts.map +1 -1
  167. package/dist/js/components/Dropdown/Dropdown.js +11 -5
  168. package/dist/js/components/Dropdown/Dropdown.js.map +1 -1
  169. package/dist/js/components/Dropdown/package.json +1 -1
  170. package/dist/js/components/DualListSelector/package.json +1 -1
  171. package/dist/js/components/EmptyState/package.json +1 -1
  172. package/dist/js/components/ExpandableSection/package.json +1 -1
  173. package/dist/js/components/FileUpload/package.json +1 -1
  174. package/dist/js/components/Form/package.json +1 -1
  175. package/dist/js/components/FormSelect/package.json +1 -1
  176. package/dist/js/components/HelperText/package.json +1 -1
  177. package/dist/js/components/Hint/package.json +1 -1
  178. package/dist/js/components/Icon/package.json +1 -1
  179. package/dist/js/components/InputGroup/package.json +1 -1
  180. package/dist/js/components/JumpLinks/package.json +1 -1
  181. package/dist/js/components/Label/package.json +1 -1
  182. package/dist/js/components/List/package.json +1 -1
  183. package/dist/js/components/LoginPage/package.json +1 -1
  184. package/dist/js/components/Masthead/package.json +1 -1
  185. package/dist/js/components/Menu/MenuItem.d.ts +1 -1
  186. package/dist/js/components/Menu/MenuItem.d.ts.map +1 -1
  187. package/dist/js/components/Menu/package.json +1 -1
  188. package/dist/js/components/MenuToggle/package.json +1 -1
  189. package/dist/js/components/Modal/package.json +1 -1
  190. package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatusItem.d.ts +1 -1
  191. package/dist/js/components/MultipleFileUpload/MultipleFileUploadStatusItem.d.ts.map +1 -1
  192. package/dist/js/components/MultipleFileUpload/package.json +1 -1
  193. package/dist/js/components/Nav/package.json +1 -1
  194. package/dist/js/components/NotificationBadge/package.json +1 -1
  195. package/dist/js/components/NotificationDrawer/package.json +1 -1
  196. package/dist/js/components/NumberInput/package.json +1 -1
  197. package/dist/js/components/OverflowMenu/package.json +1 -1
  198. package/dist/js/components/Page/package.json +1 -1
  199. package/dist/js/components/Pagination/package.json +1 -1
  200. package/dist/js/components/Panel/package.json +1 -1
  201. package/dist/js/components/Popover/package.json +1 -1
  202. package/dist/js/components/Progress/Progress.d.ts +1 -1
  203. package/dist/js/components/Progress/ProgressContainer.d.ts +1 -1
  204. package/dist/js/components/Progress/package.json +1 -1
  205. package/dist/js/components/ProgressStepper/package.json +1 -1
  206. package/dist/js/components/Radio/package.json +1 -1
  207. package/dist/js/components/SearchInput/package.json +1 -1
  208. package/dist/js/components/Select/Select.d.ts +31 -5
  209. package/dist/js/components/Select/Select.d.ts.map +1 -1
  210. package/dist/js/components/Select/Select.js +16 -10
  211. package/dist/js/components/Select/Select.js.map +1 -1
  212. package/dist/js/components/Select/SelectGroup.d.ts +3 -0
  213. package/dist/js/components/Select/SelectGroup.d.ts.map +1 -1
  214. package/dist/js/components/Select/SelectGroup.js.map +1 -1
  215. package/dist/js/components/Select/SelectOption.d.ts +14 -1
  216. package/dist/js/components/Select/SelectOption.d.ts.map +1 -1
  217. package/dist/js/components/Select/SelectOption.js +4 -4
  218. package/dist/js/components/Select/SelectOption.js.map +1 -1
  219. package/dist/js/components/Select/package.json +1 -1
  220. package/dist/js/components/Sidebar/package.json +1 -1
  221. package/dist/js/components/SimpleList/package.json +1 -1
  222. package/dist/js/components/Skeleton/package.json +1 -1
  223. package/dist/js/components/SkipToContent/package.json +1 -1
  224. package/dist/js/components/Slider/package.json +1 -1
  225. package/dist/js/components/Spinner/package.json +1 -1
  226. package/dist/js/components/Switch/package.json +1 -1
  227. package/dist/js/components/Tabs/Tab.d.ts +3 -3
  228. package/dist/js/components/Tabs/Tab.d.ts.map +1 -1
  229. package/dist/js/components/Tabs/Tabs.d.ts +1 -1
  230. package/dist/js/components/Tabs/Tabs.d.ts.map +1 -1
  231. package/dist/js/components/Tabs/package.json +1 -1
  232. package/dist/js/components/Text/package.json +1 -1
  233. package/dist/js/components/TextArea/package.json +1 -1
  234. package/dist/js/components/TextInput/package.json +1 -1
  235. package/dist/js/components/TextInputGroup/package.json +1 -1
  236. package/dist/js/components/Tile/package.json +1 -1
  237. package/dist/js/components/TimePicker/package.json +1 -1
  238. package/dist/js/components/Timestamp/package.json +1 -1
  239. package/dist/js/components/Title/package.json +1 -1
  240. package/dist/js/components/ToggleGroup/package.json +1 -1
  241. package/dist/js/components/Toolbar/package.json +1 -1
  242. package/dist/js/components/Tooltip/package.json +1 -1
  243. package/dist/js/components/TreeView/package.json +1 -1
  244. package/dist/js/components/Truncate/package.json +1 -1
  245. package/dist/js/components/Wizard/hooks/package.json +1 -1
  246. package/dist/js/components/Wizard/package.json +1 -1
  247. package/dist/js/components/package.json +1 -1
  248. package/dist/js/deprecated/components/ApplicationLauncher/package.json +1 -1
  249. package/dist/js/deprecated/components/ContextSelector/package.json +1 -1
  250. package/dist/js/deprecated/components/Dropdown/DropdownToggleCheckbox.d.ts +3 -3
  251. package/dist/js/deprecated/components/Dropdown/DropdownToggleCheckbox.d.ts.map +1 -1
  252. package/dist/js/deprecated/components/Dropdown/package.json +1 -1
  253. package/dist/js/deprecated/components/OptionsMenu/package.json +1 -1
  254. package/dist/js/deprecated/components/PageHeader/package.json +1 -1
  255. package/dist/js/deprecated/components/Select/package.json +1 -1
  256. package/dist/js/deprecated/components/Wizard/package.json +1 -1
  257. package/dist/js/deprecated/components/package.json +1 -1
  258. package/dist/js/deprecated/package.json +1 -1
  259. package/dist/js/helpers/Popper/Popper.d.ts +1 -1
  260. package/dist/js/helpers/Popper/Popper.d.ts.map +1 -1
  261. package/dist/js/helpers/Popper/thirdparty/popper-core/package.json +1 -1
  262. package/dist/js/helpers/package.json +1 -1
  263. package/dist/js/layouts/Bullseye/package.json +1 -1
  264. package/dist/js/layouts/Flex/Flex.d.ts +27 -0
  265. package/dist/js/layouts/Flex/Flex.d.ts.map +1 -1
  266. package/dist/js/layouts/Flex/Flex.js +2 -2
  267. package/dist/js/layouts/Flex/Flex.js.map +1 -1
  268. package/dist/js/layouts/Flex/package.json +1 -1
  269. package/dist/js/layouts/Gallery/package.json +1 -1
  270. package/dist/js/layouts/Grid/package.json +1 -1
  271. package/dist/js/layouts/Level/package.json +1 -1
  272. package/dist/js/layouts/Split/package.json +1 -1
  273. package/dist/js/layouts/Stack/package.json +1 -1
  274. package/dist/js/layouts/package.json +1 -1
  275. package/dist/js/next/components/package.json +1 -1
  276. package/dist/js/next/package.json +1 -1
  277. package/dist/js/package.json +1 -1
  278. package/dist/umd/react-core.min.js +2 -2
  279. package/package.json +2 -2
  280. package/src/components/DatePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap +27 -29
  281. package/src/components/DatePicker/examples/DatePicker.md +0 -1
  282. package/src/components/Dropdown/Dropdown.tsx +25 -11
  283. package/src/components/Dropdown/examples/Dropdown.md +10 -1
  284. package/src/components/Dropdown/examples/DropdownBasic.tsx +2 -6
  285. package/src/components/Dropdown/examples/DropdownWithDescriptions.tsx +2 -6
  286. package/src/components/Dropdown/examples/DropdownWithGroups.tsx +2 -6
  287. package/src/components/Dropdown/examples/DropdownWithKebabToggle.tsx +2 -6
  288. package/src/components/Icon/examples/Icon.md +0 -1
  289. package/src/components/Menu/MenuItem.tsx +1 -1
  290. package/src/components/Menu/examples/Menu.md +1 -1
  291. package/src/components/MultipleFileUpload/MultipleFileUploadStatusItem.tsx +1 -1
  292. package/src/components/Progress/Progress.tsx +1 -1
  293. package/src/components/Progress/ProgressContainer.tsx +1 -1
  294. package/src/components/Progress/examples/Progress.md +1 -1
  295. package/src/components/ProgressStepper/examples/ProgressStepper.md +0 -1
  296. package/src/components/SearchInput/examples/SearchInput.md +0 -1
  297. package/src/components/Select/Select.tsx +62 -24
  298. package/src/components/Select/SelectGroup.tsx +3 -0
  299. package/src/components/Select/SelectOption.tsx +22 -2
  300. package/src/components/Select/examples/Select.md +49 -2
  301. package/src/components/Select/examples/SelectBasic.tsx +27 -17
  302. package/src/components/Select/examples/SelectCheckbox.tsx +1 -3
  303. package/src/components/Select/examples/SelectFooter.tsx +57 -0
  304. package/src/components/Select/examples/SelectGrouped.tsx +14 -6
  305. package/src/components/Select/examples/SelectMultiTypeahead.tsx +7 -12
  306. package/src/components/Select/examples/SelectMultiTypeaheadCheckbox.tsx +204 -0
  307. package/src/components/Select/examples/SelectMultiTypeaheadCreatable.tsx +222 -0
  308. package/src/components/Select/examples/SelectOptionVariations.tsx +70 -0
  309. package/src/components/Select/examples/SelectTypeahead.tsx +13 -13
  310. package/src/components/Select/examples/SelectTypeaheadCreatable.tsx +220 -0
  311. package/src/components/Select/examples/SelectViewMore.tsx +146 -0
  312. package/src/components/Tabs/Tab.tsx +3 -3
  313. package/src/components/Tabs/Tabs.tsx +1 -1
  314. package/src/components/Tabs/examples/Tabs.md +3 -3
  315. package/src/components/TextInputGroup/examples/TextInputGroup.md +0 -1
  316. package/src/components/Tile/examples/Tile.md +0 -1
  317. package/src/components/Truncate/examples/Truncate.md +1 -2
  318. package/src/demos/ComposableMenu/ComposableMenu.md +17 -3
  319. package/src/demos/DatePicker/DatePicker.md +0 -1
  320. package/src/demos/ProgressStepperDemo.md +0 -1
  321. package/src/demos/SearchInput/SearchInput.md +0 -1
  322. package/src/demos/TextInputGroupDemo.md +0 -1
  323. package/src/deprecated/components/Dropdown/DropdownToggleCheckbox.tsx +3 -3
  324. package/src/deprecated/components/Dropdown/examples/Dropdown.md +1 -1
  325. package/src/helpers/Popper/Popper.tsx +1 -1
  326. package/src/layouts/Flex/Flex.tsx +141 -0
  327. package/src/layouts/Flex/__tests__/Flex.test.tsx +30 -10
  328. package/src/layouts/Flex/examples/Flex.md +192 -65
@@ -0,0 +1,222 @@
1
+ import React from 'react';
2
+ import {
3
+ Select,
4
+ SelectOption,
5
+ SelectList,
6
+ SelectOptionProps,
7
+ MenuToggle,
8
+ MenuToggleElement,
9
+ TextInputGroup,
10
+ TextInputGroupMain,
11
+ TextInputGroupUtilities,
12
+ ChipGroup,
13
+ Chip,
14
+ Button
15
+ } from '@patternfly/react-core';
16
+ import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
17
+
18
+ let initialSelectOptions: SelectOptionProps[] = [
19
+ { itemId: 'Alabama', children: 'Alabama' },
20
+ { itemId: 'Florida', children: 'Florida' },
21
+ { itemId: 'New Jersey', children: 'New Jersey' },
22
+ { itemId: 'New Mexico', children: 'New Mexico' },
23
+ { itemId: 'New York', children: 'New York' },
24
+ { itemId: 'North Carolina', children: 'North Carolina' }
25
+ ];
26
+
27
+ export const SelectMultiTypeaheadCreatable: React.FunctionComponent = () => {
28
+ const [isOpen, setIsOpen] = React.useState(false);
29
+ const [inputValue, setInputValue] = React.useState<string>('');
30
+ const [selected, setSelected] = React.useState<string[]>([]);
31
+ const [selectOptions, setSelectOptions] = React.useState<SelectOptionProps[]>(initialSelectOptions);
32
+ const [focusedItemIndex, setFocusedItemIndex] = React.useState<number | null>(null);
33
+ const [activeItem, setActiveItem] = React.useState<string | null>(null);
34
+ const [onCreation, setOnCreation] = React.useState<boolean>(false); // Boolean to refresh filter state after new option is created
35
+ const textInputRef = React.useRef<HTMLInputElement>();
36
+
37
+ React.useEffect(() => {
38
+ let newSelectOptions: SelectOptionProps[] = initialSelectOptions;
39
+
40
+ // Filter menu items based on the text input value when one exists
41
+ if (inputValue) {
42
+ newSelectOptions = initialSelectOptions.filter((menuItem) =>
43
+ String(menuItem.children).toLowerCase().includes(inputValue.toLowerCase())
44
+ );
45
+
46
+ // When no options are found after filtering, display creation option
47
+ if (!newSelectOptions.length) {
48
+ newSelectOptions = [{ isDisabled: false, children: `Create new option "${inputValue}"`, itemId: 'create' }];
49
+ }
50
+
51
+ // Open the menu when the input value changes and the new value is not empty
52
+ if (!isOpen) {
53
+ setIsOpen(true);
54
+ }
55
+ }
56
+
57
+ setSelectOptions(newSelectOptions);
58
+ setFocusedItemIndex(null);
59
+ setActiveItem(null);
60
+ }, [inputValue, onCreation]);
61
+
62
+ const handleMenuArrowKeys = (key: string) => {
63
+ let indexToFocus;
64
+
65
+ if (isOpen) {
66
+ if (key === 'ArrowUp') {
67
+ // When no index is set or at the first index, focus to the last, otherwise decrement focus index
68
+ if (focusedItemIndex === null || focusedItemIndex === 0) {
69
+ indexToFocus = selectOptions.length - 1;
70
+ } else {
71
+ indexToFocus = focusedItemIndex - 1;
72
+ }
73
+ }
74
+
75
+ if (key === 'ArrowDown') {
76
+ // When no index is set or at the last index, focus to the first, otherwise increment focus index
77
+ if (focusedItemIndex === null || focusedItemIndex === selectOptions.length - 1) {
78
+ indexToFocus = 0;
79
+ } else {
80
+ indexToFocus = focusedItemIndex + 1;
81
+ }
82
+ }
83
+
84
+ setFocusedItemIndex(indexToFocus);
85
+ const focusedItem = selectOptions.filter((option) => !option.isDisabled)[indexToFocus];
86
+ setActiveItem(`select-multi-create-typeahead-${focusedItem.itemId.replace(' ', '-')}`);
87
+ }
88
+ };
89
+
90
+ const onInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
91
+ const enabledMenuItems = selectOptions.filter((menuItem) => !menuItem.isDisabled);
92
+ const [firstMenuItem] = enabledMenuItems;
93
+ const focusedItem = focusedItemIndex ? enabledMenuItems[focusedItemIndex] : firstMenuItem;
94
+
95
+ switch (event.key) {
96
+ // Select the first available option
97
+ case 'Enter':
98
+ if (!isOpen) {
99
+ setIsOpen((prevIsOpen) => !prevIsOpen);
100
+ } else if (isOpen && focusedItem.itemId !== 'no results') {
101
+ onSelect(focusedItem.itemId as string);
102
+ }
103
+ break;
104
+ case 'Tab':
105
+ case 'Escape':
106
+ setIsOpen(false);
107
+ setActiveItem(null);
108
+ break;
109
+ case 'ArrowUp':
110
+ case 'ArrowDown':
111
+ event.preventDefault();
112
+ handleMenuArrowKeys(event.key);
113
+ break;
114
+ }
115
+ };
116
+
117
+ const onToggleClick = () => {
118
+ setIsOpen(!isOpen);
119
+ };
120
+
121
+ const onTextInputChange = (_event: React.FormEvent<HTMLInputElement>, value: string) => {
122
+ setInputValue(value);
123
+ };
124
+
125
+ const onSelect = (itemId: string) => {
126
+ if (itemId) {
127
+ if (itemId === 'create') {
128
+ if (!initialSelectOptions.some((item) => item.itemId === inputValue)) {
129
+ initialSelectOptions = [...initialSelectOptions, { itemId: inputValue, children: inputValue }];
130
+ }
131
+ setSelected(
132
+ selected.includes(inputValue)
133
+ ? selected.filter((selection) => selection !== inputValue)
134
+ : [...selected, inputValue]
135
+ );
136
+ setOnCreation(!onCreation);
137
+ } else {
138
+ // eslint-disable-next-line no-console
139
+ console.log('selected', itemId);
140
+ setSelected(
141
+ selected.includes(itemId) ? selected.filter((selection) => selection !== itemId) : [...selected, itemId]
142
+ );
143
+ }
144
+ }
145
+
146
+ textInputRef.current?.focus();
147
+ };
148
+
149
+ const toggle = (toggleRef: React.Ref<MenuToggleElement>) => (
150
+ <MenuToggle variant="typeahead" onClick={onToggleClick} innerRef={toggleRef} isExpanded={isOpen} isFullWidth>
151
+ <TextInputGroup isPlain>
152
+ <TextInputGroupMain
153
+ value={inputValue}
154
+ onClick={onToggleClick}
155
+ onChange={onTextInputChange}
156
+ onKeyDown={onInputKeyDown}
157
+ id="multi-create-typeahead-select-input"
158
+ autoComplete="off"
159
+ innerRef={textInputRef}
160
+ placeholder="Select a state"
161
+ {...(activeItem && { 'aria-activedescendant': activeItem })}
162
+ role="combobox"
163
+ isExpanded={isOpen}
164
+ aria-controls="select-multi-create-typeahead-listbox"
165
+ >
166
+ <ChipGroup aria-label="Current selections">
167
+ {selected.map((selection, index) => (
168
+ <Chip
169
+ key={index}
170
+ onClick={(ev) => {
171
+ ev.stopPropagation();
172
+ onSelect(selection);
173
+ }}
174
+ >
175
+ {selection}
176
+ </Chip>
177
+ ))}
178
+ </ChipGroup>
179
+ </TextInputGroupMain>
180
+ <TextInputGroupUtilities>
181
+ {selected.length > 0 && (
182
+ <Button
183
+ variant="plain"
184
+ onClick={() => {
185
+ setInputValue('');
186
+ setSelected([]);
187
+ textInputRef?.current?.focus();
188
+ }}
189
+ aria-label="Clear input value"
190
+ >
191
+ <TimesIcon aria-hidden />
192
+ </Button>
193
+ )}
194
+ </TextInputGroupUtilities>
195
+ </TextInputGroup>
196
+ </MenuToggle>
197
+ );
198
+
199
+ return (
200
+ <Select
201
+ id="multi-create-typeahead-select"
202
+ isOpen={isOpen}
203
+ selected={selected}
204
+ onSelect={(ev, selection) => onSelect(selection as string)}
205
+ onOpenChange={() => setIsOpen(false)}
206
+ toggle={toggle}
207
+ >
208
+ <SelectList isAriaMultiselectable id="select-multi-create-typeahead-listbox">
209
+ {selectOptions.map((option, index) => (
210
+ <SelectOption
211
+ key={option.itemId || option.children}
212
+ isFocused={focusedItemIndex === index}
213
+ className={option.className}
214
+ id={`select-multi-create-typeahead-${option.itemId.replace(' ', '-')}`}
215
+ {...option}
216
+ ref={null}
217
+ />
218
+ ))}
219
+ </SelectList>
220
+ </Select>
221
+ );
222
+ };
@@ -0,0 +1,70 @@
1
+ import React from 'react';
2
+ import { Select, SelectOption, SelectList, MenuToggle, MenuToggleElement } from '@patternfly/react-core';
3
+ import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
4
+
5
+ export const SelectOptionVariations: React.FunctionComponent = () => {
6
+ const [isOpen, setIsOpen] = React.useState(false);
7
+ const [selected, setSelected] = React.useState<string>('Select a value');
8
+
9
+ const onToggleClick = () => {
10
+ setIsOpen(!isOpen);
11
+ };
12
+
13
+ const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, itemId: string | number | undefined) => {
14
+ // eslint-disable-next-line no-console
15
+ console.log('selected', itemId);
16
+
17
+ setSelected(itemId as string);
18
+ setIsOpen(false);
19
+ };
20
+
21
+ const toggle = (toggleRef: React.Ref<MenuToggleElement>) => (
22
+ <MenuToggle
23
+ ref={toggleRef}
24
+ onClick={onToggleClick}
25
+ isExpanded={isOpen}
26
+ style={
27
+ {
28
+ width: '200px'
29
+ } as React.CSSProperties
30
+ }
31
+ >
32
+ {selected}
33
+ </MenuToggle>
34
+ );
35
+
36
+ return (
37
+ <Select
38
+ id="option-variations-select"
39
+ isOpen={isOpen}
40
+ selected={selected}
41
+ onSelect={onSelect}
42
+ onOpenChange={(isOpen) => setIsOpen(isOpen)}
43
+ toggle={toggle}
44
+ shouldFocusToggleOnSelect
45
+ >
46
+ <SelectList>
47
+ <SelectOption itemId="Basic option">Basic option</SelectOption>
48
+ <SelectOption itemId="Option with description" description="This is a description">
49
+ Option with description
50
+ </SelectOption>
51
+ <SelectOption
52
+ to="#"
53
+ // Prevent default clicking functionality for example purposes only
54
+ onClick={(event) => event.preventDefault()}
55
+ itemId="Option with link"
56
+ isExternalLink
57
+ >
58
+ Option with link
59
+ </SelectOption>
60
+ <SelectOption itemId="Option with icon" icon={<BellIcon />}>
61
+ Option with icon
62
+ </SelectOption>
63
+ <SelectOption itemId="Disabled option" isDisabled>
64
+ Disabled option
65
+ </SelectOption>
66
+ <SelectOption itemId="See Menu for additional variations!">See Menu for additional variations!</SelectOption>
67
+ </SelectList>
68
+ </Select>
69
+ );
70
+ };
@@ -26,28 +26,25 @@ export const SelectBasic: React.FunctionComponent = () => {
26
26
  const [isOpen, setIsOpen] = React.useState(false);
27
27
  const [selected, setSelected] = React.useState<string>('');
28
28
  const [inputValue, setInputValue] = React.useState<string>('');
29
+ const [filterValue, setFilterValue] = React.useState<string>('');
29
30
  const [selectOptions, setSelectOptions] = React.useState<SelectOptionProps[]>(initialSelectOptions);
30
31
  const [focusedItemIndex, setFocusedItemIndex] = React.useState<number | null>(null);
31
32
  const [activeItem, setActiveItem] = React.useState<string | null>(null);
32
-
33
- const menuRef = React.useRef<HTMLDivElement>(null);
34
33
  const textInputRef = React.useRef<HTMLInputElement>();
35
34
 
36
35
  React.useEffect(() => {
37
36
  let newSelectOptions: SelectOptionProps[] = initialSelectOptions;
38
37
 
39
38
  // Filter menu items based on the text input value when one exists
40
- if (inputValue) {
41
- newSelectOptions = initialSelectOptions.filter(menuItem =>
42
- String(menuItem.children)
43
- .toLowerCase()
44
- .includes(inputValue.toLowerCase())
39
+ if (filterValue) {
40
+ newSelectOptions = initialSelectOptions.filter((menuItem) =>
41
+ String(menuItem.children).toLowerCase().includes(filterValue.toLowerCase())
45
42
  );
46
43
 
47
44
  // When no options are found after filtering, display 'No results found'
48
45
  if (!newSelectOptions.length) {
49
46
  newSelectOptions = [
50
- { isDisabled: false, children: `No results found for "${inputValue}"`, itemId: 'no results' }
47
+ { isDisabled: false, children: `No results found for "${filterValue}"`, itemId: 'no results' }
51
48
  ];
52
49
  }
53
50
 
@@ -60,7 +57,7 @@ export const SelectBasic: React.FunctionComponent = () => {
60
57
  setSelectOptions(newSelectOptions);
61
58
  setActiveItem(null);
62
59
  setFocusedItemIndex(null);
63
- }, [inputValue]);
60
+ }, [filterValue]);
64
61
 
65
62
  const onToggleClick = () => {
66
63
  setIsOpen(!isOpen);
@@ -72,6 +69,7 @@ export const SelectBasic: React.FunctionComponent = () => {
72
69
 
73
70
  if (itemId && itemId !== 'no results') {
74
71
  setInputValue(itemId as string);
72
+ setFilterValue('');
75
73
  setSelected(itemId as string);
76
74
  }
77
75
  setIsOpen(false);
@@ -81,6 +79,7 @@ export const SelectBasic: React.FunctionComponent = () => {
81
79
 
82
80
  const onTextInputChange = (_event: React.FormEvent<HTMLInputElement>, value: string) => {
83
81
  setInputValue(value);
82
+ setFilterValue(value);
84
83
  };
85
84
 
86
85
  const handleMenuArrowKeys = (key: string) => {
@@ -106,13 +105,13 @@ export const SelectBasic: React.FunctionComponent = () => {
106
105
  }
107
106
 
108
107
  setFocusedItemIndex(indexToFocus);
109
- const focusedItem = selectOptions.filter(option => !option.isDisabled)[indexToFocus];
108
+ const focusedItem = selectOptions.filter((option) => !option.isDisabled)[indexToFocus];
110
109
  setActiveItem(`select-typeahead-${focusedItem.itemId.replace(' ', '-')}`);
111
110
  }
112
111
  };
113
112
 
114
113
  const onInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
115
- const enabledMenuItems = selectOptions.filter(option => !option.isDisabled);
114
+ const enabledMenuItems = selectOptions.filter((option) => !option.isDisabled);
116
115
  const [firstMenuItem] = enabledMenuItems;
117
116
  const focusedItem = focusedItemIndex ? enabledMenuItems[focusedItemIndex] : firstMenuItem;
118
117
 
@@ -121,10 +120,11 @@ export const SelectBasic: React.FunctionComponent = () => {
121
120
  case 'Enter':
122
121
  if (isOpen && focusedItem.itemId !== 'no results') {
123
122
  setInputValue(String(focusedItem.children));
123
+ setFilterValue('');
124
124
  setSelected(String(focusedItem.children));
125
125
  }
126
126
 
127
- setIsOpen(prevIsOpen => !prevIsOpen);
127
+ setIsOpen((prevIsOpen) => !prevIsOpen);
128
128
  setFocusedItemIndex(null);
129
129
  setActiveItem(null);
130
130
 
@@ -167,6 +167,7 @@ export const SelectBasic: React.FunctionComponent = () => {
167
167
  onClick={() => {
168
168
  setSelected('');
169
169
  setInputValue('');
170
+ setFilterValue('');
170
171
  textInputRef?.current?.focus();
171
172
  }}
172
173
  aria-label="Clear input value"
@@ -182,7 +183,6 @@ export const SelectBasic: React.FunctionComponent = () => {
182
183
  return (
183
184
  <Select
184
185
  id="typeahead-select"
185
- ref={menuRef}
186
186
  isOpen={isOpen}
187
187
  selected={selected}
188
188
  onSelect={onSelect}
@@ -0,0 +1,220 @@
1
+ import React from 'react';
2
+ import {
3
+ Select,
4
+ SelectOption,
5
+ SelectList,
6
+ SelectOptionProps,
7
+ MenuToggle,
8
+ MenuToggleElement,
9
+ TextInputGroup,
10
+ TextInputGroupMain,
11
+ TextInputGroupUtilities,
12
+ Button
13
+ } from '@patternfly/react-core';
14
+ import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
15
+
16
+ let initialSelectOptions: SelectOptionProps[] = [
17
+ { itemId: 'Alabama', children: 'Alabama' },
18
+ { itemId: 'Florida', children: 'Florida' },
19
+ { itemId: 'New Jersey', children: 'New Jersey' },
20
+ { itemId: 'New Mexico', children: 'New Mexico' },
21
+ { itemId: 'New York', children: 'New York' },
22
+ { itemId: 'North Carolina', children: 'North Carolina' }
23
+ ];
24
+
25
+ export const SelectTypeaheadCreatable: React.FunctionComponent = () => {
26
+ const [isOpen, setIsOpen] = React.useState(false);
27
+ const [selected, setSelected] = React.useState<string>('');
28
+ const [inputValue, setInputValue] = React.useState<string>('');
29
+ const [filterValue, setFilterValue] = React.useState<string>('');
30
+ const [selectOptions, setSelectOptions] = React.useState<SelectOptionProps[]>(initialSelectOptions);
31
+ const [focusedItemIndex, setFocusedItemIndex] = React.useState<number | null>(null);
32
+ const [activeItem, setActiveItem] = React.useState<string | null>(null);
33
+ const [onCreation, setOnCreation] = React.useState<boolean>(false); // Boolean to refresh filter state after new option is created
34
+ const textInputRef = React.useRef<HTMLInputElement>();
35
+
36
+ React.useEffect(() => {
37
+ let newSelectOptions: SelectOptionProps[] = initialSelectOptions;
38
+
39
+ // Filter menu items based on the text input value when one exists
40
+ if (filterValue) {
41
+ newSelectOptions = initialSelectOptions.filter((menuItem) =>
42
+ String(menuItem.children).toLowerCase().includes(filterValue.toLowerCase())
43
+ );
44
+
45
+ // When no options are found after filtering, display creation option
46
+ if (!newSelectOptions.length) {
47
+ newSelectOptions = [{ isDisabled: false, children: `Create new option "${filterValue}"`, itemId: 'create' }];
48
+ }
49
+
50
+ // Open the menu when the input value changes and the new value is not empty
51
+ if (!isOpen) {
52
+ setIsOpen(true);
53
+ }
54
+ }
55
+
56
+ setSelectOptions(newSelectOptions);
57
+ setActiveItem(null);
58
+ setFocusedItemIndex(null);
59
+ }, [filterValue, onCreation]);
60
+
61
+ const onToggleClick = () => {
62
+ setIsOpen(!isOpen);
63
+ };
64
+
65
+ const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, itemId: string | number | undefined) => {
66
+ // eslint-disable-next-line no-console
67
+
68
+ if (itemId) {
69
+ if (itemId === 'create') {
70
+ if (!initialSelectOptions.some((item) => item.itemId === filterValue)) {
71
+ initialSelectOptions = [...initialSelectOptions, { itemId: filterValue, children: filterValue }];
72
+ }
73
+ setSelected(filterValue);
74
+ setOnCreation(!onCreation);
75
+ setFilterValue('');
76
+ } else {
77
+ // eslint-disable-next-line no-console
78
+ console.log('selected', itemId);
79
+ setInputValue(itemId as string);
80
+ setFilterValue('');
81
+ setSelected(itemId as string);
82
+ }
83
+ }
84
+
85
+ setIsOpen(false);
86
+ setFocusedItemIndex(null);
87
+ setActiveItem(null);
88
+ };
89
+
90
+ const onTextInputChange = (_event: React.FormEvent<HTMLInputElement>, value: string) => {
91
+ setInputValue(value);
92
+ setFilterValue(value);
93
+ };
94
+
95
+ const handleMenuArrowKeys = (key: string) => {
96
+ let indexToFocus;
97
+
98
+ if (isOpen) {
99
+ if (key === 'ArrowUp') {
100
+ // When no index is set or at the first index, focus to the last, otherwise decrement focus index
101
+ if (focusedItemIndex === null || focusedItemIndex === 0) {
102
+ indexToFocus = selectOptions.length - 1;
103
+ } else {
104
+ indexToFocus = focusedItemIndex - 1;
105
+ }
106
+ }
107
+
108
+ if (key === 'ArrowDown') {
109
+ // When no index is set or at the last index, focus to the first, otherwise increment focus index
110
+ if (focusedItemIndex === null || focusedItemIndex === selectOptions.length - 1) {
111
+ indexToFocus = 0;
112
+ } else {
113
+ indexToFocus = focusedItemIndex + 1;
114
+ }
115
+ }
116
+
117
+ setFocusedItemIndex(indexToFocus);
118
+ const focusedItem = selectOptions.filter((option) => !option.isDisabled)[indexToFocus];
119
+ setActiveItem(`select-create-typeahead-${focusedItem.itemId.replace(' ', '-')}`);
120
+ }
121
+ };
122
+
123
+ const onInputKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
124
+ const enabledMenuItems = selectOptions.filter((option) => !option.isDisabled);
125
+ const [firstMenuItem] = enabledMenuItems;
126
+ const focusedItem = focusedItemIndex ? enabledMenuItems[focusedItemIndex] : firstMenuItem;
127
+
128
+ switch (event.key) {
129
+ // Select the first available option
130
+ case 'Enter':
131
+ if (isOpen) {
132
+ onSelect(undefined, focusedItem.itemId as string);
133
+ setIsOpen((prevIsOpen) => !prevIsOpen);
134
+ setFocusedItemIndex(null);
135
+ setActiveItem(null);
136
+ }
137
+
138
+ setIsOpen((prevIsOpen) => !prevIsOpen);
139
+ setFocusedItemIndex(null);
140
+ setActiveItem(null);
141
+
142
+ break;
143
+ case 'Tab':
144
+ case 'Escape':
145
+ setIsOpen(false);
146
+ setActiveItem(null);
147
+ break;
148
+ case 'ArrowUp':
149
+ case 'ArrowDown':
150
+ event.preventDefault();
151
+ handleMenuArrowKeys(event.key);
152
+ break;
153
+ }
154
+ };
155
+
156
+ const toggle = (toggleRef: React.Ref<MenuToggleElement>) => (
157
+ <MenuToggle ref={toggleRef} variant="typeahead" onClick={onToggleClick} isExpanded={isOpen} isFullWidth>
158
+ <TextInputGroup isPlain>
159
+ <TextInputGroupMain
160
+ value={inputValue}
161
+ onClick={onToggleClick}
162
+ onChange={onTextInputChange}
163
+ onKeyDown={onInputKeyDown}
164
+ id="create-typeahead-select-input"
165
+ autoComplete="off"
166
+ innerRef={textInputRef}
167
+ placeholder="Select a state"
168
+ {...(activeItem && { 'aria-activedescendant': activeItem })}
169
+ role="combobox"
170
+ isExpanded={isOpen}
171
+ aria-controls="select-create-typeahead-listbox"
172
+ />
173
+
174
+ <TextInputGroupUtilities>
175
+ {!!inputValue && (
176
+ <Button
177
+ variant="plain"
178
+ onClick={() => {
179
+ setSelected('');
180
+ setInputValue('');
181
+ setFilterValue('');
182
+ textInputRef?.current?.focus();
183
+ }}
184
+ aria-label="Clear input value"
185
+ >
186
+ <TimesIcon aria-hidden />
187
+ </Button>
188
+ )}
189
+ </TextInputGroupUtilities>
190
+ </TextInputGroup>
191
+ </MenuToggle>
192
+ );
193
+
194
+ return (
195
+ <Select
196
+ id="create-typeahead-select"
197
+ isOpen={isOpen}
198
+ selected={selected}
199
+ onSelect={onSelect}
200
+ onOpenChange={() => {
201
+ setIsOpen(false);
202
+ }}
203
+ toggle={toggle}
204
+ >
205
+ <SelectList id="select-create-typeahead-listbox">
206
+ {selectOptions.map((option, index) => (
207
+ <SelectOption
208
+ key={option.itemId || option.children}
209
+ isFocused={focusedItemIndex === index}
210
+ className={option.className}
211
+ onClick={() => setSelected(option.itemId)}
212
+ id={`select-typeahead-${option.itemId.replace(' ', '-')}`}
213
+ {...option}
214
+ ref={null}
215
+ />
216
+ ))}
217
+ </SelectList>
218
+ </Select>
219
+ );
220
+ };