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