@patternfly/react-core 5.0.0-alpha.107 → 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 (271) hide show
  1. package/CHANGELOG.md +6 -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/package.json +1 -1
  48. package/dist/esm/components/MenuToggle/package.json +1 -1
  49. package/dist/esm/components/Modal/package.json +1 -1
  50. package/dist/esm/components/MultipleFileUpload/package.json +1 -1
  51. package/dist/esm/components/Nav/package.json +1 -1
  52. package/dist/esm/components/NotificationBadge/package.json +1 -1
  53. package/dist/esm/components/NotificationDrawer/package.json +1 -1
  54. package/dist/esm/components/NumberInput/package.json +1 -1
  55. package/dist/esm/components/OverflowMenu/package.json +1 -1
  56. package/dist/esm/components/Page/package.json +1 -1
  57. package/dist/esm/components/Pagination/package.json +1 -1
  58. package/dist/esm/components/Panel/package.json +1 -1
  59. package/dist/esm/components/Popover/package.json +1 -1
  60. package/dist/esm/components/Progress/package.json +1 -1
  61. package/dist/esm/components/ProgressStepper/package.json +1 -1
  62. package/dist/esm/components/Radio/package.json +1 -1
  63. package/dist/esm/components/SearchInput/package.json +1 -1
  64. package/dist/esm/components/Select/Select.d.ts +31 -5
  65. package/dist/esm/components/Select/Select.d.ts.map +1 -1
  66. package/dist/esm/components/Select/Select.js +16 -10
  67. package/dist/esm/components/Select/Select.js.map +1 -1
  68. package/dist/esm/components/Select/SelectGroup.d.ts +3 -0
  69. package/dist/esm/components/Select/SelectGroup.d.ts.map +1 -1
  70. package/dist/esm/components/Select/SelectGroup.js.map +1 -1
  71. package/dist/esm/components/Select/SelectOption.d.ts +14 -1
  72. package/dist/esm/components/Select/SelectOption.d.ts.map +1 -1
  73. package/dist/esm/components/Select/SelectOption.js +4 -3
  74. package/dist/esm/components/Select/SelectOption.js.map +1 -1
  75. package/dist/esm/components/Select/package.json +1 -1
  76. package/dist/esm/components/Sidebar/package.json +1 -1
  77. package/dist/esm/components/SimpleList/package.json +1 -1
  78. package/dist/esm/components/Skeleton/package.json +1 -1
  79. package/dist/esm/components/SkipToContent/package.json +1 -1
  80. package/dist/esm/components/Slider/package.json +1 -1
  81. package/dist/esm/components/Spinner/package.json +1 -1
  82. package/dist/esm/components/Switch/package.json +1 -1
  83. package/dist/esm/components/Tabs/package.json +1 -1
  84. package/dist/esm/components/Text/package.json +1 -1
  85. package/dist/esm/components/TextArea/package.json +1 -1
  86. package/dist/esm/components/TextInput/package.json +1 -1
  87. package/dist/esm/components/TextInputGroup/package.json +1 -1
  88. package/dist/esm/components/Tile/package.json +1 -1
  89. package/dist/esm/components/TimePicker/package.json +1 -1
  90. package/dist/esm/components/Timestamp/package.json +1 -1
  91. package/dist/esm/components/Title/package.json +1 -1
  92. package/dist/esm/components/ToggleGroup/package.json +1 -1
  93. package/dist/esm/components/Toolbar/package.json +1 -1
  94. package/dist/esm/components/Tooltip/package.json +1 -1
  95. package/dist/esm/components/TreeView/package.json +1 -1
  96. package/dist/esm/components/Truncate/package.json +1 -1
  97. package/dist/esm/components/Wizard/hooks/package.json +1 -1
  98. package/dist/esm/components/Wizard/package.json +1 -1
  99. package/dist/esm/components/package.json +1 -1
  100. package/dist/esm/deprecated/components/ApplicationLauncher/package.json +1 -1
  101. package/dist/esm/deprecated/components/ContextSelector/package.json +1 -1
  102. package/dist/esm/deprecated/components/Dropdown/package.json +1 -1
  103. package/dist/esm/deprecated/components/OptionsMenu/package.json +1 -1
  104. package/dist/esm/deprecated/components/PageHeader/package.json +1 -1
  105. package/dist/esm/deprecated/components/Select/package.json +1 -1
  106. package/dist/esm/deprecated/components/Wizard/package.json +1 -1
  107. package/dist/esm/deprecated/components/package.json +1 -1
  108. package/dist/esm/deprecated/package.json +1 -1
  109. package/dist/esm/helpers/Popper/Popper.d.ts +1 -1
  110. package/dist/esm/helpers/Popper/Popper.d.ts.map +1 -1
  111. package/dist/esm/helpers/Popper/thirdparty/popper-core/package.json +1 -1
  112. package/dist/esm/helpers/package.json +1 -1
  113. package/dist/esm/layouts/Bullseye/package.json +1 -1
  114. package/dist/esm/layouts/Flex/package.json +1 -1
  115. package/dist/esm/layouts/Gallery/package.json +1 -1
  116. package/dist/esm/layouts/Grid/package.json +1 -1
  117. package/dist/esm/layouts/Level/package.json +1 -1
  118. package/dist/esm/layouts/Split/package.json +1 -1
  119. package/dist/esm/layouts/Stack/package.json +1 -1
  120. package/dist/esm/layouts/package.json +1 -1
  121. package/dist/esm/next/components/package.json +1 -1
  122. package/dist/esm/next/package.json +1 -1
  123. package/dist/esm/package.json +1 -1
  124. package/dist/js/components/AboutModal/package.json +1 -1
  125. package/dist/js/components/Accordion/package.json +1 -1
  126. package/dist/js/components/ActionList/package.json +1 -1
  127. package/dist/js/components/Alert/package.json +1 -1
  128. package/dist/js/components/Avatar/package.json +1 -1
  129. package/dist/js/components/BackToTop/package.json +1 -1
  130. package/dist/js/components/Backdrop/package.json +1 -1
  131. package/dist/js/components/BackgroundImage/package.json +1 -1
  132. package/dist/js/components/Badge/package.json +1 -1
  133. package/dist/js/components/Banner/package.json +1 -1
  134. package/dist/js/components/Brand/package.json +1 -1
  135. package/dist/js/components/Breadcrumb/package.json +1 -1
  136. package/dist/js/components/Button/package.json +1 -1
  137. package/dist/js/components/CalendarMonth/package.json +1 -1
  138. package/dist/js/components/Card/package.json +1 -1
  139. package/dist/js/components/Checkbox/package.json +1 -1
  140. package/dist/js/components/Chip/package.json +1 -1
  141. package/dist/js/components/ClipboardCopy/package.json +1 -1
  142. package/dist/js/components/CodeBlock/package.json +1 -1
  143. package/dist/js/components/DataList/package.json +1 -1
  144. package/dist/js/components/DatePicker/package.json +1 -1
  145. package/dist/js/components/DescriptionList/package.json +1 -1
  146. package/dist/js/components/Divider/package.json +1 -1
  147. package/dist/js/components/DragDrop/package.json +1 -1
  148. package/dist/js/components/Drawer/package.json +1 -1
  149. package/dist/js/components/Dropdown/Dropdown.d.ts +11 -3
  150. package/dist/js/components/Dropdown/Dropdown.d.ts.map +1 -1
  151. package/dist/js/components/Dropdown/Dropdown.js +11 -5
  152. package/dist/js/components/Dropdown/Dropdown.js.map +1 -1
  153. package/dist/js/components/Dropdown/package.json +1 -1
  154. package/dist/js/components/DualListSelector/package.json +1 -1
  155. package/dist/js/components/EmptyState/package.json +1 -1
  156. package/dist/js/components/ExpandableSection/package.json +1 -1
  157. package/dist/js/components/FileUpload/package.json +1 -1
  158. package/dist/js/components/Form/package.json +1 -1
  159. package/dist/js/components/FormSelect/package.json +1 -1
  160. package/dist/js/components/HelperText/package.json +1 -1
  161. package/dist/js/components/Hint/package.json +1 -1
  162. package/dist/js/components/Icon/package.json +1 -1
  163. package/dist/js/components/InputGroup/package.json +1 -1
  164. package/dist/js/components/JumpLinks/package.json +1 -1
  165. package/dist/js/components/Label/package.json +1 -1
  166. package/dist/js/components/List/package.json +1 -1
  167. package/dist/js/components/LoginPage/package.json +1 -1
  168. package/dist/js/components/Masthead/package.json +1 -1
  169. package/dist/js/components/Menu/package.json +1 -1
  170. package/dist/js/components/MenuToggle/package.json +1 -1
  171. package/dist/js/components/Modal/package.json +1 -1
  172. package/dist/js/components/MultipleFileUpload/package.json +1 -1
  173. package/dist/js/components/Nav/package.json +1 -1
  174. package/dist/js/components/NotificationBadge/package.json +1 -1
  175. package/dist/js/components/NotificationDrawer/package.json +1 -1
  176. package/dist/js/components/NumberInput/package.json +1 -1
  177. package/dist/js/components/OverflowMenu/package.json +1 -1
  178. package/dist/js/components/Page/package.json +1 -1
  179. package/dist/js/components/Pagination/package.json +1 -1
  180. package/dist/js/components/Panel/package.json +1 -1
  181. package/dist/js/components/Popover/package.json +1 -1
  182. package/dist/js/components/Progress/package.json +1 -1
  183. package/dist/js/components/ProgressStepper/package.json +1 -1
  184. package/dist/js/components/Radio/package.json +1 -1
  185. package/dist/js/components/SearchInput/package.json +1 -1
  186. package/dist/js/components/Select/Select.d.ts +31 -5
  187. package/dist/js/components/Select/Select.d.ts.map +1 -1
  188. package/dist/js/components/Select/Select.js +16 -10
  189. package/dist/js/components/Select/Select.js.map +1 -1
  190. package/dist/js/components/Select/SelectGroup.d.ts +3 -0
  191. package/dist/js/components/Select/SelectGroup.d.ts.map +1 -1
  192. package/dist/js/components/Select/SelectGroup.js.map +1 -1
  193. package/dist/js/components/Select/SelectOption.d.ts +14 -1
  194. package/dist/js/components/Select/SelectOption.d.ts.map +1 -1
  195. package/dist/js/components/Select/SelectOption.js +4 -4
  196. package/dist/js/components/Select/SelectOption.js.map +1 -1
  197. package/dist/js/components/Select/package.json +1 -1
  198. package/dist/js/components/Sidebar/package.json +1 -1
  199. package/dist/js/components/SimpleList/package.json +1 -1
  200. package/dist/js/components/Skeleton/package.json +1 -1
  201. package/dist/js/components/SkipToContent/package.json +1 -1
  202. package/dist/js/components/Slider/package.json +1 -1
  203. package/dist/js/components/Spinner/package.json +1 -1
  204. package/dist/js/components/Switch/package.json +1 -1
  205. package/dist/js/components/Tabs/package.json +1 -1
  206. package/dist/js/components/Text/package.json +1 -1
  207. package/dist/js/components/TextArea/package.json +1 -1
  208. package/dist/js/components/TextInput/package.json +1 -1
  209. package/dist/js/components/TextInputGroup/package.json +1 -1
  210. package/dist/js/components/Tile/package.json +1 -1
  211. package/dist/js/components/TimePicker/package.json +1 -1
  212. package/dist/js/components/Timestamp/package.json +1 -1
  213. package/dist/js/components/Title/package.json +1 -1
  214. package/dist/js/components/ToggleGroup/package.json +1 -1
  215. package/dist/js/components/Toolbar/package.json +1 -1
  216. package/dist/js/components/Tooltip/package.json +1 -1
  217. package/dist/js/components/TreeView/package.json +1 -1
  218. package/dist/js/components/Truncate/package.json +1 -1
  219. package/dist/js/components/Wizard/hooks/package.json +1 -1
  220. package/dist/js/components/Wizard/package.json +1 -1
  221. package/dist/js/components/package.json +1 -1
  222. package/dist/js/deprecated/components/ApplicationLauncher/package.json +1 -1
  223. package/dist/js/deprecated/components/ContextSelector/package.json +1 -1
  224. package/dist/js/deprecated/components/Dropdown/package.json +1 -1
  225. package/dist/js/deprecated/components/OptionsMenu/package.json +1 -1
  226. package/dist/js/deprecated/components/PageHeader/package.json +1 -1
  227. package/dist/js/deprecated/components/Select/package.json +1 -1
  228. package/dist/js/deprecated/components/Wizard/package.json +1 -1
  229. package/dist/js/deprecated/components/package.json +1 -1
  230. package/dist/js/deprecated/package.json +1 -1
  231. package/dist/js/helpers/Popper/Popper.d.ts +1 -1
  232. package/dist/js/helpers/Popper/Popper.d.ts.map +1 -1
  233. package/dist/js/helpers/Popper/thirdparty/popper-core/package.json +1 -1
  234. package/dist/js/helpers/package.json +1 -1
  235. package/dist/js/layouts/Bullseye/package.json +1 -1
  236. package/dist/js/layouts/Flex/package.json +1 -1
  237. package/dist/js/layouts/Gallery/package.json +1 -1
  238. package/dist/js/layouts/Grid/package.json +1 -1
  239. package/dist/js/layouts/Level/package.json +1 -1
  240. package/dist/js/layouts/Split/package.json +1 -1
  241. package/dist/js/layouts/Stack/package.json +1 -1
  242. package/dist/js/layouts/package.json +1 -1
  243. package/dist/js/next/components/package.json +1 -1
  244. package/dist/js/next/package.json +1 -1
  245. package/dist/js/package.json +1 -1
  246. package/dist/umd/react-core.min.js +2 -2
  247. package/package.json +2 -2
  248. package/src/components/DatePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap +27 -29
  249. package/src/components/Dropdown/Dropdown.tsx +25 -11
  250. package/src/components/Dropdown/examples/Dropdown.md +10 -1
  251. package/src/components/Dropdown/examples/DropdownBasic.tsx +2 -6
  252. package/src/components/Dropdown/examples/DropdownWithDescriptions.tsx +2 -6
  253. package/src/components/Dropdown/examples/DropdownWithGroups.tsx +2 -6
  254. package/src/components/Dropdown/examples/DropdownWithKebabToggle.tsx +2 -6
  255. package/src/components/Select/Select.tsx +62 -24
  256. package/src/components/Select/SelectGroup.tsx +3 -0
  257. package/src/components/Select/SelectOption.tsx +22 -2
  258. package/src/components/Select/examples/Select.md +49 -2
  259. package/src/components/Select/examples/SelectBasic.tsx +27 -17
  260. package/src/components/Select/examples/SelectCheckbox.tsx +1 -3
  261. package/src/components/Select/examples/SelectFooter.tsx +57 -0
  262. package/src/components/Select/examples/SelectGrouped.tsx +14 -6
  263. package/src/components/Select/examples/SelectMultiTypeahead.tsx +7 -12
  264. package/src/components/Select/examples/SelectMultiTypeaheadCheckbox.tsx +204 -0
  265. package/src/components/Select/examples/SelectMultiTypeaheadCreatable.tsx +222 -0
  266. package/src/components/Select/examples/SelectOptionVariations.tsx +70 -0
  267. package/src/components/Select/examples/SelectTypeahead.tsx +13 -13
  268. package/src/components/Select/examples/SelectTypeaheadCreatable.tsx +220 -0
  269. package/src/components/Select/examples/SelectViewMore.tsx +146 -0
  270. package/src/demos/ComposableMenu/ComposableMenu.md +14 -0
  271. package/src/helpers/Popper/Popper.tsx +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "5.0.0-alpha.107",
