@patternfly/react-core 5.0.0-alpha.61 → 5.0.0-alpha.63

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 (239) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/esm/components/CalendarMonth/CalendarMonth.d.ts.map +1 -1
  3. package/dist/esm/components/CalendarMonth/CalendarMonth.js +9 -11
  4. package/dist/esm/components/CalendarMonth/CalendarMonth.js.map +1 -1
  5. package/dist/esm/components/DualListSelector/DualListSelectorControl.d.ts +1 -1
  6. package/dist/esm/components/Menu/MenuItem.d.ts +1 -1
  7. package/dist/esm/components/MenuToggle/MenuToggle.d.ts.map +1 -1
  8. package/dist/esm/components/MenuToggle/MenuToggle.js +3 -1
  9. package/dist/esm/components/MenuToggle/MenuToggle.js.map +1 -1
  10. package/dist/esm/components/Select/Select.d.ts +26 -192
  11. package/dist/esm/components/Select/Select.d.ts.map +1 -1
  12. package/dist/esm/components/Select/Select.js +51 -935
  13. package/dist/esm/components/Select/Select.js.map +1 -1
  14. package/dist/esm/components/Select/SelectGroup.d.ts +7 -8
  15. package/dist/esm/components/Select/SelectGroup.d.ts.map +1 -1
  16. package/dist/esm/components/Select/SelectGroup.js +4 -7
  17. package/dist/esm/components/Select/SelectGroup.js.map +1 -1
  18. package/dist/{js/next → esm}/components/Select/SelectList.d.ts +1 -1
  19. package/dist/esm/components/Select/SelectList.d.ts.map +1 -0
  20. package/dist/esm/{next/components → components}/Select/SelectList.js +1 -1
  21. package/dist/esm/components/Select/SelectList.js.map +1 -0
  22. package/dist/esm/components/Select/SelectOption.d.ts +13 -66
  23. package/dist/esm/components/Select/SelectOption.d.ts.map +1 -1
  24. package/dist/esm/components/Select/SelectOption.js +6 -192
  25. package/dist/esm/components/Select/SelectOption.js.map +1 -1
  26. package/dist/esm/components/Select/index.d.ts +1 -1
  27. package/dist/esm/components/Select/index.d.ts.map +1 -1
  28. package/dist/esm/components/Select/index.js +1 -1
  29. package/dist/esm/components/Select/index.js.map +1 -1
  30. package/dist/esm/deprecated/components/Select/Select.d.ts +199 -0
  31. package/dist/esm/deprecated/components/Select/Select.d.ts.map +1 -0
  32. package/dist/esm/deprecated/components/Select/Select.js +940 -0
  33. package/dist/esm/deprecated/components/Select/Select.js.map +1 -0
  34. package/dist/esm/deprecated/components/Select/SelectGroup.d.ts +13 -0
  35. package/dist/esm/deprecated/components/Select/SelectGroup.d.ts.map +1 -0
  36. package/dist/esm/deprecated/components/Select/SelectGroup.js +13 -0
  37. package/dist/esm/deprecated/components/Select/SelectGroup.js.map +1 -0
  38. package/dist/esm/deprecated/components/Select/SelectMenu.d.ts.map +1 -0
  39. package/dist/esm/{components → deprecated/components}/Select/SelectMenu.js +1 -1
  40. package/dist/esm/deprecated/components/Select/SelectMenu.js.map +1 -0
  41. package/dist/esm/deprecated/components/Select/SelectOption.d.ts +73 -0
  42. package/dist/esm/deprecated/components/Select/SelectOption.d.ts.map +1 -0
  43. package/dist/esm/deprecated/components/Select/SelectOption.js +196 -0
  44. package/dist/esm/deprecated/components/Select/SelectOption.js.map +1 -0
  45. package/dist/esm/deprecated/components/Select/SelectToggle.d.ts.map +1 -0
  46. package/dist/esm/{components → deprecated/components}/Select/SelectToggle.js +2 -2
  47. package/dist/esm/deprecated/components/Select/SelectToggle.js.map +1 -0
  48. package/dist/esm/{next → deprecated}/components/Select/index.d.ts +1 -1
  49. package/dist/esm/deprecated/components/Select/index.d.ts.map +1 -0
  50. package/dist/esm/{next → deprecated}/components/Select/index.js +1 -1
  51. package/dist/esm/deprecated/components/Select/index.js.map +1 -0
  52. package/dist/esm/deprecated/components/Select/selectConstants.d.ts.map +1 -0
  53. package/dist/esm/deprecated/components/Select/selectConstants.js.map +1 -0
  54. package/dist/esm/deprecated/components/index.d.ts +1 -0
  55. package/dist/esm/deprecated/components/index.d.ts.map +1 -1
  56. package/dist/esm/deprecated/components/index.js +1 -0
  57. package/dist/esm/deprecated/components/index.js.map +1 -1
  58. package/dist/esm/next/components/index.d.ts +0 -1
  59. package/dist/esm/next/components/index.d.ts.map +1 -1
  60. package/dist/esm/next/components/index.js +0 -1
  61. package/dist/esm/next/components/index.js.map +1 -1
  62. package/dist/js/components/CalendarMonth/CalendarMonth.d.ts.map +1 -1
  63. package/dist/js/components/CalendarMonth/CalendarMonth.js +8 -10
  64. package/dist/js/components/CalendarMonth/CalendarMonth.js.map +1 -1
  65. package/dist/js/components/DualListSelector/DualListSelectorControl.d.ts +1 -1
  66. package/dist/js/components/Menu/MenuItem.d.ts +1 -1
  67. package/dist/js/components/MenuToggle/MenuToggle.d.ts.map +1 -1
  68. package/dist/js/components/MenuToggle/MenuToggle.js +3 -1
  69. package/dist/js/components/MenuToggle/MenuToggle.js.map +1 -1
  70. package/dist/js/components/Select/Select.d.ts +26 -192
  71. package/dist/js/components/Select/Select.d.ts.map +1 -1
  72. package/dist/js/components/Select/Select.js +51 -936
  73. package/dist/js/components/Select/Select.js.map +1 -1
  74. package/dist/js/components/Select/SelectGroup.d.ts +7 -8
  75. package/dist/js/components/Select/SelectGroup.d.ts.map +1 -1
  76. package/dist/js/components/Select/SelectGroup.js +4 -7
  77. package/dist/js/components/Select/SelectGroup.js.map +1 -1
  78. package/dist/{esm/next → js}/components/Select/SelectList.d.ts +1 -1
  79. package/dist/js/components/Select/SelectList.d.ts.map +1 -0
  80. package/dist/js/{next/components → components}/Select/SelectList.js +1 -1
  81. package/dist/js/components/Select/SelectList.js.map +1 -0
  82. package/dist/js/components/Select/SelectOption.d.ts +13 -66
  83. package/dist/js/components/Select/SelectOption.d.ts.map +1 -1
  84. package/dist/js/components/Select/SelectOption.js +7 -193
  85. package/dist/js/components/Select/SelectOption.js.map +1 -1
  86. package/dist/js/components/Select/index.d.ts +1 -1
  87. package/dist/js/components/Select/index.d.ts.map +1 -1
  88. package/dist/js/components/Select/index.js +1 -1
  89. package/dist/js/components/Select/index.js.map +1 -1
  90. package/dist/js/deprecated/components/Select/Select.d.ts +199 -0
  91. package/dist/js/deprecated/components/Select/Select.d.ts.map +1 -0
  92. package/dist/js/deprecated/components/Select/Select.js +944 -0
  93. package/dist/js/deprecated/components/Select/Select.js.map +1 -0
  94. package/dist/js/deprecated/components/Select/SelectGroup.d.ts +13 -0
  95. package/dist/js/deprecated/components/Select/SelectGroup.d.ts.map +1 -0
  96. package/dist/js/deprecated/components/Select/SelectGroup.js +17 -0
  97. package/dist/js/deprecated/components/Select/SelectGroup.js.map +1 -0
  98. package/dist/js/deprecated/components/Select/SelectMenu.d.ts.map +1 -0
  99. package/dist/js/{components → deprecated/components}/Select/SelectMenu.js +1 -1
  100. package/dist/js/deprecated/components/Select/SelectMenu.js.map +1 -0
  101. package/dist/js/deprecated/components/Select/SelectOption.d.ts +73 -0
  102. package/dist/js/deprecated/components/Select/SelectOption.d.ts.map +1 -0
  103. package/dist/js/deprecated/components/Select/SelectOption.js +200 -0
  104. package/dist/js/deprecated/components/Select/SelectOption.js.map +1 -0
  105. package/dist/js/deprecated/components/Select/SelectToggle.d.ts.map +1 -0
  106. package/dist/js/{components → deprecated/components}/Select/SelectToggle.js +2 -2
  107. package/dist/js/deprecated/components/Select/SelectToggle.js.map +1 -0
  108. package/dist/js/{next → deprecated}/components/Select/index.d.ts +1 -1
  109. package/dist/js/deprecated/components/Select/index.d.ts.map +1 -0
  110. package/dist/js/{next → deprecated}/components/Select/index.js +1 -1
  111. package/dist/js/deprecated/components/Select/index.js.map +1 -0
  112. package/dist/js/deprecated/components/Select/selectConstants.d.ts.map +1 -0
  113. package/dist/js/deprecated/components/Select/selectConstants.js.map +1 -0
  114. package/dist/js/deprecated/components/index.d.ts +1 -0
  115. package/dist/js/deprecated/components/index.d.ts.map +1 -1
  116. package/dist/js/deprecated/components/index.js +1 -0
  117. package/dist/js/deprecated/components/index.js.map +1 -1
  118. package/dist/js/next/components/index.d.ts +0 -1
  119. package/dist/js/next/components/index.d.ts.map +1 -1
  120. package/dist/js/next/components/index.js +0 -1
  121. package/dist/js/next/components/index.js.map +1 -1
  122. package/dist/umd/react-core.min.js +3 -3
  123. package/package.json +2 -2
  124. package/src/components/Alert/examples/Alert.md +5 -5
  125. package/src/components/Breadcrumb/examples/BreadcrumbBasic.tsx +1 -1
  126. package/src/components/Button/examples/ButtonVariations.tsx +4 -4
  127. package/src/components/CalendarMonth/CalendarMonth.tsx +25 -15
  128. package/src/components/Card/examples/CardBasic.tsx +1 -1
  129. package/src/components/DatePicker/__tests__/__snapshots__/DatePicker.test.tsx.snap +22 -31
  130. package/src/components/Dropdown/examples/DropdownBasic.tsx +1 -0
  131. package/src/components/FormSelect/examples/FormSelectBasic.tsx +1 -1
  132. package/src/components/LoginPage/examples/LoginPageLanguageSelect.tsx +28 -19
  133. package/src/components/MenuToggle/MenuToggle.tsx +2 -1
  134. package/src/components/MenuToggle/__tests__/__snapshots__/MenuToggle.test.tsx.snap +18 -10
  135. package/src/components/Modal/examples/ModalBasic.tsx +2 -1
  136. package/src/components/Nav/examples/NavDefault.tsx +1 -1
  137. package/src/components/Pagination/examples/PaginationTop.tsx +1 -0
  138. package/src/components/Select/Select.tsx +113 -1475
  139. package/src/components/Select/SelectGroup.tsx +13 -25
  140. package/src/{next/components → components}/Select/SelectList.tsx +1 -1
  141. package/src/components/Select/SelectOption.tsx +22 -452
  142. package/src/components/Select/examples/Select.md +11 -2896
  143. package/src/{next/components → components}/Select/examples/SelectBasic.tsx +1 -2
  144. package/src/{next/components → components}/Select/examples/SelectCheckbox.tsx +1 -2
  145. package/src/{next/components → components}/Select/examples/SelectGrouped.tsx +1 -2
  146. package/src/{next/components → components}/Select/examples/SelectMultiTypeahead.tsx +4 -1
  147. package/src/{next/components → components}/Select/examples/SelectTypeahead.tsx +4 -1
  148. package/src/components/Select/index.ts +1 -1
  149. package/src/components/Switch/examples/SwitchBasic.tsx +1 -0
  150. package/src/components/Toolbar/__tests__/Toolbar.test.tsx +3 -21
  151. package/src/components/Toolbar/__tests__/__snapshots__/Toolbar.test.tsx.snap +12 -124
  152. package/src/components/Toolbar/examples/Toolbar.md +0 -1
  153. package/src/components/Toolbar/examples/ToolbarComponentManagedToggleGroups.tsx +59 -63
  154. package/src/components/Toolbar/examples/ToolbarConsumerManagedToggleGroups.tsx +58 -62
  155. package/src/components/Toolbar/examples/ToolbarCustomChipGroupContent.tsx +107 -23
  156. package/src/components/Toolbar/examples/ToolbarGroups.tsx +96 -59
  157. package/src/components/Toolbar/examples/ToolbarStacked.tsx +56 -39
  158. package/src/components/Toolbar/examples/ToolbarWithFilters.tsx +115 -28
  159. package/src/components/Tooltip/examples/TooltipOptions.tsx +53 -23
  160. package/src/demos/Card/Card.md +39 -23
  161. package/src/demos/CardDemos.md +99 -46
  162. package/src/demos/Toolbar.md +51 -21
  163. package/src/demos/examples/Tabs/TabsAndTable.tsx +5 -22
  164. package/src/deprecated/components/ContextSelector/examples/ContextSelectorBasic.tsx +1 -0
  165. package/src/deprecated/components/OptionsMenu/examples/OptionsMenu.md +2 -1
  166. package/src/deprecated/components/Select/Select.tsx +1495 -0
  167. package/src/deprecated/components/Select/SelectGroup.tsx +36 -0
  168. package/src/{components → deprecated/components}/Select/SelectMenu.tsx +2 -2
  169. package/src/deprecated/components/Select/SelectOption.tsx +461 -0
  170. package/src/{components → deprecated/components}/Select/SelectToggle.tsx +3 -3
  171. package/src/{components → deprecated/components}/Select/__tests__/Select.test.tsx +1 -1
  172. package/src/deprecated/components/Select/examples/Select.md +2937 -0
  173. package/src/{next → deprecated}/components/Select/index.ts +1 -1
  174. package/src/deprecated/components/index.ts +1 -0
  175. package/src/next/components/index.ts +0 -1
  176. package/dist/esm/components/Select/SelectMenu.d.ts.map +0 -1
  177. package/dist/esm/components/Select/SelectMenu.js.map +0 -1
  178. package/dist/esm/components/Select/SelectToggle.d.ts.map +0 -1
  179. package/dist/esm/components/Select/SelectToggle.js.map +0 -1
  180. package/dist/esm/components/Select/selectConstants.d.ts.map +0 -1
  181. package/dist/esm/components/Select/selectConstants.js.map +0 -1
  182. package/dist/esm/next/components/Select/Select.d.ts +0 -33
  183. package/dist/esm/next/components/Select/Select.d.ts.map +0 -1
  184. package/dist/esm/next/components/Select/Select.js +0 -56
  185. package/dist/esm/next/components/Select/Select.js.map +0 -1
  186. package/dist/esm/next/components/Select/SelectGroup.d.ts +0 -12
  187. package/dist/esm/next/components/Select/SelectGroup.d.ts.map +0 -1
  188. package/dist/esm/next/components/Select/SelectGroup.js +0 -10
  189. package/dist/esm/next/components/Select/SelectGroup.js.map +0 -1
  190. package/dist/esm/next/components/Select/SelectList.d.ts.map +0 -1
  191. package/dist/esm/next/components/Select/SelectList.js.map +0 -1
  192. package/dist/esm/next/components/Select/SelectOption.d.ts +0 -20
  193. package/dist/esm/next/components/Select/SelectOption.d.ts.map +0 -1
  194. package/dist/esm/next/components/Select/SelectOption.js +0 -10
  195. package/dist/esm/next/components/Select/SelectOption.js.map +0 -1
  196. package/dist/esm/next/components/Select/index.d.ts.map +0 -1
  197. package/dist/esm/next/components/Select/index.js.map +0 -1
  198. package/dist/js/components/Select/SelectMenu.d.ts.map +0 -1
  199. package/dist/js/components/Select/SelectMenu.js.map +0 -1
  200. package/dist/js/components/Select/SelectToggle.d.ts.map +0 -1
  201. package/dist/js/components/Select/SelectToggle.js.map +0 -1
  202. package/dist/js/components/Select/selectConstants.d.ts.map +0 -1
  203. package/dist/js/components/Select/selectConstants.js.map +0 -1
  204. package/dist/js/next/components/Select/Select.d.ts +0 -33
  205. package/dist/js/next/components/Select/Select.d.ts.map +0 -1
  206. package/dist/js/next/components/Select/Select.js +0 -59
  207. package/dist/js/next/components/Select/Select.js.map +0 -1
  208. package/dist/js/next/components/Select/SelectGroup.d.ts +0 -12
  209. package/dist/js/next/components/Select/SelectGroup.d.ts.map +0 -1
  210. package/dist/js/next/components/Select/SelectGroup.js +0 -14
  211. package/dist/js/next/components/Select/SelectGroup.js.map +0 -1
  212. package/dist/js/next/components/Select/SelectList.d.ts.map +0 -1
  213. package/dist/js/next/components/Select/SelectList.js.map +0 -1
  214. package/dist/js/next/components/Select/SelectOption.d.ts +0 -20
  215. package/dist/js/next/components/Select/SelectOption.d.ts.map +0 -1
  216. package/dist/js/next/components/Select/SelectOption.js +0 -14
  217. package/dist/js/next/components/Select/SelectOption.js.map +0 -1
  218. package/dist/js/next/components/Select/index.d.ts.map +0 -1
  219. package/dist/js/next/components/Select/index.js.map +0 -1
  220. package/src/next/components/Select/Select.tsx +0 -133
  221. package/src/next/components/Select/SelectGroup.tsx +0 -24
  222. package/src/next/components/Select/SelectOption.tsx +0 -31
  223. package/src/next/components/Select/examples/Select.md +0 -38
  224. /package/dist/esm/{components → deprecated/components}/Select/SelectMenu.d.ts +0 -0
  225. /package/dist/esm/{components → deprecated/components}/Select/SelectToggle.d.ts +0 -0
  226. /package/dist/esm/{components → deprecated/components}/Select/selectConstants.d.ts +0 -0
  227. /package/dist/esm/{components → deprecated/components}/Select/selectConstants.js +0 -0
  228. /package/dist/js/{components → deprecated/components}/Select/SelectMenu.d.ts +0 -0
  229. /package/dist/js/{components → deprecated/components}/Select/SelectToggle.d.ts +0 -0
  230. /package/dist/js/{components → deprecated/components}/Select/selectConstants.d.ts +0 -0
  231. /package/dist/js/{components → deprecated/components}/Select/selectConstants.js +0 -0
  232. /package/src/{components → deprecated/components}/Select/__tests__/SelectGroup.test.tsx +0 -0
  233. /package/src/{components → deprecated/components}/Select/__tests__/SelectOption.test.tsx +0 -0
  234. /package/src/{components → deprecated/components}/Select/__tests__/SelectToggle.test.tsx +0 -0
  235. /package/src/{components → deprecated/components}/Select/__tests__/__snapshots__/Select.test.tsx.snap +0 -0
  236. /package/src/{components → deprecated/components}/Select/__tests__/__snapshots__/SelectGroup.test.tsx.snap +0 -0
  237. /package/src/{components → deprecated/components}/Select/__tests__/__snapshots__/SelectOption.test.tsx.snap +0 -0
  238. /package/src/{components → deprecated/components}/Select/__tests__/__snapshots__/SelectToggle.test.tsx.snap +0 -0
  239. /package/src/{components → deprecated/components}/Select/selectConstants.tsx +0 -0