3
+ "version": "5.0.0-alpha.108",
4
4
  "description": "This library provides a set of common React components for use with the PatternFly reference implementation.",
5
5
  "main": "dist/js/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -71,5 +71,5 @@
71
71
  "react": "^17 || ^18",
72
72
  "react-dom": "^17 || ^18"
73
73
  },
74
- "gitHead": "2da278eeebfb3475c31e3693435a8c7f04a0edde"
74
+ "gitHead": "c3fe2fb841eabc1aded749983b71c487fc9cdf0c"
75
75
  }
@@ -114,39 +114,37 @@ exports[`With popover opened 1`] = `
114
114
  >
115
115
  Month
116
116
  </span>
117
- <div>
118
- <button
119
- aria-expanded="false"
120
- class="pf-v5-c-menu-toggle"
121
- style="width: 140px;"
122
- type="button"
117
+ <button
118
+ aria-expanded="false"
119
+ class="pf-v5-c-menu-toggle"
120
+ style="width: 140px;"
121
+ type="button"
122
+ >
123
+ <span
124
+ class="pf-v5-c-menu-toggle__text"
125
+ >
126
+ December
127
+ </span>
128
+ <span
129
+ class="pf-v5-c-menu-toggle__controls"
123
130
  >
124
131
  <span
125
- class="pf-v5-c-menu-toggle__text"
126
- >
127
- December
128
- </span>
129
- <span
130
- class="pf-v5-c-menu-toggle__controls"
132
+ class="pf-v5-c-menu-toggle__toggle-icon"
131
133
  >
132
- <span
133
- class="pf-v5-c-menu-toggle__toggle-icon"
134
+ <svg
135
+ aria-hidden="true"
136
+ class="pf-v5-svg"
137
+ fill="currentColor"
138
+ role="img"
139
+ viewBox="0 0 320 512"
134
140
  >
135
- <svg
136
- aria-hidden="true"
137
- class="pf-v5-svg"
138
- fill="currentColor"
139
- role="img"
140
- viewBox="0 0 320 512"
141
- >
142
- <path
143
- d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
144
- />
145
- </svg>
146
- </span>
141
+ <path
142
+ d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"
143
+ />
144
+ </svg>
147
145
  </span>
148
- </button>
149
- </div>
146
+ </span>
147
+ </button>
150
148
  </div>
151
149
  </div>
152
150
  <div
@@ -813,4 +811,4 @@ exports[`disabled date picker 1`] = `
813
811
  </div>