@@ -3,2920 +3,35 @@ id: Select
3
3
  section: components
4
4
  subsection: menus
5
5
  cssPrefix: pf-c-select
6
- propComponents: ['Select', 'SelectOption', 'SelectGroup', 'SelectOptionObject', 'SelectViewMoreObject']
6
+ propComponents: ['Select', 'SelectOption', 'SelectGroup', 'SelectList', 'MenuToggle']
7
7
  ouia: true
8
8
  ---
9
9
 
10
- import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
10
+ import TimesIcon from '@patternfly/react-icons/dist/esm/icons/times-icon';
11
11
 
12
12
  ## Examples
13
13
 
14
- ### Single select
14
+ ### Single
15
15
 
16
- To let users select a single item from a list, use a single select list.
17
-
18
- A select list may use other properties for additional customization. Select each checkbox in the example below to visualize the following behavior:
19
-
20
- - To prevent a toggle click from opening a select list, use the `isDisabled` property.
21
- - To adjust the direction a select menu opens, use the `direction` property. The menu in the following example expands upwards. By default, select lists open upwards.
22
- - To add an icon to a select toggle, use the `toggleIcon` property.
23
-
24
- ```js
25
- import React from 'react';
26
- import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
27
- import { Select, SelectOption, SelectVariant, SelectDirection, Checkbox, Divider } from '@patternfly/react-core';
28
-
29
- class SingleSelectInput extends React.Component {
30
- constructor(props) {
31
- super(props);
32
- this.options = [
33
- <SelectOption key={0} value="Select a title" isPlaceholder />,
34
- <SelectOption key={1} value="Mr" />,
35
- <SelectOption key={2} value="Miss" />,
36
- <SelectOption key={3} value="Mrs" />,
37
- <SelectOption key={4} value="Ms" />,
38
- <Divider component="li" key={5} />,
39
- <SelectOption key={6} value="Dr" />,
40
- <SelectOption key={7} value="Other" />
41
- ];
42
-
43
- this.toggleRef = React.createRef();
44
-
45
- this.state = {
46
- isToggleIcon: false,
47
- isOpen: false,
48
- selected: null,
49
- isDisabled: false,
50
- direction: SelectDirection.down
51
- };
52
-
53
- this.onToggle = (_event, isOpen) => {
54
- this.setState({
55
- isOpen
56
- });
57
- };
58
-
59
- this.onSelect = (event, selection, isPlaceholder) => {
60
- if (isPlaceholder) this.clearSelection();
61
- else {
62
- this.setState({
63
- selected: selection,
64
- isOpen: false
65
- });
66
- console.log('selected:', selection);
67
- this.toggleRef.current.focus();
68
- }
69
- };
70
-
71
- this.clearSelection = () => {
72
- this.setState({
73
- selected: null,
74
- isOpen: false
75
- });
76
- };
77
-
78
- this.toggleDisabled = checked => {
79
- this.setState({
80
- isDisabled: checked
81
- });
82
- };
83
-
84
- this.setIcon = checked => {
85
- this.setState({
86
- isToggleIcon: checked
87
- });
88
- };
89
-
90
- this.toggleDirection = () => {
91
- if (this.state.direction === SelectDirection.up) {
92
- this.setState({
93
- direction: SelectDirection.down
94
- });
95
- } else {
96
- this.setState({
97
- direction: SelectDirection.up
98
- });
99
- }
100
- };
101
- }
102
-
103
- render() {
104
- const { isOpen, selected, isDisabled, direction, isToggleIcon } = this.state;
105
- const titleId = 'title-id-1';
106
- return (
107
- <div>
108
- <span id={titleId} hidden>
109
- Title
110
- </span>
111
- <Select
112
- toggleRef={this.toggleRef}
113
- toggleIcon={isToggleIcon && <CubeIcon />}
114
- variant={SelectVariant.single}
115
- aria-label="Select Input"
116
- onToggle={this.onToggle}
117
- onSelect={this.onSelect}
118
- selections={selected}
119
- isOpen={isOpen}
120
- aria-labelledby={titleId}
121
- isDisabled={isDisabled}
122
- direction={direction}
123
- >
124
- {this.options}
125
- </Select>
126
- <Checkbox
127
- label="isDisabled"
128
- isChecked={this.state.isDisabled}
129
- onChange={(_event, checked) => this.toggleDisabled(checked)}
130
- aria-label="disabled checkbox"
131
- id="toggle-disabled"
132
- name="toggle-disabled"
133
- />
134
- <Checkbox
135
- label="Expands up"
136
- isChecked={direction === SelectDirection.up}
137
- onChange={this.toggleDirection}
138
- aria-label="direction checkbox"
139
- id="toggle-direction"
140
- name="toggle-direction"
141
- />
142
- <Checkbox
143
- label="Show icon"
144
- isChecked={isToggleIcon}
145
- onChange={(_event, checked) => this.setIcon(checked)}
146
- aria-label="show icon checkbox"
147
- id="toggle-icon"
148
- name="toggle-icon"
149
- />
150
- </div>
151
- );
152
- }
153
- }
154
- ```
155
-
156
- ### With item descriptions
157
-
158
- To give more context to a `<SelectOption>` in a list, use the `description` property.
159
-
160
- ```js
161
- import React from 'react';
162
- import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
163
-
164
- class SingleSelectDescription extends React.Component {
165
- constructor(props) {
166
- super(props);
167
- this.options = [
168
- { value: 'Mr', disabled: false },
169
- { value: 'Miss', disabled: false },
170
- { value: 'Mrs', disabled: false },
171
- { value: 'Ms', disabled: false },
172
- { value: 'Dr', disabled: false },
173
- { value: 'Other', disabled: false }
174
- ];
175
-
176
- this.toggleRef = React.createRef();
177
-
178
- this.state = {
179
- isOpen: false,
180
- selected: null,
181
- isDisabled: false
182
- };
183
-
184
- this.onToggle = (_event, isOpen) => {
185
- this.setState({
186
- isOpen
187
- });
188
- };
189
-
190
- this.onSelect = (event, selection, isPlaceholder) => {
191
- if (isPlaceholder) this.clearSelection();
192
- else {
193
- this.setState({
194
- selected: selection,
195
- isOpen: false
196
- });
197
- console.log('selected:', selection);
198
- this.toggleRef.current.focus();
199
- }
200
- };
201
-
202
- this.clearSelection = () => {
203
- this.setState({
204
- selected: null,
205
- isOpen: false
206
- });
207
- };
208
- }
209
-
210
- render() {
211
- const { isOpen, selected, isDisabled, direction, isToggleIcon } = this.state;
212
- const titleId = 'select-descriptions-title';
213
- return (
214
- <div>
215
- <span id={titleId} hidden>
216
- Title
217
- </span>
218
- <Select
219
- variant={SelectVariant.single}
220
- placeholderText="Select an option"
221
- aria-label="Select Input with descriptions"
222
- onToggle={this.onToggle}
223
- toggleRef={this.toggleRef}
224
- onSelect={this.onSelect}
225
- selections={selected}
226
- isOpen={isOpen}
227
- aria-labelledby={titleId}
228
- isDisabled={isDisabled}
229
- >
230
- {this.options.map((option, index) => (
231
- <SelectOption
232
- isDisabled={option.disabled}
233
- key={index}
234
- value={option.value}
235
- isPlaceholder={option.isPlaceholder}
236
- description="This is a description"
237
- />
238
- ))}
239
- </Select>
240
- </div>
241
- );
242
- }
243
- }
244
- ```
245
-
246
- ### With grouped items
247
-
248
- To group related select options together, use 1 or more `<SelectGroup>` components and title each group using the `label` property.
249
-
250
- ```js
251
- import React from 'react';
252
- import { Select, SelectOption, SelectVariant, SelectGroup, Divider } from '@patternfly/react-core';
253
-
254
- class GroupedSingleSelectInput extends React.Component {
255
- constructor(props) {
256
- super(props);
257
- this.state = {
258
- isOpen: false,
259
- selected: null
260
- };
261
-
262
- this.toggleRef = React.createRef();
263
-
264
- this.onToggle = (_event, isOpen) => {
265
- this.setState({
266
- isOpen
267
- });
268
- };
269
-
270
- this.onSelect = (event, selection) => {
271
- this.setState({
272
- selected: selection,
273
- isOpen: false
274
- });
275
- this.toggleRef.current.focus();
276
- };
277
-
278
- this.clearSelection = () => {
279
- this.setState({
280
- selected: null
281
- });
282
- };
283
-
284
- this.options = [
285
- <SelectGroup label="Status" key="group1">
286
- <SelectOption key={0} value="Running" />
287
- <SelectOption key={1} value="Stopped" />
288
- <SelectOption key={2} value="Down" />
289
- <SelectOption key={3} value="Degraded" />
290
- <SelectOption key={4} value="Needs maintenance" />
291
- </SelectGroup>,
292
- <Divider key="divider" />,
293
- <SelectGroup label="Vendor names" key="group2">
294
- <SelectOption key={5} value="Dell" />
295
- <SelectOption key={6} value="Samsung" isDisabled />
296
- <SelectOption key={7} value="Hewlett-Packard" />
297
- </SelectGroup>
298
- ];
299
- }
300
-
301
- render() {
302
- const { isOpen, selected } = this.state;
303
- const titleId = 'grouped-single-select-id';
304
- return (
305
- <div>
306
- <span id={titleId} hidden>
307
- Grouped Checkbox Title
308
- </span>
309
- <Select
310
- variant={SelectVariant.single}
311
- toggleRef={this.toggleRef}
312
- onToggle={this.onToggle}
313
- onSelect={this.onSelect}
314
- selections={selected}
315
- isOpen={isOpen}
316
- placeholderText="Filter by status/vendor"
317
- aria-labelledby={titleId}
318
- isGrouped
319
- >
320
- {this.options}
321
- </Select>
322
- </div>
323
- );
324
- }
325
- }
326
- ```
327
-
328
- ### Favoriting items
329
-
330
- To allow users to favorite items in a select list, use the `onFavorite` callback. When users click the favorite button, the item is duplicated and placed in a separated group at the top of the menu. To change the name of the group use the `favoritesLabel` property.
331
-
332
- ```js
333
- import React from 'react';
334
- import { Select, SelectOption, SelectVariant, SelectGroup } from '@patternfly/react-core';
335
-
336
- class FavoritesSelect extends React.Component {
337
- constructor(props) {
338
- super(props);
339
- this.state = {
340
- isOpen: false,
341
- selected: null,
342
- favorites: []
343
- };
344
-
345
- this.onToggle = (_event, isOpen) => {
346
- this.setState({
347
- isOpen
348
- });
349
- };
350
-
351
- this.onSelect = (event, selection, isPlaceholder) => {
352
- if (isPlaceholder) this.clearSelection();
353
- else {
354
- this.setState({
355
- selected: selection,
356
- isOpen: false
357
- });
358
- console.log('selected:', selection);
359
- }
360
- };
361
-
362
- this.clearSelection = () => {
363
- this.setState({
364
- selected: null,
365
- isOpen: false
366
- });
367
- };
368
-
369
- this.onFavorite = (itemId, isFavorite) => {
370
- if (isFavorite) {
371
- this.setState({
372
- favorites: this.state.favorites.filter(id => id !== itemId)
373
- });
374
- } else
375
- this.setState({
376
- favorites: [...this.state.favorites, itemId]
377
- });
378
- };
379
-
380
- this.options = [
381
- <SelectGroup label="Status" key="group1">
382
- <SelectOption id={'option-1'} key={0} value="Running" description="This is a description." />
383
- <SelectOption id={'option-2'} key={1} value="Stopped" />
384
- <SelectOption id={'option-3'} key={2} value="Down (disabled)" isDisabled />
385
- <SelectOption id={'option-4'} key={3} value="Degraded" />
386
- <SelectOption id={'option-5'} key={4} value="Needs maintenance" />
387
- </SelectGroup>,
388
- <SelectGroup label="Vendor names" key="group2">
389
- <SelectOption id={'option-6'} key={5} value="Dell" />
390
- <SelectOption id={'option-7'} key={6} value="Samsung" description="This is a description." />
391
- <SelectOption id={'option-8'} key={7} value="Hewlett-Packard" />
392
- </SelectGroup>
393
- ];
394
- }
395
-
396
- render() {
397
- const { isOpen, selected, favorites } = this.state;
398
- const titleId = 'grouped-single-select-id';
399
- return (
400
- <Select
401
- variant={SelectVariant.typeahead}
402
- typeAheadAriaLabel="Select value"
403
- onToggle={this.onToggle}
404
- onSelect={this.onSelect}
405
- selections={selected}
406
- isOpen={isOpen}
407
- placeholderText="Favorites"
408
- aria-labelledby={titleId}
409
- isGrouped
410
- onFavorite={this.onFavorite}
411
- favorites={favorites}
412
- onClear={this.clearSelection}
413
- >
414
- {this.options}
415
- </Select>
416
- );
417
- }
418
- }
419
- ```
420
-
421
- ### Validated selections
422
-
423
- To validate selections that users make, pass a validation state to the `validated` property. Validating selections can let users know if the selections they make would cause issues or errors.
424
-
425
- The example below passes an "error" state when you choose “select a title”, a "warning" state when you choose "other", and a "success" state for any other item selected from the menu.
426
-
427
- ```js
428
- import React from 'react';
429
- import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
430
-
431
- class ValidatedSelect extends React.Component {
432
- constructor(props) {
433
- super(props);
434
- this.options = [
435
- <SelectOption key={0} value="Select a title" isPlaceholder />,
436
- <SelectOption key={1} value="Mr" />,
437
- <SelectOption key={2} value="Miss" />,
438
- <SelectOption key={3} value="Mrs" />,
439
- <SelectOption key={4} value="Ms" />,
440
- <SelectOption key={5} value="Dr" />,
441
- <SelectOption key={6} value="Other" />
442
- ];
443
-
444
- this.toggleRef = React.createRef();
445
-
446
- this.state = {
447
- isOpen: false,
448
- selected: null,
449
- isDisabled: false,
450
- validated: 'default'
451
- };
452
-
453
- this.onToggle = (_event, isOpen) => {
454
- this.setState({
455
- isOpen
456
- });
457
- };
458
-
459
- this.onSelect = (event, selection, isPlaceholder) => {
460
- let validatedState = 'success';
461
- if (isPlaceholder) {
462
- this.clearSelection();
463
- validatedState = 'error';
464
- } else {
465
- if (selection === 'Other') {
466
- validatedState = 'warning';
467
- } else {
468
- validatedState = 'success';
469
- }
470
- this.setState({
471
- selected: selection,
472
- isOpen: false
473
- });
474
- console.log('selected:', selection);
475
- }
476
- this.setState({
477
- validated: validatedState
478
- });
479
- this.toggleRef.current.focus();
480
- };
481
-
482
- this.clearSelection = () => {
483
- this.setState({
484
- selected: null,
485
- isOpen: false
486
- });
487
- };
488
- }
489
-
490
- render() {
491
- const { isOpen, selected, isDisabled, direction, isToggleIcon, validated } = this.state;
492
- const titleId = 'select-validated-title';
493
- return (
494
- <div>
495
- <span id={titleId} hidden>
496
- Title
497
- </span>
498
- <Select
499
- variant={SelectVariant.single}
500
- toggleRef={this.toggleRef}
501
- placeholderText="Select an option"
502
- aria-label="Select Input with validation"
503
- onToggle={this.onToggle}
504
- onSelect={this.onSelect}
505
- selections={selected}
506
- isOpen={isOpen}
507
- aria-labelledby={titleId}
508
- isDisabled={isDisabled}
509
- validated={validated}
510
- aria-describedby="validated-helper"
511
- aria-invalid={validated === 'error' ? true : false}
512
- >
513
- {this.options}
514
- </Select>
515
- <div aria-live="polite" id="validated-helper" hidden>
516
- {validated}
517
- </div>
518
- </div>
519
- );
520
- }
521
- }
522
- ```
523
-
524
- ### Styled placeholder text
525
-
526
- To add a toggle label to a select, use the `placeholderText` property. The following example displays "Filter by status" in the toggle before a selection is made.
527
-
528
- To fade the color of `placeholderText` to gray, use the `hasPlaceholderStyle` property.
529
-
530
- ```js
531
- import React from 'react';
532
- import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
533
-
534
- function SelectWithPlaceholderStyle() {
535
- const [isOpen, setIsOpen] = React.useState(false);
536
- const [selected, setSelected] = React.useState([]);
537
-
538
- const options = [
539
- <SelectOption key={0} value="Active" />,
540
- <SelectOption key={1} value="Cancelled" />,
541
- <SelectOption key={2} value="Paused" />
542
- ];
543
-
544
- const onToggle = (_event, isOpen) => setIsOpen(isOpen);
545
-
546
- const onSelect = (event, selection, isPlaceholder) => {
547
- setSelected(selection);
548
- setIsOpen(false);
549
- };
550
-
551
- const clearSelection = () => {
552
- setSelected(null);
553
- setIsOpen(false);
554
- };
555
-
556
- const titleId = 'placeholder-style-select-id';
557
-
558
- return (
559
- <div>
560
- <span id={titleId} hidden>
561
- Placeholder styles
562
- </span>
563
- <Select
564
- variant={SelectVariant.single}
565
- hasPlaceholderStyle
566
- aria-label="Select input"
567
- onToggle={onToggle}
568
- onSelect={onSelect}
569
- onClear={clearSelection}
570
- selections={selected}
571
- isOpen={isOpen}
572
- placeholderText="Filter by status"
573
- aria-labelledby={titleId}
574
- >
575
- {options}
576
- </Select>
577
- </div>
578
- );
579
- }
580
- ```
581
-
582
- ### Placeholder select options
583
-
584
- To set a `<SelectOption>` as a placeholder, use the `isPlaceholder` property. The following example sets the "Filter by status" as a placeholder so that it is pre-selected.
585
-
586
- ```js
587
-
588
- import React from 'react';
589
- import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
590
-
591
- function SelectWithPlaceholderStyle() {
592
- const [isOpen, setIsOpen] = React.useState(false);
593
- const [selected, setSelected] = React.useState([]);
594
-
595
- const options = [
596
- <SelectOption key={0} value="Filter by status" isPlaceholder />,
597
- <SelectOption key={1} value="Active" />,
598
- <SelectOption key={2} value="Cancelled" />,
599
- <SelectOption key={3} value="Paused" />
600
- ];
601
-
602
- const onToggle = (_event, isOpen) => setIsOpen(isOpen);
603
-
604
- const onSelect = (event, selection, isPlaceholder) => {
605
- setSelected(selection);
606
- setIsOpen(false);
607
- };
608
-
609
- const clearSelection = () => {
610
- setSelected(null);
611
- setIsOpen(false);
612
- };
613
-
614
- const titleId = 'placeholder-style-select-option-id';
615
-
616
- return (
617
- <div>
618
- <span id={titleId} hidden>
619
- Placeholder styles - select option
620
- </span>
621
- <Select
622
- variant={SelectVariant.single}
623
- hasPlaceholderStyle
624
- aria-label="Select input"
625
- onToggle={onToggle}
626
- onSelect={onSelect}
627
- onClear={clearSelection}
628
- selections={selected}
629
- isOpen={isOpen}
630
- aria-labelledby={titleId}
631
- >
632
- {options}
633
- </Select>
634
- </div>
635
- );
636
- }
637
- ```
638
-
639
- ### With a footer
640
-
641
- You can add a `footer` to a `<Select>` list to hold actions that users can take on menu items.
642
-
643
- ```js
644
- import React from 'react';
645
- import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
646
- import { Select, SelectOption, SelectVariant, SelectDirection, Divider, Button } from '@patternfly/react-core';
647
-
648
- class SelectWithFooter extends React.Component {
649
- constructor(props) {
650
- super(props);
651
- this.options = [
652
- <SelectOption key={0} value="Select a title" isPlaceholder />,
653
- <SelectOption key={1} value="Mr" />,
654
- <SelectOption key={2} value="Miss" />,
655
- <SelectOption key={3} value="Mrs" />,
656
- <SelectOption key={4} value="Ms" />,
657
- <Divider component="li" key={5} />,
658
- <SelectOption key={6} value="Dr" />,
659
- <SelectOption key={7} value="Other" />
660
- ];
661
-
662
- this.toggleRef = React.createRef();
663
-
664
- this.state = {
665
- isToggleIcon: false,
666
- isOpen: false,
667
- selected: null,
668
- isDisabled: false,
669
- direction: SelectDirection.down
670
- };
671
-
672
- this.onToggle = (_event, isOpen) => {
673
- this.setState({
674
- isOpen
675
- });
676
- };
677
-
678
- this.onSelect = (event, selection, isPlaceholder) => {
679
- if (isPlaceholder) this.clearSelection();
680
- else {
681
- this.setState({
682
- selected: selection,
683
- isOpen: false
684
- });
685
- console.log('selected:', selection);
686
- this.toggleRef.current.focus();
687
- }
688
- };
689
-
690
- this.clearSelection = () => {
691
- this.setState({
692
- selected: null,
693
- isOpen: false
694
- });
695
- };
696
- }
697
-
698
- render() {
699
- const { isOpen, selected, isDisabled, direction, isToggleIcon } = this.state;
700
- const titleId = 'title-id-footer';
701
- return (
702
- <div>
703
- <span id={titleId} hidden>
704
- Title
705
- </span>
706
- <Select
707
- toggleIcon={isToggleIcon && <CubeIcon />}
708
- toggleRef={this.toggleRef}
709
- variant={SelectVariant.single}
710
- aria-label="Select Input"
711
- onToggle={this.onToggle}
712
- onSelect={this.onSelect}
713
- selections={selected}
714
- isOpen={isOpen}
715
- aria-labelledby={titleId}
716
- isDisabled={isDisabled}
717
- direction={direction}
718
- footer={
719
- <>
720
- <Button variant="link" isInline>
721
- Action
722
- </Button>
723
- </>
724
- }
725
- >
726
- {this.options}
727
- </Select>
728
- </div>
729
- );
730
- }
731
- }
732
- ```
733
-
734
- ### With view more
735
-
736
- To reduce the processing load for long select lists, replace overflow items with a "View more" link at the bottom of the select menu.
737
-
738
- Adjust the number of items shown above the "View more" link with the `numOptions` property. The following example passes 3 items into this property.
739
-
740
- ```js
741
- import React from 'react';
742
- import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
743
-
744
- class SelectViewMore extends React.Component {
745
- constructor(props) {
746
- super(props);
747
- this.options = [
748
- <SelectOption key={0} value="Select a title" isPlaceholder />,
749
- <SelectOption key={1} value="Mr" />,
750
- <SelectOption key={2} value="Miss" />,
751
- <SelectOption key={3} value="Mrs" />,
752
- <SelectOption key={4} value="Ms" />,
753
- <SelectOption key={5} value="Dr" />,
754
- <SelectOption key={6} value="Other" />
755
- ];
756
-
757
- this.toggleRef = React.createRef();
758
-
759
- this.state = {
760
- isOpen: false,
761
- selected: null,
762
- numOptions: 3,
763
- isLoading: false
764
- };
765
-
766
- this.onToggle = (_event, isOpen) => {
767
- this.setState({
768
- isOpen
769
- });
770
- };
771
-
772
- this.onSelect = (event, selection, isPlaceholder) => {
773
- if (isPlaceholder) this.clearSelection();
774
- else {
775
- this.setState({
776
- selected: selection,
777
- isOpen: false
778
- });
779
- console.log('selected:', selection);
780
- this.toggleRef.current.focus();
781
- }
782
- };
783
-
784
- this.clearSelection = () => {
785
- this.setState({
786
- selected: null,
787
- isOpen: false
788
- });
789
- };
790
-
791
- this.simulateNetworkCall = callback => {
792
- setTimeout(callback, 2000);
793
- };
794
-
795
- this.onViewMoreClick = () => {
796
- // Set select loadingVariant to spinner then simulate network call before loading more options
797
- this.setState({ isLoading: true });
798
- this.simulateNetworkCall(() => {
799
- const newLength =
800
- this.state.numOptions + 3 <= this.options.length ? this.state.numOptions + 3 : this.options.length;
801
- this.setState({ numOptions: newLength, isLoading: false });
802
- });
803
- };
804
- }
805
-
806
- render() {
807
- const { isOpen, selected, isToggleIcon, numOptions, loadingVariant, isLoading } = this.state;
808
- const titleId = 'title-id-view-more';
809
- return (
810
- <div>
811
- <span id={titleId} hidden>
812
- Title
813
- </span>
814
- <Select
815
- variant={SelectVariant.single}
816
- toggleRef={this.toggleRef}
817
- aria-label="Select Input"
818
- onToggle={this.onToggle}
819
- onSelect={this.onSelect}
820
- selections={selected}
821
- isOpen={isOpen}
822
- aria-labelledby={titleId}
823
- {...(!isLoading &&
824
- numOptions < this.options.length && {
825
- loadingVariant: { text: 'View more', onClick: this.onViewMoreClick }
826
- })}
827
- {...(isLoading && { loadingVariant: 'spinner' })}
828
- >
829
- {this.options.slice(0, numOptions)}
830
- </Select>
831
- </div>
832
- );
833
- }
834
- }
835
- ```
836
-
837
- ### Checkbox select
838
-
839
- To let users select multiple list options via checkbox input, use a checkbox select. To create a checkbox select, pass `variant={SelectVariant.checkbox}` into the `<Select>` component.
840
-
841
- By default, a badge is displayed in the menu toggle that indicates the number of items a user has selected.
842
-
843
- ```js
844
- import React from 'react';
845
- import { Select, SelectOption, SelectVariant, Divider } from '@patternfly/react-core';
846
-
847
- class CheckboxSelectInput extends React.Component {
848
- constructor(props) {
849
- super(props);
850
-
851
- this.state = {
852
- isOpen: false,
853
- selected: []
854
- };
855
-
856
- this.onToggle = (_event, isOpen) => {
857
- this.setState({
858
- isOpen
859
- });
860
- };
861
-
862
- this.onSelect = (event, selection) => {
863
- const { selected } = this.state;
864
- if (selected.includes(selection)) {
865
- this.setState(
866
- prevState => ({ selected: prevState.selected.filter(item => item !== selection) }),
867
- () => console.log('selections: ', this.state.selected)
868
- );
869
- } else {
870
- this.setState(
871
- prevState => ({ selected: [...prevState.selected, selection] }),
872
- () => console.log('selections: ', this.state.selected)
873
- );
874
- }
875
- };
876
-
877
- this.clearSelection = () => {
878
- this.setState({
879
- selected: []
880
- });
881
- };
882
-
883
- this.options = [
884
- <SelectOption key={0} value="Active" description="This is a description" />,
885
- <SelectOption key={1} value="Cancelled" />,
886
- <SelectOption key={2} value="Paused" />,
887
- <Divider key={3} />,
888
- <SelectOption key={4} value="Warning" />,
889
- <SelectOption key={5} value="Restarted" />
890
- ];
891
- }
892
-
893
- render() {
894
- const { isOpen, selected } = this.state;
895
- const titleId = 'checkbox-select-id';
896
- return (
897
- <div>
898
- <span id={titleId} hidden>
899
- Checkbox Title
900
- </span>
901
- <Select
902
- variant={SelectVariant.checkbox}
903
- aria-label="Select Input"
904
- onToggle={this.onToggle}
905
- onSelect={this.onSelect}
906
- selections={selected}
907
- isOpen={isOpen}
908
- placeholderText="Filter by status"
909
- aria-labelledby={titleId}
910
- >
911
- {this.options}
912
- </Select>
913
- </div>
914
- );
915
- }
916
- }
917
- ```
918
-
919
- ### Checkbox select with grouped items
920
-
921
- You can use groups alongside checkbox input. The item count badge will display the number of items selected across all groups.
922
-
923
- ```js
924
- import React from 'react';
925
- import { Select, SelectOption, SelectVariant, SelectGroup } from '@patternfly/react-core';
926
-
927
- class GroupedCheckboxSelectInput extends React.Component {
928
- constructor(props) {
929
- super(props);
930
- this.state = {
931
- isOpen: false,
932
- selected: []
933
- };
934
-
935
- this.onToggle = (_event, isOpen) => {
936
- this.setState({
937
- isOpen
938
- });
939
- };
940
-
941
- this.onSelect = (event, selection) => {
942
- const { selected } = this.state;
943
- if (selected.includes(selection)) {
944
- this.setState(
945
- prevState => ({ selected: prevState.selected.filter(item => item !== selection) }),
946
- () => console.log('selections: ', this.state.selected)
947
- );
948
- } else {
949
- this.setState(
950
- prevState => ({ selected: [...prevState.selected, selection] }),
951
- () => console.log('selections: ', this.state.selected)
952
- );
953
- }
954
- };
955
-
956
- this.clearSelection = () => {
957
- this.setState({
958
- selected: []
959
- });
960
- };
961
-
962
- this.options = [
963
- <SelectGroup label="Status" key="group1">
964
- <SelectOption key={0} value="Running" />
965
- <SelectOption key={1} value="Stopped" />
966
- <SelectOption key={2} value="Down" />
967
- <SelectOption key={3} value="Degraded" />
968
- <SelectOption key={4} value="Needs maintenance" />
969
- </SelectGroup>,
970
- <SelectGroup label="Vendor names" key="group2">
971
- <SelectOption key={5} value="Dell" />
972
- <SelectOption key={6} value="Samsung" isDisabled />
973
- <SelectOption key={7} value="Hewlett-Packard" />
974
- </SelectGroup>
975
- ];
976
- }
977
-
978
- render() {
979
- const { isOpen, selected } = this.state;
980
- const titleId = 'grouped-checkbox-select-id-1';
981
- return (
982
- <div>
983
- <span id={titleId} hidden>
984
- Grouped Checkbox Title
985
- </span>
986
- <Select
987
- variant={SelectVariant.checkbox}
988
- onToggle={this.onToggle}
989
- onSelect={this.onSelect}
990
- selections={selected}
991
- isOpen={isOpen}
992
- placeholderText="Filter by status"
993
- aria-labelledby={titleId}
994
- isGrouped
995
- >
996
- {this.options}
997
- </Select>
998
- </div>
999
- );
1000
- }
1001
- }
16
+ ```ts file="./SelectBasic.tsx"
1002
17
  ```
1003
18
 
1004
- ### Checkbox select with custom badge
1005
-
1006
- To change the default badge text for a checkbox select, use the `customBadgeText` property. The following example uses `customBadgeText` to display "all" in the badge once all menu items are selected.
1007
-
1008
- ```js
1009
- import React from 'react';
1010
- import { Select, SelectOption, SelectGroup, SelectVariant } from '@patternfly/react-core';
1011
-
1012
- class FilteringCheckboxSelectInputWithBadging extends React.Component {
1013
- constructor(props) {
1014
- super(props);
1015
-
1016
- this.state = {
1017
- isOpen: false,
1018
- selected: [],
1019
- customBadgeText: 0
1020
- };
1021
-
1022
- this.options = [
1023
- <SelectGroup label="Status" key="group1">
1024
- <SelectOption key={0} value="Running" />
1025
- <SelectOption key={1} value="Stopped" />
1026
- <SelectOption key={2} value="Down" />
1027
- <SelectOption key={3} value="Degraded" />
1028
- <SelectOption key={4} value="Needs maintenance" />
1029
- </SelectGroup>,
1030
- <SelectGroup label="Vendor names" key="group2">
1031
- <SelectOption key={5} value="Dell" />
1032
- <SelectOption key={6} value="Samsung" isDisabled />
1033
- <SelectOption key={7} value="Hewlett-Packard" />
1034
- </SelectGroup>
1035
- ];
1036
-
1037
- this.onToggle = (_event, isOpen) => {
1038
- this.setState({
1039
- isOpen
1040
- });
1041
- };
1042
-
1043
- this.onSelect = (event, selection) => {
1044
- const { selected } = this.state;
1045
- if (selected.includes(selection)) {
1046
- this.setState(
1047
- prevState => ({
1048
- selected: prevState.selected.filter(item => item !== selection),
1049
- customBadgeText: this.setBadgeText(prevState.selected.length - 1)
1050
- }),
1051
- () => console.log('selections: ', this.state.selected)
1052
- );
1053
- } else {
1054
- this.setState(
1055
- prevState => ({
1056
- selected: [...prevState.selected, selection],
1057
- customBadgeText: this.setBadgeText(prevState.selected.length + 1)
1058
- }),
1059
- () => console.log('selections: ', this.state.selected)
1060
- );
1061
- }
1062
- };
1063
-
1064
- this.onFilter = (_, textInput) => {
1065
- if (textInput === '') {
1066
- return this.options;
1067
- } else {
1068
- let filteredGroups = this.options
1069
- .map(group => {
1070
- let filteredGroup = React.cloneElement(group, {
1071
- children: group.props.children.filter(item => {
1072
- return item.props.value.toLowerCase().includes(textInput.toLowerCase());
1073
- })
1074
- });
1075
- if (filteredGroup.props.children.length > 0) return filteredGroup;
1076
- })
1077
- .filter(newGroup => newGroup);
1078
- return filteredGroups;
1079
- }
1080
- };
1081
-
1082
- this.clearSelection = () => {
1083
- this.setState({
1084
- selected: [],
1085
- customBadgeText: this.setBadgeText(0)
1086
- });
1087
- };
1088
-
1089
- this.setBadgeText = selected => {
1090
- if (selected === 7) {
1091
- return 'All';
1092
- }
1093
- if (selected === 0) {
1094
- return 0;
1095
- }
1096
- return null;
1097
- };
1098
- }
1099
-
1100
- render() {
1101
- const { isOpen, selected, filteredOptions, customBadgeText } = this.state;
1102
- const titleId = 'checkbox-filtering-custom-badging-select-id';
1103
- return (
1104
- <div>
1105
- <span id={titleId} hidden>
1106
- Checkbox Title
1107
- </span>
1108
- <Select
1109
- variant={SelectVariant.checkbox}
1110
- onToggle={this.onToggle}
1111
- onSelect={this.onSelect}
1112
- selections={selected}
1113
- isOpen={isOpen}
1114
- placeholderText="Filter by status"
1115
- aria-labelledby={titleId}
1116
- onFilter={this.onFilter}
1117
- onClear={this.clearSelection}
1118
- isGrouped
1119
- hasInlineFilter
1120
- customBadgeText={customBadgeText}
1121
- >
1122
- {this.options}
1123
- </Select>
1124
- </div>
1125
- );
1126
- }
1127
- }
1128
- ```
1129
-
1130
- ### Checkbox select without selected count
1131
-
1132
- To remove the default item count badge, use the `isCheckboxSelectionBadgeHidden` property.
1133
-
1134
- ```js
1135
- import React from 'react';
1136
- import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
1137
-
1138
- class CheckboxSelectInputNoBadge extends React.Component {
1139
- constructor(props) {
1140
- super(props);
1141
-
1142
- this.state = {
1143
- isOpen: false,
1144
- selected: []
1145
- };
1146
-
1147
- this.onToggle = (_event, isOpen) => {
1148
- this.setState({
1149
- isOpen
1150
- });
1151
- };
19
+ ### Grouped single
1152
20
 
1153
- this.onSelect = (event, selection) => {
1154
- const { selected } = this.state;
1155
- if (selected.includes(selection)) {
1156
- this.setState(
1157
- prevState => ({ selected: prevState.selected.filter(item => item !== selection) }),
1158
- () => console.log('selections: ', this.state.selected)
1159
- );
1160
- } else {
1161
- this.setState(
1162
- prevState => ({ selected: [...prevState.selected, selection] }),
1163
- () => console.log('selections: ', this.state.selected)
1164
- );
1165
- }
1166
- };
1167
-
1168
- this.clearSelection = () => {
1169
- this.setState({
1170
- selected: []
1171
- });
1172
- };
1173
-
1174
- this.options = [
1175
- <SelectOption key={0} value="Debug" />,
1176
- <SelectOption key={1} value="Info" />,
1177
- <SelectOption key={2} value="Warn" />,
1178
- <SelectOption key={3} value="Error" />
1179
- ];
1180
- }
1181
-
1182
- render() {
1183
- const { isOpen, selected } = this.state;
1184
- const titleId = 'checkbox-no-badge-select-id';
1185
- return (
1186
- <div>
1187
- <span id={titleId} hidden>
1188
- Checkbox Title
1189
- </span>
1190
- <Select
1191
- variant={SelectVariant.checkbox}
1192
- aria-label="Select Input"
1193
- onToggle={this.onToggle}
1194
- onSelect={this.onSelect}
1195
- selections={selected}
1196
- isCheckboxSelectionBadgeHidden
1197
- isOpen={isOpen}
1198
- placeholderText="Filter by status"
1199
- aria-labelledby={titleId}
1200
- >
1201
- {this.options}
1202
- </Select>
1203
- </div>
1204
- );
1205
- }
1206
- }
21
+ ```ts file="./SelectGrouped.tsx"
1207
22
  ```