814
812
  </div>
815
813
  </DocumentFragment>
816
- `;
814
+ `;
@@ -19,6 +19,13 @@ export interface DropdownPopperProps {
19
19
  enableFlip?: boolean;
20
20
  }
21
21
 
22
+ export interface DropdownToggleProps {
23
+ /** Dropdown toggle node. */
24
+ toggleNode: React.ReactNode;
25
+ /** Reference to the toggle. */
26
+ toggleRef?: React.RefObject<HTMLButtonElement>;
27
+ }
28
+
22
29
  /**
23
30
  * See the Menu documentation for additional props that may be passed.
24
31
  */
@@ -27,16 +34,14 @@ export interface DropdownProps extends MenuProps, OUIAProps {
27
34
  children?: React.ReactNode;
28
35
  /** Classes applied to root element of dropdown. */
29
36
  className?: string;
30
- /** Renderer for a custom dropdown toggle. Forwards a ref to the toggle. */
31
- toggle: (toggleRef: React.RefObject<any>) => React.ReactNode;
37
+ /** Dropdown toggle. The toggle should either be a renderer function which forwards the given toggle ref, or a direct ReactNode that should be passed along with the toggleRef property. */
38
+ toggle: DropdownToggleProps | ((toggleRef: React.RefObject<any>) => React.ReactNode);
32
39
  /** Flag to indicate if menu is opened.*/
33
40
  isOpen?: boolean;
41
+ /** Flag indicating the toggle should be focused after a selection. If this use case is too restrictive, the optional toggleRef property with a node toggle may be used to control focus. */
42
+ shouldFocusToggleOnSelect?: boolean;
34
43
  /** Function callback called when user selects item. */
35
- onSelect?: (
36
- event?: React.MouseEvent<Element, MouseEvent>,
37
- itemId?: string | number,
38
- toggleRef?: React.RefObject<any>
39
- ) => void;
44
+ onSelect?: (event?: React.MouseEvent<Element, MouseEvent>, itemId?: string | number) => void;
40
45
  /** Callback to allow the dropdown component to change the open state of the menu.
41
46
  * Triggered by clicking outside of the menu, or by pressing either tab or escape. */
42
47
  onOpenChange?: (isOpen: boolean) => void;
@@ -62,6 +67,7 @@ const DropdownBase: React.FunctionComponent<DropdownProps> = ({
62
67
  onSelect,
63
68
  isOpen,
64
69
  toggle,
70
+ shouldFocusToggleOnSelect = false,
65
71
  onOpenChange,
66
72
  isPlain,
67
73
  isScrollable,
@@ -73,10 +79,15 @@ const DropdownBase: React.FunctionComponent<DropdownProps> = ({
73
79
  ...props
74
80
  }: DropdownProps) => {
75
81
  const localMenuRef = React.useRef<HTMLDivElement>();
76
- const toggleRef = React.useRef<HTMLButtonElement>();
82
+ const localToggleRef = React.useRef<HTMLButtonElement>();
77
83
  const ouiaProps = useOUIAProps(Dropdown.displayName, ouiaId, ouiaSafe);
78
84
 
79
85
  const menuRef = (innerRef as React.RefObject<HTMLDivElement>) || localMenuRef;
86
+ const toggleRef =
87
+ typeof toggle === 'function' || (typeof toggle !== 'function' && !toggle.toggleRef)
88
+ ? localToggleRef
89
+ : (toggle?.toggleRef as React.RefObject<HTMLButtonElement>);
90
+
80
91
  React.useEffect(() => {
81
92
  const handleMenuKeys = (event: KeyboardEvent) => {
82
93
  // Close the menu on tab or escape if onOpenChange is provided
@@ -119,13 +130,16 @@ const DropdownBase: React.FunctionComponent<DropdownProps> = ({
119
130
  window.removeEventListener('keydown', handleMenuKeys);
120
131
  window.removeEventListener('click', handleClick);
121
132
  };
122
- }, [isOpen, menuRef, onOpenChange]);
133
+ }, [isOpen, menuRef, toggleRef, onOpenChange]);
123
134
 
124
135
  const menu = (
125
136
  <Menu
126
137
  className={css(className)}
127
138
  ref={menuRef}
128
- onSelect={(event, itemId) => onSelect && onSelect(event, itemId, toggleRef)}
139
+ onSelect={(event, itemId) => {
140
+ onSelect && onSelect(event, itemId);
141
+ shouldFocusToggleOnSelect && toggleRef.current.focus();
142
+ }}
129
143
  isPlain={isPlain}
130
144
  isScrollable={isScrollable}
131
145
  {...props}
@@ -136,7 +150,7 @@ const DropdownBase: React.FunctionComponent<DropdownProps> = ({
136
150
  );
137
151
  return (
138
152
  <Popper
139
- trigger={toggle(toggleRef)}
153
+ trigger={typeof toggle === 'function' ? toggle(toggleRef) : toggle.toggleNode}
140
154
  triggerRef={toggleRef}
141
155
  popper={menu}
142
156
  popperRef={menuRef}
@@ -3,7 +3,16 @@ id: Dropdown
3
3
  section: components
4
4
  subsection: menus
5
5
  cssPrefix: pf-c-menu
6
- propComponents: ['Dropdown', DropdownGroup, 'DropdownItem', 'DropdownList', 'MenuToggle', 'DropdownPopperProps']
6
+ propComponents:
7
+ [
8
+ 'Dropdown',
9
+ 'DropdownGroup',
10
+ 'DropdownItem',
11
+ 'DropdownList',
12
+ 'MenuToggle',
13
+ 'DropdownToggleProps',
14
+ 'DropdownPopperProps'
15
+ ]
7
16
  ---
8
17
 
9
18
  import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
@@ -8,15 +8,10 @@ export const DropdownBasic: React.FunctionComponent = () => {
8
8
  setIsOpen(!isOpen);
9
9
  };
10
10
 
11
- const onSelect = (
12
- _event: React.MouseEvent<Element, MouseEvent> | undefined,
13
- itemId: string | number | undefined,
14
- toggleRef: React.RefObject<any>
15
- ) => {
11
+ const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, itemId: string | number | undefined) => {
16
12
  // eslint-disable-next-line no-console
17
13
  console.log('selected', itemId);
18
14
  setIsOpen(false);
19
- toggleRef?.current.focus();
20
15
  };
21
16
 
22
17
  return (
@@ -30,6 +25,7 @@ export const DropdownBasic: React.FunctionComponent = () => {
30
25
  </MenuToggle>
31
26
  )}
32
27
  ouiaId="BasicDropdown"
28
+ shouldFocusToggleOnSelect
33
29
  >
34
30
  <DropdownList>
35
31
  <DropdownItem itemId={0} key="action">
@@ -8,15 +8,10 @@ export const DropdownWithDescriptions: React.FunctionComponent = () => {
8
8
  setIsOpen(!isOpen);
9
9
  };
10
10
 
11
- const onSelect = (
12
- _event: React.MouseEvent<Element, MouseEvent> | undefined,
13
- itemId: string | number | undefined,
14
- toggleRef: React.RefObject<any>
15
- ) => {
11
+ const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, itemId: string | number | undefined) => {
16
12
  // eslint-disable-next-line no-console
17
13
  console.log('selected', itemId);
18
14
  setIsOpen(false);
19
- toggleRef?.current.focus();
20
15
  };
21
16
 
22
17
  return (
@@ -29,6 +24,7 @@ export const DropdownWithDescriptions: React.FunctionComponent = () => {
29
24
  Dropdown
30
25
  </MenuToggle>
31
26
  )}
27
+ shouldFocusToggleOnSelect
32
28
  >
33
29
  <DropdownList>
34
30
  <DropdownItem itemId={0} key="action" description="This is a description">
@@ -16,15 +16,10 @@ export const DropdownWithGroups: React.FunctionComponent = () => {
16
16
  setIsOpen(!isOpen);
17
17
  };
18
18
 
19
- const onSelect = (
20
- _event: React.MouseEvent<Element, MouseEvent> | undefined,
21
- itemId: string | number | undefined,
22
- toggleRef: React.RefObject<any>
23
- ) => {
19
+ const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, itemId: string | number | undefined) => {
24
20
  // eslint-disable-next-line no-console
25
21
  console.log('selected', itemId);
26
22
  setIsOpen(false);
27
- toggleRef?.current.focus();
28
23
  };
29
24
 
30
25
  return (
@@ -37,6 +32,7 @@ export const DropdownWithGroups: React.FunctionComponent = () => {
37
32
  Dropdown
38
33
  </MenuToggle>
39
34
  )}
35
+ shouldFocusToggleOnSelect
40
36
  >
41
37
  <DropdownGroup>
42
38
  <DropdownList>
@@ -9,15 +9,10 @@ export const DropdownWithKebab: React.FunctionComponent = () => {
9
9
  setIsOpen(!isOpen);
10
10
  };
11
11
 
12
- const onSelect = (
13
- _event: React.MouseEvent<Element, MouseEvent> | undefined,
14
- itemId: string | number | undefined,
15
- toggleRef: React.RefObject<any>
16
- ) => {
12
+ const onSelect = (_event: React.MouseEvent<Element, MouseEvent> | undefined, itemId: string | number | undefined) => {
17
13
  // eslint-disable-next-line no-console
18
14
  console.log('selected', itemId);
19
15
  setIsOpen(false);
20
- toggleRef?.current.focus();
21
16
  };
22
17
 
23
18
  return (
@@ -36,6 +31,7 @@ export const DropdownWithKebab: React.FunctionComponent = () => {
36
31
  <EllipsisVIcon />
37
32
  </MenuToggle>
38
33
  )}
34
+ shouldFocusToggleOnSelect
39
35
  >
40
36
  <DropdownList>
41
37
  <DropdownItem itemId={0} key="action">
@@ -1,9 +1,35 @@
1
1
  import React from 'react';
2
2
  import { css } from '@patternfly/react-styles';
3
3
  import { Menu, MenuContent, MenuProps } from '../Menu';
4
- import { Popper, PopperProps } from '../../helpers/Popper/Popper';
4
+ import { Popper } from '../../helpers/Popper/Popper';
5
5
  import { getOUIAProps, OUIAProps, getDefaultOUIAId } from '../../helpers';
6
6
 
7
+ export interface SelectPopperProps {
8
+ /** Vertical direction of the popper. If enableFlip is set to true, this will set the initial direction before the popper flips. */
9
+ direction?: 'up' | 'down';
10
+ /** Horizontal position of the popper */
11
+ position?: 'right' | 'left' | 'center';
12
+ /** Custom width of the popper. If the value is "trigger", it will set the width to the select toggle's width */
13
+ width?: string | 'trigger';
14
+ /** Minimum width of the popper. If the value is "trigger", it will set the min width to the select toggle's width */
15
+ minWidth?: string | 'trigger';
16
+ /** Maximum width of the popper. If the value is "trigger", it will set the max width to the select toggle's width */
17
+ maxWidth?: string | 'trigger';
18
+ /** Enable to flip the popper when it reaches the boundary */
19
+ enableFlip?: boolean;
20
+ }
21
+
22
+ export interface SelectToggleProps {
23
+ /** Select toggle node. */
24
+ toggleNode: React.ReactNode;
25
+ /** Reference to the toggle. */
26
+ toggleRef?: React.RefObject<HTMLButtonElement>;
27
+ }
28
+
29
+ /**
30
+ * See the Menu documentation for additional props that may be passed.
31
+ */
32
+
7
33
  export interface SelectProps extends MenuProps, OUIAProps {
8
34
  /** Anything which can be rendered in a select */
9
35
  children?: React.ReactNode;
@@ -13,13 +39,17 @@ export interface SelectProps extends MenuProps, OUIAProps {
13
39
  isOpen?: boolean;
14
40
  /** Single itemId for single select menus, or array of itemIds for multi select. You can also specify isSelected on the SelectOption. */
15
41
  selected?: any | any[];
16
- /** Renderer for a custom select toggle. Forwards a ref to the toggle. */
17
- toggle: (toggleRef: React.RefObject<any>) => React.ReactNode;
42
+ /** Select toggle. The toggle should either be a renderer function which forwards the given toggle ref, or a direct ReactNode that should be passed along with the toggleRef property. */
43
+ toggle: SelectToggleProps | ((toggleRef: React.RefObject<any>) => React.ReactNode);
44
+ /** Flag indicating the toggle should be focused after a selection. If this use case is too restrictive, the optional toggleRef property with a node toggle may be used to control focus. */
45
+ shouldFocusToggleOnSelect?: boolean;
18
46
  /** Function callback when user selects an option. */
19
47
  onSelect?: (event?: React.MouseEvent<Element, MouseEvent>, itemId?: string | number) => void;
20
48
  /** Callback to allow the select component to change the open state of the menu.
21
- * Triggered by clicking outside of the menu, or by pressing either tab or escape. */
49
+ * Triggered by clicking outside of the menu, or by pressing any keys specificed in onOpenChangeKeys. */
22
50
  onOpenChange?: (isOpen: boolean) => void;
51
+ /** @beta Keys that trigger onOpenChange, defaults to tab and escape. It is highly recommended to include Escape in the array, while Tab may be omitted if the menu contains non-menu items that are focusable. */
52
+ onOpenChangeKeys?: string[];
23
53
  /** Indicates if the select should be without the outer box-shadow */
24
54
  isPlain?: boolean;
25
55
  /** @hide Forwarded ref */
@@ -29,7 +59,7 @@ export interface SelectProps extends MenuProps, OUIAProps {
29
59
  /** @beta Determines the accessible role of the select. For a checkbox select pass in "menu". */
30
60
  role?: string;
31
61
  /** Additional properties to pass to the popper */
32
- popperProps?: Partial<PopperProps>;
62
+ popperProps?: SelectPopperProps;
33
63
  }
34
64
 
35
65
  const SelectBase: React.FunctionComponent<SelectProps & OUIAProps> = ({
@@ -39,7 +69,9 @@ const SelectBase: React.FunctionComponent<SelectProps & OUIAProps> = ({
39
69
  isOpen,
40
70
  selected,
41
71
  toggle,
72
+ shouldFocusToggleOnSelect = false,
42
73
  onOpenChange,
74
+ onOpenChangeKeys = ['Escape', 'Tab'],
43
75
  isPlain,
44
76
  innerRef,
45
77
  zIndex = 9999,
@@ -48,18 +80,24 @@ const SelectBase: React.FunctionComponent<SelectProps & OUIAProps> = ({
48
80
  ...props
49
81
  }: SelectProps & OUIAProps) => {
50
82
  const localMenuRef = React.useRef<HTMLDivElement>();
51
- const toggleRef = React.useRef<HTMLButtonElement>();
52
- const containerRef = React.useRef<HTMLDivElement>();
83
+ const localToggleRef = React.useRef<HTMLButtonElement>();
53
84
 
54
85
  const menuRef = (innerRef as React.RefObject<HTMLDivElement>) || localMenuRef;
86
+ const toggleRef =
87
+ typeof toggle === 'function' || (typeof toggle !== 'function' && !toggle.toggleRef)
88
+ ? localToggleRef
89
+ : (toggle?.toggleRef as React.RefObject<HTMLButtonElement>);
90
+
55
91
  React.useEffect(() => {
56
92
  const handleMenuKeys = (event: KeyboardEvent) => {
57
93
  // Close the menu on tab or escape if onOpenChange is provided
58
94
  if (
59
- (isOpen && onOpenChange && menuRef.current?.contains(event.target as Node)) ||
60
- toggleRef.current?.contains(event.target as Node)
95
+ isOpen &&
96
+ onOpenChange &&
97
+ (menuRef.current?.contains(event.target as Node) || toggleRef.current?.contains(event.target as Node))
61
98
  ) {
62
- if (event.key === 'Escape' || event.key === 'Tab') {
99
+ if (onOpenChangeKeys.includes(event.key)) {
100
+ event.preventDefault();
63
101
  onOpenChange(false);
64
102
  toggleRef.current?.focus();
65
103
  }
@@ -90,14 +128,17 @@ const SelectBase: React.FunctionComponent<SelectProps & OUIAProps> = ({
90
128
  window.removeEventListener('keydown', handleMenuKeys);
91
129
  window.removeEventListener('click', handleClick);
92
130
  };
93
- }, [isOpen, menuRef, onOpenChange]);
131
+ }, [isOpen, menuRef, toggleRef, onOpenChange, onOpenChangeKeys]);
94
132
 
95
133
  const menu = (
96
134
  <Menu
97
135
  role={role}
98
136
  className={css(className)}
99
137
  ref={menuRef}
100
- onSelect={(event, itemId) => onSelect && onSelect(event, itemId)}
138
+ onSelect={(event, itemId) => {
139
+ onSelect && onSelect(event, itemId);
140
+ shouldFocusToggleOnSelect && toggleRef.current.focus();
141
+ }}
101
142
  isPlain={isPlain}
102
143
  selected={selected}
103
144
  {...getOUIAProps(
@@ -111,18 +152,15 @@ const SelectBase: React.FunctionComponent<SelectProps & OUIAProps> = ({
111
152
  </Menu>
112
153
  );
113
154
  return (
114
- <div ref={containerRef}>
115
- <Popper
116
- trigger={toggle(toggleRef)}
117
- triggerRef={toggleRef}
118
- popper={menu}
119
- popperRef={menuRef}
120
- appendTo={containerRef.current || undefined}
121
- isVisible={isOpen}
122
- zIndex={zIndex}
123
- {...popperProps}
124
- />
125
- </div>
155
+ <Popper
156
+ trigger={typeof toggle === 'function' ? toggle(toggleRef) : toggle.toggleNode}
157
+ triggerRef={toggleRef}
158
+ popper={menu}
159
+ popperRef={menuRef}
160
+ isVisible={isOpen}
161
+ zIndex={zIndex}
162
+ {...popperProps}
163
+ />
126
164
  );
127
165
  };
128
166
 
@@ -2,6 +2,9 @@ import React from 'react';
2
2
  import { css } from '@patternfly/react-styles';
3
3
  import { MenuGroupProps, MenuGroup } from '../Menu';
4
4
 
5
+ /**
6
+ * See the MenuGroup section of the Menu documentation for additional props that may be passed.
7
+ */
5
8
  export interface SelectGroupProps extends Omit<MenuGroupProps, 'ref'> {
6
9
  /** Anything which can be rendered in a select group */
7
10
  children: React.ReactNode;
@@ -2,11 +2,17 @@ import React from 'react';
2
2
  import { css } from '@patternfly/react-styles';
3
3
  import { MenuItemProps, MenuItem } from '../Menu';
4
4
 
5
+ /**
6
+ * See the MenuItem section of the Menu documentation for additional props that may be passed.
7
+ */
8
+
5
9
  export interface SelectOptionProps extends Omit<MenuItemProps, 'ref'> {
6
10
  /** Anything which can be rendered in a select option */
7
11
  children?: React.ReactNode;
8
12
  /** Classes applied to root element of select option */
9
13
  className?: string;
14
+ /** @hide Forwarded ref */
15
+ innerRef?: React.Ref<HTMLAnchorElement | HTMLButtonElement>;
10
16
  /** Identifies the component in the Select onSelect callback */
11
17
  itemId?: any;
12
18
  /** Indicates the option has a checkbox */
@@ -17,15 +23,29 @@ export interface SelectOptionProps extends Omit<MenuItemProps, 'ref'> {
17
23
  isSelected?: boolean;
18
24
  /** Indicates the option is focused */
19
25
  isFocused?: boolean;
26
+ /** Render an external link icon on focus or hover, and set the link's
27
+ * "target" attribute to a value of "_blank".
28
+ */
29
+ isExternalLink?: boolean;
30
+ /** Render option with icon */
31
+ icon?: React.ReactNode;
32
+ /** Description of the option */
33
+ description?: React.ReactNode;
20
34
  }
21
35
 
22
- export const SelectOption: React.FunctionComponent<MenuItemProps> = ({
36
+ const SelectOptionBase: React.FunctionComponent<MenuItemProps> = ({
23
37
  children,
24
38
  className,
39
+ innerRef,
25
40
  ...props
26
41
  }: SelectOptionProps) => (
27
- <MenuItem className={css(className)} {...props}>
42
+ <MenuItem ref={innerRef} className={css(className)} {...props}>
28
43
  {children}
29
44
  </MenuItem>
30
45
  );
46
+
47
+ export const SelectOption = React.forwardRef((props: SelectOptionProps, ref: React.Ref<any>) => (
48
+ <SelectOptionBase {...props} innerRef={ref} />
49
+ ));
50
+
31
51
  SelectOption.displayName = 'SelectOption';
@@ -3,35 +3,82 @@ id: Select
3
3
  section: components
4
4
  subsection: menus
5
5
  cssPrefix: pf-c-select
6
- propComponents: ['Select', 'SelectOption', 'SelectGroup', 'SelectList', 'MenuToggle']
6
+ propComponents:
7
+ ['Select', 'SelectOption', 'SelectGroup', 'SelectList', 'MenuToggle', 'SelectToggleProps', 'SelectPopperProps']
7
8
  ouia: true
8
9
  ---
9
10
 
10
11
  import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
12
+ import BellIcon from '@patternfly/react-icons/dist/esm/icons/bell-icon';
11
13
 
12
14
  ## Examples
13
15
 
16
+ `Select` builds off of the Menu component suite to wrap commonly used properties and functions for a select menu. See the [Menu documentation](/components/menus/menu) for a full list of properties that may be passed through `Select` to further customize the select menu, or the [custom menu examples](/components/menus/custom-menus) for additional examples of fully functional menus.
17
+
14
18
  ### Single
15
19
 
16
20
  ```ts file="./SelectBasic.tsx"
21
+
22
+ ```
23
+
24
+ ### Option variations
25
+
26
+ Showcases different option variants and customizations that are commonly used in a select menu. For a more complete list, see the [Menu documentation](/components/menus/menu).
27
+
28
+ ```ts file="./SelectOptionVariations.tsx"
29
+
17
30
  ```
18
31
 
19
32
  ### Grouped single
20
33
 
21
34
  ```ts file="./SelectGrouped.tsx"
35
+
22
36
  ```
23
37
 
24
38
  ### Checkbox
25
39
 
26
40
  ```ts file="./SelectCheckbox.tsx"
41
+
27
42
  ```
28
43
 
29
44
  ### Typeahead
30
45
 
31
46
  ```ts file="./SelectTypeahead.tsx"
47
+
48
+ ```
49
+
50
+ ### Typeahead with create option
51
+
52
+ ```ts file="./SelectTypeaheadCreatable.tsx"
53
+
32
54
  ```
33
55
 
34
- ### Multiple Typeahead
56
+ ### Multiple typeahead with chips
35
57
 
36
58
  ```ts file="./SelectMultiTypeahead.tsx"
59
+
60
+ ```
61
+
62
+ ### Multiple typeahead with create option
63
+
64
+ ```ts file="./SelectMultiTypeaheadCreatable.tsx"
65
+
66
+ ```
67
+
68
+ ### Multiple typeahead with checkboxes
69
+
70
+ ```ts file="./SelectMultiTypeaheadCheckbox.tsx"
71
+
72
+ ```
73
+
74
+ ### View more
75
+
76
+ ```ts file="./SelectViewMore.tsx"
77
+
78
+ ```
79
+
80
+ ### Footer
81
+
82
+ ```ts file="./SelectFooter.tsx"
83
+
37
84
  ```
@@ -1,10 +1,10 @@
1
1
  import React from 'react';
2
- import { Select, SelectOption, SelectList, MenuToggle, MenuToggleElement } from '@patternfly/react-core';
2
+ import { Select, SelectOption, SelectList, MenuToggle, MenuToggleElement, Checkbox } from '@patternfly/react-core';
3
3
 
4
4
  export const SelectBasic: React.FunctionComponent = () => {
5
5
  const [isOpen, setIsOpen] = React.useState(false);
6
6
  const [selected, setSelected] = React.useState<string>('Select a value');
7
- const menuRef = React.useRef<HTMLDivElement>(null);
7
+ const [isDisabled, setIsDisabled] = React.useState<boolean>(false);
8
8
 
9
9
  const onToggleClick = () => {
10
10
  setIsOpen(!isOpen);
@@ -23,6 +23,7 @@ export const SelectBasic: React.FunctionComponent = () => {
23
23
  ref={toggleRef}
24
24
  onClick={onToggleClick}
25
25
  isExpanded={isOpen}
26
+ isDisabled={isDisabled}
26
27
  style={
27
28
  {
28
29
  width: '200px'
@@ -34,20 +35,29 @@ export const SelectBasic: React.FunctionComponent = () => {
34
35
  );
35
36
 
36
37
  return (
37
- <Select
38
- id="single-select"
39
- ref={menuRef}
40
- isOpen={isOpen}
41
- selected={selected}
42
- onSelect={onSelect}
43
- onOpenChange={isOpen => setIsOpen(isOpen)}
44
- toggle={toggle}
45
- >
46
- <SelectList>
47
- <SelectOption itemId="Option 1">Option 1</SelectOption>
48
- <SelectOption itemId="Option 2">Option 2</SelectOption>
49
- <SelectOption itemId="Option 3">Option 3</SelectOption>
50
- </SelectList>
51
- </Select>
38
+ <React.Fragment>
39
+ <Checkbox
40
+ id="toggle-disabled"
41
+ label="isDisabled"
42
+ isChecked={isDisabled}
43
+ onChange={(_event, checked) => setIsDisabled(checked)}
44
+ style={{ marginBottom: 20 }}
45
+ />
46
+ <Select
47
+ id="single-select"
48
+ isOpen={isOpen}
49
+ selected={selected}
50
+ onSelect={onSelect}
51
+ onOpenChange={(isOpen) => setIsOpen(isOpen)}
52
+ toggle={toggle}
53
+ shouldFocusToggleOnSelect
54
+ >
55
+ <SelectList>
56
+ <SelectOption itemId="Option 1">Option 1</SelectOption>
57
+ <SelectOption itemId="Option 2">Option 2</SelectOption>
58
+ <SelectOption itemId="Option 3">Option 3</SelectOption>
59
+ </SelectList>
60
+ </Select>
61
+ </React.Fragment>
52
62
  );
53
63
  };