1208
23
 
1209
- ### Checkbox select with item counts
1210
-
1211
- To show users the number of items that a `<SelectOption>` would match, use the `itemCount` property. The numerical value you pass into `itemCount` is displayed to the right of each menu item.
1212
-
1213
- ```js
1214
- import React from 'react';
1215
- import { Select, SelectOption, SelectVariant, Divider } from '@patternfly/react-core';
1216
-
1217
- class CheckboxSelectWithCounts extends React.Component {
1218
- constructor(props) {
1219
- super(props);
1220
-
1221
- this.state = {
1222
- isOpen: false,
1223
- selected: []
1224
- };
1225
-
1226
- this.onToggle = (_event, isOpen) => {
1227
- this.setState({
1228
- isOpen
1229
- });
1230
- };
1231
-
1232
- this.onSelect = (event, selection) => {
1233
- const { selected } = this.state;
1234
- if (selected.includes(selection)) {
1235
- this.setState(
1236
- prevState => ({ selected: prevState.selected.filter(item => item !== selection) }),
1237
- () => console.log('selections: ', this.state.selected)
1238
- );
1239
- } else {
1240
- this.setState(
1241
- prevState => ({ selected: [...prevState.selected, selection] }),
1242
- () => console.log('selections: ', this.state.selected)
1243
- );
1244
- }
1245
- };
1246
-
1247
- this.clearSelection = () => {
1248
- this.setState({
1249
- selected: []
1250
- });
1251
- };
1252
-
1253
- this.options = [
1254
- <SelectOption key={0} value="Active" description="This is a description" itemCount={3} />,
1255
- <SelectOption key={1} value="Cancelled" itemCount={1} />,
1256
- <SelectOption key={2} value="Paused" itemCount={15} />,
1257
- <SelectOption key={3} value="Warning" itemCount={2} />,
1258
- <SelectOption key={4} value="Restarted" itemCount={8} />
1259
- ];
1260
- }
24
+ ### Checkbox
1261
25
 
1262
- render() {
1263
- const { isOpen, selected } = this.state;
1264
- const titleId = 'checkbox-select-with-counts-id';
1265
- return (
1266
- <div>
1267
- <span id={titleId} hidden>
1268
- Checkbox With Counts Title
1269
- </span>
1270
- <Select
1271
- variant={SelectVariant.checkbox}
1272
- aria-label="Select Input"
1273
- onToggle={this.onToggle}
1274
- onSelect={this.onSelect}
1275
- selections={selected}
1276
- isOpen={isOpen}
1277
- placeholderText="Filter by status"
1278
- aria-labelledby={titleId}
1279
- >
1280
- {this.options}
1281
- </Select>
1282
- </div>
1283
- );
1284
- }
1285
- }
1286
- ```
1287
-
1288
- ### Checkbox select with a footer
1289
-
1290
- You can combine a footer with checkbox input to allow users to apply an action to multiple items.
1291
-
1292
- ```js
1293
- import React from 'react';
1294
- import { Select, SelectOption, SelectVariant, Button } from '@patternfly/react-core';
1295
-
1296
- class SelectWithFooterCheckbox extends React.Component {
1297
- constructor(props) {
1298
- super(props);
1299
- this.state = {
1300
- isOpen: false,
1301
- selected: [],
1302
- numOptions: 3,
1303
- isLoading: false
1304
- };
1305
-
1306
- this.toggleRef = React.createRef();
1307
-
1308
- this.options = [
1309
- <SelectOption key={0} value="Active" description="This is a description" />,
1310
- <SelectOption key={1} value="Cancelled" />,
1311
- <SelectOption key={2} value="Paused" />,
1312
- <SelectOption key={4} value="Warning" />,
1313
- <SelectOption key={5} value="Restarted" />
1314
- ];
1315
-
1316
- this.onToggle = (_event, isOpen) => {
1317
- this.setState({ isOpen });
1318
- };
1319
-
1320
- this.onSelect = (event, selection) => {
1321
- this.setState({ selected: selection, isOpen: false }), console.log('selected: ', selection);
1322
- this.toggleRef.current.focus();
1323
- };
1324
-
1325
- this.onFilter = (_, textInput) => {
1326
- if (textInput === '') {
1327
- return this.options;
1328
- } else {
1329
- this.setState(
1330
- prevState => ({ selected: [...prevState.selected, selection] }),
1331
- () => console.log('selections: ', this.state.selected)
1332
- );
1333
- }
1334
- };
1335
-
1336
- this.clearSelection = () => {
1337
- this.setState({
1338
- selected: []
1339
- });
1340
- };
1341
- }
1342
-
1343
- render() {
1344
- const { isOpen, selected, isDisabled, direction, isToggleIcon } = this.state;
1345
- const titleId = 'title-id-footer-checkbox';
1346
- return (
1347
- <div>
1348
- <span id={titleId} hidden>
1349
- Title
1350
- </span>
1351
- <Select
1352
- variant={SelectVariant.single}
1353
- toggleRef={this.toggleRef}
1354
- onToggle={this.onToggle}
1355
- onSelect={this.onSelect}
1356
- selections={selected}
1357
- isOpen={isOpen}
1358
- placeholderText="Filter by status"
1359
- aria-labelledby={titleId}
1360
- footer={
1361
- <Button variant="link" isInline>
1362
- Action
1363
- </Button>
1364
- }
1365
- >
1366
- {this.options}
1367
- </Select>
1368
- </div>
1369
- );
1370
- }
1371
- }
1372
- ```
1373
-
1374
- ### Checkbox select with view more
1375
-
1376
- When a "view more" link is used alongside checkbox input, selections that users make prior to clicking "view more" are persisted after the click.
1377
-
1378
- ```js
1379
- import React from 'react';
1380
- import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
1381
-
1382
- class SelectViewMoreCheckbox extends React.Component {
1383
- constructor(props) {
1384
- super(props);
1385
-
1386
- this.state = {
1387
- isOpen: false,
1388
- selected: [],
1389
- numOptions: 3,
1390
- isLoading: false
1391
- };
1392
-
1393
- this.options = [
1394
- <SelectOption key={0} value="Active" description="This is a description" />,
1395
- <SelectOption key={1} value="Cancelled" />,
1396
- <SelectOption key={2} value="Paused" />,
1397
- <SelectOption key={4} value="Warning" />,
1398
- <SelectOption key={5} value="Restarted" />,
1399
- <SelectOption key={6} value="Down" />,
1400
- <SelectOption key={7} value="Disabled" />,
1401
- <SelectOption key={8} value="Needs maintenance " />,
1402
- <SelectOption key={9} value="Degraded " />
1403
- ];
1404
-
1405
- this.onToggle = (_event, isOpen) => {
1406
- this.setState({
1407
- isOpen
1408
- });
1409
- };
1410
-
1411
- this.onSelect = (event, selection) => {
1412
- const { selected } = this.state;
1413
- if (selected.includes(selection)) {
1414
- this.setState(
1415
- prevState => ({ selected: prevState.selected.filter(item => item !== selection) }),
1416
- () => console.log('selections: ', this.state.selected)
1417
- );
1418
- } else {
1419
- this.setState(
1420
- prevState => ({ selected: [...prevState.selected, selection] }),
1421
- () => console.log('selections: ', this.state.selected)
1422
- );
1423
- }
1424
- };
1425
-
1426
- this.clearSelection = () => {
1427
- this.setState({
1428
- selected: []
1429
- });
1430
- };
1431
-
1432
- this.simulateNetworkCall = callback => {
1433
- setTimeout(callback, 2000);
1434
- };
1435
-
1436
- this.onViewMoreClick = () => {
1437
- // Set select loadingVariant to spinner then simulate network call before loading more options
1438
- this.setState({ isLoading: true });
1439
- this.simulateNetworkCall(() => {
1440
- const newLength =
1441
- this.state.numOptions + 3 <= this.options.length ? this.state.numOptions + 3 : this.options.length;
1442
- this.setState({ numOptions: newLength, isLoading: false });
1443
- });
1444
- };
1445
- }
1446
-
1447
- render() {
1448
- const { isOpen, selected, numOptions, isLoading } = this.state;
1449
- const titleId = 'view-more-checkbox-select-id';
1450
- return (
1451
- <div>
1452
- <span id={titleId} hidden>
1453
- Checkbox View more check
1454
- </span>
1455
- <Select
1456
- variant={SelectVariant.checkbox}
1457
- aria-label="Select input"
1458
- onToggle={this.onToggle}
1459
- onSelect={this.onSelect}
1460
- selections={selected}
1461
- isOpen={isOpen}
1462
- placeholderText="Filter by status"
1463
- aria-labelledby={titleId}
1464
- {...(!isLoading &&
1465
- numOptions < this.options.length && {
1466
- loadingVariant: { text: 'View more', onClick: this.onViewMoreClick }
1467
- })}
1468
- {...(isLoading && { loadingVariant: 'spinner' })}
1469
- >
1470
- {this.options.slice(0, numOptions)}
1471
- </Select>
1472
- </div>
1473
- );
1474
- }
1475
- }
1476
- ```
1477
-
1478
- ### Filtering with placeholder text
1479
-
1480
- To preload a filter search bar with placeholder text, use the `inlineFilterPlaceholderText` property. The following example preloads the search bar with "Filter by status".
1481
-
1482
- ```js
1483
- import React from 'react';
1484
- import { Select, SelectOption, SelectGroup, SelectVariant } from '@patternfly/react-core';
1485
-
1486
- class FilteringCheckboxSelectInputWithPlaceholder extends React.Component {
1487
- constructor(props) {
1488
- super(props);
1489
-
1490
- this.state = {
1491
- isOpen: false,
1492
- selected: []
1493
- };
1494
-
1495
- this.options = [
1496
- <SelectGroup label="Status" key="group1">
1497
- <SelectOption key={0} value="Running" />
1498
- <SelectOption key={1} value="Stopped" />
1499
- <SelectOption key={2} value="Down" />
1500
- <SelectOption key={3} value="Degraded" />
1501
- <SelectOption key={4} value="Needs maintenance" />
1502
- </SelectGroup>,
1503
- <SelectGroup label="Vendor names" key="group2">
1504
- <SelectOption key={5} value="Dell" />
1505
- <SelectOption key={6} value="Samsung" isDisabled />
1506
- <SelectOption key={7} value="Hewlett-Packard" />
1507
- </SelectGroup>
1508
- ];
1509
-
1510
- this.onToggle = (_event, isOpen) => {
1511
- this.setState({
1512
- isOpen
1513
- });
1514
- };
1515
-
1516
- this.onSelect = (event, selection) => {
1517
- const { selected } = this.state;
1518
- if (selected.includes(selection)) {
1519
- this.setState(
1520
- prevState => ({ selected: prevState.selected.filter(item => item !== selection) }),
1521
- () => console.log('selections: ', this.state.selected)
1522
- );
1523
- } else {
1524
- this.setState(
1525
- prevState => ({ selected: [...prevState.selected, selection] }),
1526
- () => console.log('selections: ', this.state.selected)
1527
- );
1528
- }
1529
- };
1530
-
1531
- this.onFilter = (_, textInput) => {
1532
- if (textInput === '') {
1533
- return this.options;
1534
- } else {
1535
- let filteredGroups = this.options
1536
- .map(group => {
1537
- let filteredGroup = React.cloneElement(group, {
1538
- children: group.props.children.filter(item => {
1539
- return item.props.value.toLowerCase().includes(textInput.toLowerCase());
1540
- })
1541
- });
1542
- if (filteredGroup.props.children.length > 0) return filteredGroup;
1543
- })
1544
- .filter(newGroup => newGroup);
1545
- return filteredGroups;
1546
- }
1547
- };
1548
-
1549
- this.clearSelection = () => {
1550
- this.setState({
1551
- selected: []
1552
- });
1553
- };
1554
- }
1555
-
1556
- render() {
1557
- const { isOpen, selected, filteredOptions } = this.state;
1558
- const titleId = 'checkbox-filtering-with-placeholder-select-id';
1559
- return (
1560
- <div>
1561
- <span id={titleId} hidden>
1562
- Checkbox Title
1563
- </span>
1564
- <Select
1565
- variant={SelectVariant.checkbox}
1566
- onToggle={this.onToggle}
1567
- onSelect={this.onSelect}
1568
- selections={selected}
1569
- isOpen={isOpen}
1570
- placeholderText="Filter by status"
1571
- aria-labelledby={titleId}
1572
- onFilter={this.onFilter}
1573
- onClear={this.clearSelection}
1574
- isGrouped
1575
- hasInlineFilter
1576
- inlineFilterPlaceholderText="Filter by status"
1577
- >
1578
- {this.options}
1579
- </Select>
1580
- </div>
1581
- );
1582
- }
1583
- }
1584
- ```
1585
-
1586
- ### Inline filtering
1587
-
1588
- To allow users to filter select lists using text input, use the `hasInlineFilter` property. Filtering behavior can be further customized with other properties, as shown in the example below. Select each checkbox to visualize the following behavior:
1589
-
1590
- - To persist filter results on blur, use the `isInputValuePersisted` property.
1591
- - To persist a filter that a user has searched, use the `isInputFilterPersisted` property.
1592
- - To allow users to add new items to a select list, use the `isCreatable` property. When this property is applied and a user searches for an option that doesn't exist, they will be prompted to "create" the item.
1593
-
1594
- ```js
1595
- import React from 'react';
1596
- import { Select, SelectOption, SelectGroup, SelectVariant, Checkbox } from '@patternfly/react-core';
1597
-
1598
- class FilteringSingleSelectInput extends React.Component {
1599
- constructor(props) {
1600
- super(props);
1601
-
1602
- this.state = {
1603
- isOpen: false,
1604
- selected: '',
1605
- isCreatable: false,
1606
- isInputValuePersisted: false,
1607
- isInputFilterPersisted: false
1608
- };
1609
-
1610
- this.options = [
1611
- <SelectGroup label="Status" key="group1">
1612
- <SelectOption key={0} value="Running" />
1613
- <SelectOption key={1} value="Stopped" />
1614
- <SelectOption key={2} value="Down" />
1615
- <SelectOption key={3} value="Degraded" />
1616
- <SelectOption key={4} value="Needs maintenance" />
1617
- </SelectGroup>,
1618
- <SelectGroup label="Vendor names" key="group2">
1619
- <SelectOption key={5} value="Dell" />
1620
- <SelectOption key={6} value="Samsung" isDisabled />
1621
- <SelectOption key={7} value="Hewlett-Packard" />
1622
- </SelectGroup>
1623
- ];
1624
-
1625
- this.onToggle = (_event, isOpen) => {
1626
- this.setState({
1627
- isOpen
1628
- });
1629
- };
1630
-
1631
- this.onSelect = (event, selection) => {
1632
- this.setState({ selected: selection, isOpen: false }), console.log('selected: ', selection);
1633
- };
1634
-
1635
- this.onFilter = (_, textInput) => {
1636
- if (textInput === '') {
1637
- return this.options;
1638
- } else {
1639
- let filteredGroups = this.options
1640
- .map(group => {
1641
- let filteredGroup = React.cloneElement(group, {
1642
- children: group.props.children.filter(item => {
1643
- return item.props.value.toLowerCase().includes(textInput.toLowerCase());
1644
- })
1645
- });
1646
- if (filteredGroup.props.children.length > 0) return filteredGroup;
1647
- })
1648
- .filter(Boolean);
1649
- return filteredGroups;
1650
- }
1651
- };
1652
-
1653
- this.toggleCreatable = (_, checked) => {
1654
- this.setState({
1655
- isCreatable: checked
1656
- });
1657
- };
1658
-
1659
- this.toggleInputValuePersisted = (_, checked) => {
1660
- this.setState({
1661
- isInputValuePersisted: checked
1662
- });
1663
- };
1664
-
1665
- this.toggleInputFilterPersisted = (_, checked) => {
1666
- this.setState({
1667
- isInputFilterPersisted: checked
1668
- });
1669
- };
1670
- }
1671
-
1672
- render() {
1673
- const {
1674
- isOpen,
1675
- selected,
1676
- filteredOptions,
1677
- isInputValuePersisted,
1678
- isInputFilterPersisted,
1679
- isCreatable
1680
- } = this.state;
1681
- const titleId = 'single-filtering-select-id';
1682
- return (
1683
- <div>
1684
- <span id={titleId} hidden>
1685
- Single select with filter
1686
- </span>
1687
- <Select
1688
- variant={SelectVariant.single}
1689
- onToggle={this.onToggle}
1690
- onSelect={this.onSelect}
1691
- selections={selected}
1692
- isOpen={isOpen}
1693
- placeholderText="Filter by status"
1694
- aria-labelledby={titleId}
1695
- onFilter={this.onFilter}
1696
- isGrouped
1697
- hasInlineFilter
1698
- isCreatable={isCreatable}
1699
- isInputValuePersisted={isInputValuePersisted}
1700
- isInputFilterPersisted={isInputFilterPersisted}
1701
- >
1702
- {this.options}
1703
- </Select>
1704
- <Checkbox
1705
- label="isInputValuePersisted"
1706
- isChecked={isInputValuePersisted}
1707
- onChange={this.toggleInputValuePersisted}
1708
- aria-label="toggle input value persisted"
1709
- id="toggle-inline-filter-input-value-persisted"
1710
- name="toggle-inline-filter-input-value-persisted"
1711
- />
1712
- <Checkbox
1713
- label="isInputFilterPersisted"
1714
- isChecked={isInputFilterPersisted}
1715
- onChange={this.toggleInputFilterPersisted}
1716
- aria-label="toggle input filter persisted"
1717
- id="toggle-inline-filter-input-filter-persisted"
1718
- name="toggle-inline-filter-input-filter-persisted"
1719
- />
1720
- <Checkbox
1721
- label="isCreatable"
1722
- isChecked={this.state.isCreatable}
1723
- onChange={this.toggleCreatable}
1724
- aria-label="toggle creatable checkbox"
1725
- id="toggle-inline-filter-creatable-typeahead"
1726
- name="toggle-inline-filter-creatable-typeahead"
1727
- />
1728
- </div>
1729
- );
1730
- }
1731
- }
26
+ ```ts file="./SelectCheckbox.tsx"
1732
27
  ```
1733
28
 
1734
29
  ### Typeahead
1735
30
 
1736
- Typeahead is a select variant that replaces the typical button toggle for opening the select menu with a text input and button toggle combo. As a user types in the text input, the select menu will provide suggestions by filtering the select options.
1737
-
1738
- To make a typeahead, pass `variant=typeahead` into the `<Select>` component. To specify a label for the input field, use the `typeAheadAriaLabel` property.
1739
-
1740
- A few additional customization options are shown in the example below. Select each checkbox to visualize the following behavior:
1741
-
1742
- - To place a created item at the top of a typeahead list use the `isCreateOptionOnTop` property.
1743
- - To trigger a callback for newly created items, use the `onCreateOption` property.
1744
- - To reset the typeahead value after a user makes a selection, use the `shouldResetOnSelect` property.
1745
-
1746
- ```js
1747
- import React from 'react';
1748
- import { Checkbox, Select, SelectOption, SelectVariant } from '@patternfly/react-core';
1749
-
1750
- class TypeaheadSelectInput extends React.Component {
1751
- constructor(props) {
1752
- super(props);
1753
- this.defaultOptions = [
1754
- { value: 'Alabama' },
1755
- { value: 'Florida', description: 'This is a description' },
1756
- { value: 'New Jersey' },
1757
- { value: 'New Mexico' },
1758
- { value: 'New York' },
1759
- { value: 'North Carolina' }
1760
- ];
1761
-
1762
- this.state = {
1763
- options: this.defaultOptions,
1764
- isOpen: false,
1765
- selected: null,
1766
- isDisabled: false,
1767
- isCreatable: false,
1768
- isCreateOptionOnTop: false,
1769
- isInputValuePersisted: false,
1770
- isInputFilterPersisted: false,
1771
- hasOnCreateOption: false,
1772
- resetOnSelect: true
1773
- };
1774
-
1775
- this.onToggle = (_event, isOpen) => {
1776
- this.setState({
1777
- isOpen
1778
- });
1779
- };
1780
-
1781
- this.onSelect = (event, selection, isPlaceholder) => {
1782
- if (isPlaceholder) this.clearSelection();
1783
- else {
1784
- this.setState({
1785
- selected: selection,
1786
- isOpen: this.state.resetOnSelect ? false : this.state.isOpen
1787
- });
1788
- console.log('selected:', selection);
1789
- }
1790
- };
1791
-
1792
- this.onCreateOption = newValue => {
1793
- this.setState({
1794
- options: [...this.state.options, { value: newValue }]
1795
- });
1796
- };
1797
-
1798
- this.clearSelection = () => {
1799
- this.setState({
1800
- selected: null,
1801
- isOpen: false,
1802
- options: this.defaultOptions
1803
- });
1804
- };
1805
-
1806
- this.toggleDisabled = checked => {
1807
- this.setState({
1808
- isDisabled: checked
1809
- });
1810
- };
1811
-
1812
- this.toggleCreatable = checked => {
1813
- this.setState({
1814
- isCreatable: checked
1815
- });
1816
- };
1817
-
1818
- this.toggleCreateOptionOnTop = checked => {
1819
- this.setState({
1820
- isCreateOptionOnTop: checked
1821
- });
1822
- };
1823
-
1824
- this.toggleCreateNew = checked => {
1825
- this.setState({
1826
- hasOnCreateOption: checked
1827
- });
1828
- };
1829
-
1830
- this.toggleInputValuePersisted = checked => {
1831
- this.setState({
1832
- isInputValuePersisted: checked
1833
- });
1834
- };
1835
-
1836
- this.toggleInputFilterPersisted = checked => {
1837
- this.setState({
1838
- isInputFilterPersisted: checked
1839
- });
1840
- };
1841
-
1842
- this.toggleResetOnSelect = checked => {
1843
- this.setState({
1844
- resetOnSelect: checked
1845
- });
1846
- };
1847
- }
1848
-
1849
- render() {
1850
- const {
1851
- isOpen,
1852
- selected,
1853
- isDisabled,
1854
- isCreatable,
1855
- isCreateOptionOnTop,
1856
- hasOnCreateOption,
1857
- isInputValuePersisted,
1858
- isInputFilterPersisted,
1859
- resetOnSelect,
1860
- options
1861
- } = this.state;
1862
- const titleId = 'typeahead-select-id-1';
1863
- return (
1864
- <div>
1865
- <span id={titleId} hidden>
1866
- Select a state
1867
- </span>
1868
- <Select
1869
- variant={SelectVariant.typeahead}
1870
- typeAheadAriaLabel="Select a state"
1871
- onToggle={this.onToggle}
1872
- onSelect={this.onSelect}
1873
- onClear={this.clearSelection}
1874
- selections={selected}
1875
- isOpen={isOpen}
1876
- aria-labelledby={titleId}
1877
- isInputValuePersisted={isInputValuePersisted}
1878
- isInputFilterPersisted={isInputFilterPersisted}
1879
- placeholderText="Select a state"
1880
- isDisabled={isDisabled}
1881
- isCreatable={isCreatable}
1882
- isCreateOptionOnTop={isCreateOptionOnTop}
1883
- onCreateOption={(hasOnCreateOption && this.onCreateOption) || undefined}
1884
- shouldResetOnSelect={resetOnSelect}
1885
- >
1886
- {options.map((option, index) => (
1887
- <SelectOption
1888
- isDisabled={option.disabled}
1889
- key={index}
1890
- value={option.value}
1891
- {...(option.description && { description: option.description })}
1892
- />
1893
- ))}
1894
- </Select>
1895
- <Checkbox
1896
- label="isDisabled"
1897
- isChecked={this.state.isDisabled}
1898
- onChange={(_event, checked) => this.toggleDisabled(checked)}
1899
- aria-label="toggle disabled checkbox"
1900
- id="toggle-disabled-typeahead"
1901
- name="toggle-disabled-typeahead"
1902
- />
1903
- <Checkbox
1904
- label="isCreatable"
1905
- isChecked={this.state.isCreatable}
1906
- onChange={(_event, checked) => this.toggleCreatable(checked)}
1907
- aria-label="toggle creatable checkbox"
1908
- id="toggle-creatable-typeahead"
1909
- name="toggle-creatable-typeahead"
1910
- />
1911
- <Checkbox
1912
- label="isCreateOptionOnTop"
1913
- isChecked={this.state.isCreateOptionOnTop}
1914
- onChange={(_event, checked) => this.toggleCreateOptionOnTop(checked)}
1915
- aria-label="toggle createOptionOnTop checkbox"
1916
- id="toggle-create-option-on-top-typeahead"
1917
- name="toggle-create-option-on-top-typeahead"
1918
- />
1919
- <Checkbox
1920
- label="onCreateOption"
1921
- isChecked={this.state.hasOnCreateOption}
1922
- onChange={(_event, checked) => this.toggleCreateNew(checked)}
1923
- aria-label="toggle new checkbox"
1924
- id="toggle-new-typeahead"
1925
- name="toggle-new-typeahead"
1926
- />
1927
- <Checkbox
1928
- label="isInputValuePersisted"
1929
- isChecked={isInputValuePersisted}
1930
- onChange={(_event, checked) => this.toggleInputValuePersisted(checked)}
1931
- aria-label="toggle input value persisted"
1932
- id="toggle-input-value-persisted"
1933
- name="toggle-input-value-persisted"
1934
- />
1935
- <Checkbox
1936
- label="isInputFilterPersisted"
1937
- isChecked={isInputFilterPersisted}
1938
- onChange={(_event, checked) => this.toggleInputFilterPersisted(checked)}
1939
- aria-label="toggle input filter persisted"
1940
- id="toggle-input-filter-persisted"
1941
- name="toggle-input-filter-persisted"
1942
- />
1943
- <Checkbox
1944
- label="shouldResetOnSelect"
1945
- isChecked={this.state.resetOnSelect}
1946
- onChange={(_event, checked) => this.toggleResetOnSelect(checked)}
1947
- aria-label="toggle reset checkbox"
1948
- id="toggle-reset-typeahead"
1949
- name="toggle-reset-typeahead"
1950
- />
1951
- </div>
1952
- );
1953
- }
1954
- }
1955
- ```
1956
-
1957
- ### Grouped typeahead
1958
-
1959
- Typeahead matches items with user input across groups.
1960
-
1961
- ```js
1962
- import React from 'react';
1963
- import { Checkbox, Select, SelectGroup, SelectOption, SelectVariant, Divider } from '@patternfly/react-core';
1964
-
1965
- class GroupedTypeaheadSelectInput extends React.Component {
1966
- constructor(props) {
1967
- super(props);
1968
-
1969
- this.state = {
1970
- options: [
1971
- <SelectGroup label="Status" key="group1">
1972
- <SelectOption key={0} value="Running" />
1973
- <SelectOption key={1} value="Stopped" />
1974
- <SelectOption key={2} value="Down" />
1975
- <SelectOption key={3} value="Degraded" />
1976
- <SelectOption key={4} value="Needs maintenance" />
1977
- </SelectGroup>,
1978
- <Divider key="divider" />,
1979
- <SelectGroup label="Vendor names" key="group2">
1980
- <SelectOption key={5} value="Dell" />
1981
- <SelectOption key={6} value="Samsung" isDisabled />
1982
- <SelectOption key={7} value="Hewlett-Packard" />
1983
- </SelectGroup>
1984
- ],
1985
- newOptions: [],
1986
- isOpen: false,
1987
- selected: null,
1988
- isCreatable: false,
1989
- hasOnCreateOption: false
1990
- };
1991
-
1992
- this.onToggle = (_event, isOpen) => {
1993
- this.setState({
1994
- isOpen
1995
- });
1996
- };
1997
-
1998
- this.onSelect = (event, selection, isPlaceholder) => {
1999
- if (isPlaceholder) this.clearSelection();
2000
- else {
2001
- this.setState({
2002
- selected: selection,
2003
- isOpen: false
2004
- });
2005
- console.log('selected:', selection);
2006
- }
2007
- };
2008
-
2009
- this.onCreateOption = newValue => {
2010
- this.setState({
2011
- newOptions: [...this.state.newOptions, <SelectOption key={newValue} value={newValue} />]
2012
- });
2013
- };
2014
-
2015
- this.clearSelection = () => {
2016
- this.setState({
2017
- selected: null,
2018
- isOpen: false
2019
- });
2020
- };
2021
-
2022
- this.toggleCreatable = checked => {
2023
- this.setState({
2024
- isCreatable: checked
2025
- });
2026
- };
2027
-
2028
- this.toggleCreateNew = checked => {
2029
- this.setState({
2030
- hasOnCreateOption: checked
2031
- });
2032
- };
2033
- }
2034
-
2035
- render() {
2036
- const { isOpen, selected, isDisabled, isCreatable, hasOnCreateOption, options, newOptions } = this.state;
2037
- const titleId = 'grouped-typeahead-select-id';
2038
- const allOptions =
2039
- newOptions.length > 0
2040
- ? options.concat(
2041
- <SelectGroup label="Created" key="create-group">
2042
- {newOptions}
2043
- </SelectGroup>
2044
- )
2045
- : options;
2046
- return (
2047
- <div>
2048
- <span id={titleId} hidden>
2049
- Select a state
2050
- </span>
2051
- <Select
2052
- variant={SelectVariant.typeahead}
2053
- typeAheadAriaLabel="Select a state"
2054
- onToggle={this.onToggle}
2055
- onSelect={this.onSelect}
2056
- onClear={this.clearSelection}
2057
- selections={selected}
2058
- isOpen={isOpen}
2059
- aria-labelledby={titleId}
2060
- placeholderText="Select a state"
2061
- isGrouped
2062
- isCreatable={isCreatable}
2063
- onCreateOption={(hasOnCreateOption && this.onCreateOption) || undefined}
2064
- >
2065
- {allOptions}
2066
- </Select>
2067
- <Checkbox
2068
- label="isCreatable"
2069
- isChecked={this.state.isCreatable}
2070
- onChange={(_event, checked) => this.toggleCreatable(checked)}
2071
- aria-label="toggle creatable checkbox"
2072
- id="toggle-creatable-grouped-typeahead"
2073
- name="toggle-creatable-grouped-typeahead"
2074
- />
2075
- <Checkbox
2076
- label="onCreateOption"
2077
- isChecked={this.state.hasOnCreateOption}
2078
- onChange={(_event, checked) => this.toggleCreateNew(checked)}
2079
- aria-label="toggle new checkbox"
2080
- id="toggle-new-grouped-typeahead"
2081
- name="toggle-new-grouped-typeahead"
2082
- />
2083
- </div>
2084
- );
2085
- }
2086
- }
2087
- ```
2088
-
2089
- ### Typeahead with custom filtering
2090
-
2091
- You can add custom filtering to a select list to better fit needs that aren't covered by inline filtering. If you use custom filtering, use the `onFilter` property to trigger a callback with your custom filter implementation.
2092
-
2093
- ```js
2094
- import React from 'react';
2095
- import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
2096
-
2097
- class TypeaheadSelectInput extends React.Component {
2098
- constructor(props) {
2099
- super(props);
2100
- this.options = [
2101
- <SelectOption key={0} value="Alabama" />,
2102
- <SelectOption key={1} value="Florida" />,
2103
- <SelectOption key={2} value="New Jersey" />,
2104
- <SelectOption key={3} value="New Mexico" />,
2105
- <SelectOption key={4} value="New York" />,
2106
- <SelectOption key={5} value="North Carolina" />
2107
- ];
2108
- this.state = {
2109
- isOpen: false,
2110
- selected: null
2111
- };
2112
-
2113
- this.onToggle = (_event, isOpen) => {
2114
- this.setState({
2115
- isOpen
2116
- });
2117
- };
2118
-
2119
- this.onSelect = (event, selection, isPlaceholder) => {
2120
- if (isPlaceholder) this.clearSelection();
2121
- else {
2122
- this.setState({
2123
- selected: selection,
2124
- isOpen: false
2125
- });
2126
- console.log('selected:', selection);
2127
- }
2128
- };
2129
-
2130
- this.clearSelection = () => {
2131
- this.setState({
2132
- selected: null,
2133
- isOpen: false
2134
- });
2135
- };
2136
-
2137
- this.customFilter = (_, value) => {
2138
- if (!value) {
2139
- return this.options;
2140
- }
2141
-
2142
- const input = new RegExp(value, 'i');
2143
- return this.options.filter(child => input.test(child.props.value));
2144
- };
2145
- }
2146
-
2147
- render() {
2148
- const { isOpen, selected } = this.state;
2149
- const titleId = 'typeahead-select-id-2';
2150
- return (
2151
- <div>
2152
- <span id={titleId} hidden>
2153
- Select a state
2154
- </span>
2155
- <Select
2156
- variant={SelectVariant.typeahead}
2157
- typeAheadAriaLabel="Select a state"
2158
- onToggle={this.onToggle}
2159
- onSelect={this.onSelect}
2160
- onClear={this.clearSelection}
2161
- onFilter={this.customFilter}
2162
- selections={selected}
2163
- isOpen={isOpen}
2164
- aria-labelledby={titleId}
2165
- placeholderText="Select a state"
2166
- >
2167
- {this.options}
2168
- </Select>
2169
- </div>
2170
- );
2171
- }
2172
- }
31
+ ```ts file="./SelectTypeahead.tsx"
2173
32
  ```
2174
33
 
2175
- ### Multiple typeahead
2176
-
2177
- To create a multiple typeahead select variant, pass `variant={SelectVariant.typeaheadMulti}` into the `<Select>` component. Multiple typeaheads let users select multiple items from a select list. Selected items appear as chips in the select toggle.
2178
-
2179
- When many items are selected, you can hide overflowing items under a "more" button. The following example hides items after more than 3 are selected. To show hidden items, select the “more” button. Click "show less" to hide extra items again.
2180
-
2181
- ```js
2182
- import React from 'react';
2183
- import { Checkbox, Select, SelectOption, SelectVariant } from '@patternfly/react-core';
2184
-
2185
- class MultiTypeaheadSelectInput extends React.Component {
2186
- constructor(props) {
2187
- super(props);
2188
-
2189
- this.state = {
2190
- options: [
2191
- { value: 'Alabama', disabled: false },
2192
- { value: 'Florida', disabled: false },
2193
- { value: 'New Jersey', disabled: false },
2194
- { value: 'New Mexico', disabled: false, description: 'This is a description' },
2195
- { value: 'New York', disabled: false },
2196
- { value: 'North Carolina', disabled: false }
2197
- ],
2198
- isOpen: false,
2199
- selected: [],
2200
- isCreatable: false,
2201
- hasOnCreateOption: false,
2202
- hasDisabledOption: false,
2203
- resetOnSelect: true
2204
- };
2205
-
2206
- this.onCreateOption = newValue => {
2207
- this.setState({
2208
- options: [...this.state.options, { value: newValue }]
2209
- });
2210
- };
2211
-
2212
- this.onToggle = (_event, isOpen) => {
2213
- this.setState({
2214
- isOpen
2215
- });
2216
- };
2217
-
2218
- this.onSelect = (event, selection) => {
2219
- const { selected } = this.state;
2220
- if (selected.includes(selection)) {
2221
- this.setState(
2222
- prevState => ({ selected: prevState.selected.filter(item => item !== selection) }),
2223
- () => console.log('selections: ', this.state.selected)
2224
- );
2225
- } else {
2226
- this.setState(
2227
- prevState => ({ selected: [...prevState.selected, selection] }),
2228
- () => console.log('selections: ', this.state.selected)
2229
- );
2230
- }
2231
- };
2232
-
2233
- this.clearSelection = () => {
2234
- this.setState({
2235
- selected: [],
2236
- isOpen: false
2237
- });
2238
- };
2239
-
2240
- this.toggleCreatable = checked => {
2241
- this.setState({
2242
- isCreatable: checked
2243
- });
2244
- };
2245
-
2246
- this.toggleCreateNew = checked => {
2247
- this.setState({
2248
- hasOnCreateOption: checked
2249
- });
2250
- };
2251
-
2252
- this.toggleOptionDisabled = toggleIndex => () => {
2253
- this.setState(prevState => ({
2254
- hasDisabledOption: !prevState.hasDisabledOption,
2255
- options: prevState.options.map((option, index) =>
2256
- index === toggleIndex ? { ...option, disabled: !option.disabled } : option
2257
- )
2258
- }));
2259
- };
2260
-
2261
- this.toggleResetOnSelect = checked => {
2262
- this.setState({
2263
- resetOnSelect: checked
2264
- });
2265
- };
2266
- }
2267
-
2268
- render() {
2269
- const { isOpen, selected, isCreatable, hasOnCreateOption, resetOnSelect, options } = this.state;
2270
- const titleId = 'multi-typeahead-select-id-1';
2271
-
2272
- return (
2273
- <div>
2274
- <span id={titleId} hidden>
2275
- Select a state
2276
- </span>
2277
- <Select
2278
- variant={SelectVariant.typeaheadMulti}
2279
- typeAheadAriaLabel="Select a state"
2280
- onToggle={this.onToggle}
2281
- onSelect={this.onSelect}
2282
- onClear={this.clearSelection}
2283
- selections={selected}
2284
- isOpen={isOpen}
2285
- aria-labelledby={titleId}
2286
- placeholderText="Select a state"
2287
- isCreatable={isCreatable}
2288
- onCreateOption={(hasOnCreateOption && this.onCreateOption) || undefined}
2289
- shouldResetOnSelect={resetOnSelect}
2290
- >
2291
- {options.map((option, index) => (
2292
- <SelectOption
2293
- isDisabled={option.disabled}
2294
- key={index}
2295
- value={option.value}
2296
- {...(option.description && { description: option.description })}
2297
- />
2298
- ))}
2299
- </Select>
2300
- <Checkbox
2301
- label="isCreatable"
2302
- isChecked={this.state.isCreatable}
2303
- onChange={(_event, checked) => this.toggleCreatable(checked)}
2304
- aria-label="toggle creatable checkbox"
2305
- id="toggle-creatable-typeahead-multi"
2306
- name="toggle-creatable-typeahead-multi"
2307
- />
2308
- <Checkbox
2309
- label="onCreateOption"
2310
- isChecked={this.state.hasOnCreateOption}
2311
- onChange={(_event, checked) => this.toggleCreateNew(checked)}
2312
- aria-label="toggle new checkbox"
2313
- id="toggle-new-typeahead-multi"
2314
- name="toggle-new-typeahead-multi"
2315
- />
2316
- <Checkbox
2317
- label="isDisabled (1st option only)"
2318
- isChecked={this.state.hasDisabledOption}
2319
- onChange={this.toggleOptionDisabled(0)}
2320
- aria-label="toggle disable first option"
2321
- id="toggle-disable-first-option"
2322
- name="toggle-disable-first-option"
2323
- />
2324
- <Checkbox
2325
- label="shouldResetOnSelect"
2326
- isChecked={this.state.resetOnSelect}
2327
- onChange={(_event, checked) => this.toggleResetOnSelect(checked)}
2328
- aria-label="toggle multi reset checkbox"
2329
- id="toggle-reset-multi-typeahead"
2330
- name="toggle-reset-multi-typeahead"
2331
- />
2332
- </div>
2333
- );
2334
- }
2335
- }
2336
- ```
2337
-
2338
- ### Multiple typeahead with custom chips
2339
-
2340
- To customize the appearance of chips, use the `chipGroupProps` property. The `numChips` property allows you to control the number of items shown, while the `expandedText` and `collapsedText` properties allow you to control the labels of the expansion and collapse chips.
2341
-
2342
- ```js
2343
- import React from 'react';
2344
- import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
2345
-
2346
- class MultiTypeaheadSelectInputWithChipGroupProps extends React.Component {
2347
- constructor(props) {
2348
- super(props);
2349
-
2350
- this.state = {
2351
- options: [
2352
- { value: 'Alabama', disabled: false },
2353
- { value: 'Florida', disabled: false },
2354
- { value: 'New Jersey', disabled: false },
2355
- { value: 'New Mexico', disabled: false, description: 'This is a description' },
2356
- { value: 'New York', disabled: false },
2357
- { value: 'North Carolina', disabled: false }
2358
- ],
2359
- isOpen: false,
2360
- selected: []
2361
- };
2362
-
2363
- this.onToggle = (_event, isOpen) => {
2364
- this.setState({
2365
- isOpen
2366
- });
2367
- };
2368
-
2369
- this.onSelect = (event, selection) => {
2370
- const { selected } = this.state;
2371
- if (selected.includes(selection)) {
2372
- this.setState(
2373
- prevState => ({ selected: prevState.selected.filter(item => item !== selection) }),
2374
- () => console.log('selections: ', this.state.selected)
2375
- );
2376
- } else {
2377
- this.setState(
2378
- prevState => ({ selected: [...prevState.selected, selection] }),
2379
- () => console.log('selections: ', this.state.selected)
2380
- );
2381
- }
2382
- };
2383
-
2384
- this.clearSelection = () => {
2385
- this.setState({
2386
- selected: [],
2387
- isOpen: false
2388
- });
2389
- };
2390
- }
2391
-
2392
- render() {
2393
- const { isOpen, selected, isCreatable, hasOnCreateOption } = this.state;
2394
- const titleId = 'multi-typeahead-custom-chip-group-props-id-1';
2395
-
2396
- return (
2397
- <div>
2398
- <span id={titleId} hidden>
2399
- Select a state
2400
- </span>
2401
- <Select
2402
- chipGroupProps={{ numChips: 1, expandedText: 'Hide', collapsedText: 'Show ${remaining}' }}
2403
- variant={SelectVariant.typeaheadMulti}
2404
- typeAheadAriaLabel="Select a state"
2405
- onToggle={this.onToggle}
2406
- onSelect={this.onSelect}
2407
- onClear={this.clearSelection}
2408
- selections={selected}
2409
- isOpen={isOpen}
2410
- aria-labelledby={titleId}
2411
- placeholderText="Select a state"
2412
- >
2413
- {this.state.options.map((option, index) => (
2414
- <SelectOption
2415
- isDisabled={option.disabled}
2416
- key={index}
2417
- value={option.value}
2418
- {...(option.description && { description: option.description })}
2419
- />
2420
- ))}
2421
- </Select>
2422
- </div>
2423
- );
2424
- }
2425
- }
2426
- ```
2427
-
2428
- ### Multiple typeahead with chip group
2429
-
2430
- To customize chips even more, render a [`<ChipGroup>`](/components/chip-group) component and pass it into the `chipGroupComponent` property of the `<Select>` component.
2431
-
2432
- ```js
2433
- import React from 'react';
2434
- import { Select, SelectOption, SelectVariant, ChipGroup, Chip } from '@patternfly/react-core';
2435
-
2436
- class MultiTypeaheadSelectInputWithChipGroupProps extends React.Component {
2437
- constructor(props) {
2438
- super(props);
2439
-
2440
- this.state = {
2441
- options: [
2442
- { value: 'Alabama', disabled: false },
2443
- { value: 'Florida', disabled: false },
2444
- { value: 'New Jersey', disabled: false },
2445
- { value: 'New Mexico', disabled: false, description: 'This is a description' },
2446
- { value: 'New York', disabled: false },
2447
- { value: 'North Carolina', disabled: false }
2448
- ],
2449
- isOpen: false,
2450
- selected: []
2451
- };
2452
-
2453
- this.onToggle = (_event, isOpen) => {
2454
- this.setState({
2455
- isOpen
2456
- });
2457
- };
2458
-
2459
- this.onSelect = (event, selection) => {
2460
- const { selected } = this.state;
2461
- if (selected.includes(selection)) {
2462
- this.setState(
2463
- prevState => ({ selected: prevState.selected.filter(item => item !== selection) }),
2464
- () => console.log('selections: ', this.state.selected)
2465
- );
2466
- } else {
2467
- this.setState(
2468
- prevState => ({ selected: [...prevState.selected, selection] }),
2469
- () => console.log('selections: ', this.state.selected)
2470
- );
2471
- }
2472
- };
2473
-
2474
- this.clearSelection = () => {
2475
- this.setState({
2476
- selected: [],
2477
- isOpen: false
2478
- });
2479
- };
2480
- this.chipGroupComponent = () => {
2481
- const { selected } = this.state;
2482
- return (
2483
- <ChipGroup>
2484
- {(selected || []).map((currentChip, index) => (
2485
- <Chip
2486
- isReadOnly={index === 0 ? true : false}
2487
- key={currentChip}
2488
- onClick={event => this.onSelect(event, currentChip)}
2489
- >
2490
- {currentChip}
2491
- </Chip>
2492
- ))}
2493
- </ChipGroup>
2494
- );
2495
- };
2496
- }
2497
-
2498
- render() {
2499
- const { isOpen, selected, isCreatable, hasOnCreateOption } = this.state;
2500
- const titleId = 'multi-typeahead-render-chip-group-props-id-1';
2501
-
2502
- return (
2503
- <div>
2504
- <span id={titleId} hidden>
2505
- Select a state
2506
- </span>
2507
- <Select
2508
- chipGroupProps={{ numChips: 1, expandedText: 'Hide', collapsedText: 'Show ${remaining}' }}
2509
- variant={SelectVariant.typeaheadMulti}
2510
- typeAheadAriaLabel="Select a state"
2511
- onToggle={this.onToggle}
2512
- onSelect={this.onSelect}
2513
- onClear={this.clearSelection}
2514
- selections={selected}
2515
- isOpen={isOpen}
2516
- aria-labelledby={titleId}
2517
- placeholderText="Select a state"
2518
- chipGroupComponent={this.chipGroupComponent()}
2519
- >
2520
- {this.state.options.map((option, index) => (
2521
- <SelectOption
2522
- isDisabled={option.disabled}
2523
- key={index}
2524
- value={option.value}
2525
- {...(option.description && { description: option.description })}
2526
- />
2527
- ))}
2528
- </Select>
2529
- </div>
2530
- );
2531
- }
2532
- }
2533
- ```
2534
-
2535
- ### Multiple typeahead with custom objects
2536
-
2537
- A `<SelectOption>` can have an object passed into the `value` property in order to store additional data beyond just a string value. The object passed in must have a `toString` function that returns a string to display in the `SelectMenu`.
2538
-
2539
- ```js
2540
- import React from 'react';
2541
- import { Select, SelectOption, SelectVariant, Divider } from '@patternfly/react-core';
2542
-
2543
- class MultiTypeaheadSelectInputCustomObjects extends React.Component {
2544
- constructor(props) {
2545
- super(props);
2546
- this.createState = (name, abbreviation, capital, founded) => {
2547
- return {
2548
- name: name,
2549
- abbreviation: abbreviation,
2550
- capital: capital,
2551
- founded: founded,
2552
- toString: function() {
2553
- return `${this.name} (${this.abbreviation}) - Founded: ${this.founded}`;
2554
- },
2555
- compareTo: function(value) {
2556
- return this.toString()
2557
- .toLowerCase()
2558
- .includes(value.toString().toLowerCase());
2559
- }
2560
- };
2561
- };
2562
- this.options = [
2563
- <SelectOption key={0} value={this.createState('Alabama', 'AL', 'Montgomery', 1846)} />,
2564
- <Divider component="li" key={111} />,
2565
- <SelectOption key={1} value={this.createState('Florida', 'FL', 'Tailahassee', 1845)} />,
2566
- <SelectOption key={2} value={this.createState('New Jersey', 'NJ', 'Trenton', 1787)} />,
2567
- <SelectOption key={3} value={this.createState('New Mexico', 'NM', 'Santa Fe', 1912)} />,
2568
- <SelectOption key={4} value={this.createState('New York', 'NY', 'Albany', 1788)} />,
2569
- <SelectOption key={5} value={this.createState('North Carolina', 'NC', 'Raleigh', 1789)} />
2570
- ];
2571
-
2572
- this.state = {
2573
- isOpen: false,
2574
- selected: []
2575
- };
2576
-
2577
- this.onToggle = (_event, isOpen) => {
2578
- this.setState({
2579
- isOpen
2580
- });
2581
- };
2582
-
2583
- this.onSelect = (event, selection) => {
2584
- const { selected } = this.state;
2585
- if (selected.includes(selection)) {
2586
- this.setState(
2587
- prevState => ({ selected: prevState.selected.filter(item => item !== selection) }),
2588
- () => console.log('selections: ', this.state.selected)
2589
- );
2590
- } else {
2591
- this.setState(
2592
- prevState => ({ selected: [...prevState.selected, selection] }),
2593
- () => console.log('selections: ', this.state.selected)
2594
- );
2595
- }
2596
- };
2597
-
2598
- this.clearSelection = () => {
2599
- this.setState({
2600
- selected: [],
2601
- isOpen: false
2602
- });
2603
- };
2604
- }
2605
-
2606
- render() {
2607
- const { isOpen, selected } = this.state;
2608
- const titleId = 'multi-typeahead-select-id-2';
2609
-
2610
- return (
2611
- <div>
2612
- <span id={titleId} hidden>
2613
- Select a state
2614
- </span>
2615
- <Select
2616
- variant={SelectVariant.typeaheadMulti}
2617
- typeAheadAriaLabel="Select a state"
2618
- onToggle={this.onToggle}
2619
- onSelect={this.onSelect}
2620
- onClear={this.clearSelection}
2621
- onFilter={this.customFilter}
2622
- selections={selected}
2623
- isOpen={isOpen}
2624
- aria-labelledby={titleId}
2625
- placeholderText="Select a state"
2626
- >
2627
- {this.options}
2628
- </Select>
2629
- </div>
2630
- );
2631
- }
2632
- }
2633
- ```
2634
-
2635
- ### Plain multiple typeahead
2636
-
2637
- To plainly style a typeahead, use the `isPlain` property.
2638
-
2639
- ```js
2640
- import React from 'react';
2641
- import { Select, SelectOption, SelectVariant } from '@patternfly/react-core';
2642
-
2643
- class PlainSelectInput extends React.Component {
2644
- constructor(props) {
2645
- super(props);
2646
- this.options = [
2647
- { value: 'Alabama', disabled: false },
2648
- { value: 'Florida', disabled: false },
2649
- { value: 'New Jersey', disabled: false },
2650
- { value: 'New Mexico', disabled: false },
2651
- { value: 'New York', disabled: false },
2652
- { value: 'North Carolina', disabled: false }
2653
- ];
2654
-
2655
- this.state = {
2656
- isOpen: false,
2657
- isPlain: true,
2658
- selected: []
2659
- };
2660
-
2661
- this.onToggle = (_event, isOpen) => {
2662
- this.setState({
2663
- isOpen
2664
- });
2665
- };
2666
-
2667
- this.onSelect = (event, selection) => {
2668
- const { selected } = this.state;
2669
- if (selected.includes(selection)) {
2670
- this.setState(
2671
- prevState => ({ selected: prevState.selected.filter(item => item !== selection) }),
2672
- () => console.log('selections: ', this.state.selected)
2673
- );
2674
- } else {
2675
- this.setState(
2676
- prevState => ({ selected: [...prevState.selected, selection] }),
2677
- () => console.log('selections: ', this.state.selected)
2678
- );
2679
- }
2680
- };
2681
-
2682
- this.clearSelection = () => {
2683
- this.setState({
2684
- selected: [],
2685
- isOpen: false
2686
- });
2687
- };
2688
- }
2689
-
2690
- render() {
2691
- const { isOpen, isPlain, selected } = this.state;
2692
- const titleId = 'plain-typeahead-select-id';
2693
-
2694
- return (
2695
- <div>
2696
- <span id={titleId} hidden>
2697
- Select a state
2698
- </span>
2699
- <Select
2700
- variant={SelectVariant.typeaheadMulti}
2701
- typeAheadAriaLabel="Select a state"
2702
- onToggle={this.onToggle}
2703
- onSelect={this.onSelect}
2704
- onClear={this.clearSelection}
2705
- selections={selected}
2706
- isOpen={isOpen}
2707
- isPlain={isPlain}
2708
- aria-labelledby={titleId}
2709
- placeholderText="Select a state"
2710
- >
2711
- {this.options.map((option, index) => (
2712
- <SelectOption isDisabled={option.disabled} key={index} value={option.value} />
2713
- ))}
2714
- </Select>
2715
- </div>
2716
- );
2717
- }
2718
- }
2719
- ```
2720
-
2721
- ### Custom menu content
2722
-
2723
- To add custom menu content, use the `customContent` property.
2724
-
2725
- ```js
2726
- import React from 'react';
2727
- import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
2728
- import { Select, SelectOption, SelectDirection, Checkbox } from '@patternfly/react-core';
2729
-
2730
- class SingleSelectInput extends React.Component {
2731
- constructor(props) {
2732
- super(props);
2733
- this.state = {
2734
- isOpen: false,
2735
- isDisabled: false,
2736
- direction: SelectDirection.down
2737
- };
2738
-
2739
- this.onToggle = (_event, isOpen) => {
2740
- this.setState({
2741
- isOpen
2742
- });
2743
- };
2744
-
2745
- this.toggleDisabled = checked => {
2746
- this.setState({
2747
- isDisabled: checked
2748
- });
2749
- };
2750
-
2751
- this.toggleDirection = () => {
2752
- if (this.state.direction === SelectDirection.up) {
2753
- this.setState({
2754
- direction: SelectDirection.down
2755
- });
2756
- } else {
2757
- this.setState({
2758
- direction: SelectDirection.up
2759
- });
2760
- }
2761
- };
2762
- }
2763
-
2764
- render() {
2765
- const { isOpen, selected, isDisabled, direction } = this.state;
2766
- const titleId = 'title-id-2';
2767
- return (
2768
- <div>
2769
- <span id={titleId} hidden>
2770
- Title
2771
- </span>
2772
- <Select
2773
- aria-label="Select Input"
2774
- onToggle={this.onToggle}
2775
- isOpen={isOpen}
2776
- aria-labelledby={titleId}
2777
- isDisabled={isDisabled}
2778
- direction={direction}
2779
- customContent="[Panel contents here]"
2780
- placeholderText="Filter by birth month"
2781
- />
2782
- <Checkbox
2783
- label="isDisabled"
2784
- isChecked={this.state.isDisabled}
2785
- onChange={(_event, checked) => this.toggleDisabled(checked)}
2786
- aria-label="disabled checkbox panel"
2787
- id="toggle-disabled-panel"
2788
- name="toggle-disabled-panel"
2789
- />
2790
- <Checkbox
2791
- label="Expands up"
2792
- isChecked={direction === SelectDirection.up}
2793
- onChange={this.toggleDirection}
2794
- aria-label="direction checkbox panel"
2795
- id="toggle-direction-panel"
2796
- name="toggle-direction-panel"
2797
- />
2798
- </div>
2799
- );
2800
- }
2801
- }
2802
- ```
2803
-
2804
- ### Appending document body vs parent
2805
-
2806
- Avoid passing in `document.body` to the `menuAppendTo` property. Doing so can cause accessibility issues because this prevents users from being able to enter the contents of the select options via assistive technologies (like keyboards or screen readers). Instead, pass in `parent` to achieve the same result without sacrificing accessibility.
2807
-
2808
- The following example demonstrates both methods. When the dropdown is opened, both select variants manage focus the same way, but behave differently when the tab key is pressed after an option is selected.
2809
-
2810
- - For the `document.body` variant, the focus will be placed at the end of the page, since that is where the dropdown content is appended to in the DOM (rather than focus being placed on the second Select variant as one might expect).
2811
- - For the `parent` variant, however, the focus will be placed on the next tab-able element (the "Toggle JS code" button for the code editor in this case).
2812
-
2813
- ```js
2814
- import React from 'react';
2815
- import { Select, SelectOption, Flex, FlexItem } from '@patternfly/react-core';
2816
-
2817
- class SelectDocumentBodyVsParent extends React.Component {
2818
- constructor(props) {
2819
- super(props);
2820
- this.bodyOptions = [
2821
- <SelectOption key={0} value="Select a title - document body" isPlaceholder />,
2822
- <SelectOption key={1} value="Mr" />,
2823
- <SelectOption key={2} value="Miss" />,
2824
- <SelectOption key={3} value="Mrs" />,
2825
- <SelectOption key={4} value="Ms" />,
2826
- <SelectOption key={6} value="Dr" />,
2827
- <SelectOption key={7} value="Other" />
2828
- ];
2829
-
2830
- this.parentOptions = [
2831
- <SelectOption key={0} value="Select a title - parent" isPlaceholder />,
2832
- <SelectOption key={1} value="Mr" />,
2833
- <SelectOption key={2} value="Miss" />,
2834
- <SelectOption key={3} value="Mrs" />,
2835
- <SelectOption key={4} value="Ms" />,
2836
- <SelectOption key={6} value="Dr" />,
2837
- <SelectOption key={7} value="Other" />
2838
- ];
2839
-
2840
- this.state = {
2841
- isBodyOpen: false,
2842
- isParentOpen: false,
2843
- bodySelected: null,
2844
- parentSelected: null
2845
- };
2846
-
2847
- this.onBodyToggle = (_event, isBodyOpen) => {
2848
- this.setState({
2849
- isBodyOpen
2850
- });
2851
- };
2852
-
2853
- this.onParentToggle = (_event, isParentOpen) => {
2854
- this.setState({
2855
- isParentOpen
2856
- });
2857
- };
2858
-
2859
- this.onBodySelect = (event, selection, isPlaceholder) => {
2860
- if (isPlaceholder) this.clearSelection();
2861
- else {
2862
- this.setState({
2863
- bodySelected: selection,
2864
- isBodyOpen: false
2865
- });
2866
- console.log('selected on document body:', selection);
2867
- }
2868
- };
2869
-
2870
- this.onParentSelect = (event, selection, isPlaceholder) => {
2871
- if (isPlaceholder) this.clearSelection();
2872
- else {
2873
- this.setState({
2874
- parentSelected: selection,
2875
- isParentOpen: false
2876
- });
2877
- console.log('selected on parent:', selection);
2878
- }
2879
- };
2880
-
2881
- this.clearSelection = () => {
2882
- this.setState({
2883
- selected: null,
2884
- isOpen: false
2885
- });
2886
- };
2887
- }
2888
-
2889
- render() {
2890
- const { isBodyOpen, isParentOpen, bodySelected, parentSelected } = this.state;
34
+ ### Multiple Typeahead
2891
35
 
2892
- return (
2893
- <Flex space={{ default: 'spacerMd' }} direction={{ default: 'column' }}>
2894
- <FlexItem>
2895
- <Select
2896
- aria-label="Select Input for Document Body"
2897
- onToggle={this.onBodyToggle}
2898
- onSelect={this.onBodySelect}
2899
- selections={bodySelected}
2900
- isOpen={isBodyOpen}
2901
- menuAppendTo={() => document.body}
2902
- >
2903
- {this.bodyOptions}
2904
- </Select>
2905
- </FlexItem>
2906
- <FlexItem>
2907
- <Select
2908
- aria-label="Select Input for Parent"
2909
- onToggle={this.onParentToggle}
2910
- onSelect={this.onParentSelect}
2911
- selections={parentSelected}
2912
- isOpen={isParentOpen}
2913
- menuAppendTo="parent"
2914
- >
2915
- {this.parentOptions}
2916
- </Select>
2917
- </FlexItem>
2918
- </Flex>
2919
- );
2920
- }
2921
- }
36
+ ```ts file="./SelectMultiTypeahead.tsx"
2922
37
  ```