@patternfly/react-core 4.201.2 → 4.202.2

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 (81) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/esm/components/DescriptionList/DescriptionList.d.ts +13 -3
  3. package/dist/esm/components/DescriptionList/DescriptionList.d.ts.map +1 -1
  4. package/dist/esm/components/DescriptionList/DescriptionList.js +10 -6
  5. package/dist/esm/components/DescriptionList/DescriptionList.js.map +1 -1
  6. package/dist/esm/components/Menu/MenuContent.d.ts.map +1 -1
  7. package/dist/esm/components/Menu/MenuContent.js +21 -2
  8. package/dist/esm/components/Menu/MenuContent.js.map +1 -1
  9. package/dist/esm/components/MenuToggle/MenuToggle.d.ts +1 -1
  10. package/dist/esm/components/MenuToggle/MenuToggle.d.ts.map +1 -1
  11. package/dist/esm/components/MenuToggle/MenuToggle.js +1 -1
  12. package/dist/esm/components/MenuToggle/MenuToggle.js.map +1 -1
  13. package/dist/esm/components/Popover/Popover.d.ts +1 -1
  14. package/dist/esm/components/Select/Select.d.ts +5 -3
  15. package/dist/esm/components/Select/Select.d.ts.map +1 -1
  16. package/dist/esm/components/Select/Select.js +36 -17
  17. package/dist/esm/components/Select/Select.js.map +1 -1
  18. package/dist/esm/components/Select/SelectOption.d.ts.map +1 -1
  19. package/dist/esm/components/Select/SelectOption.js +3 -3
  20. package/dist/esm/components/Select/SelectOption.js.map +1 -1
  21. package/dist/esm/components/Select/SelectToggle.d.ts +1 -1
  22. package/dist/esm/components/Select/SelectToggle.d.ts.map +1 -1
  23. package/dist/esm/components/Select/SelectToggle.js +14 -14
  24. package/dist/esm/components/Select/SelectToggle.js.map +1 -1
  25. package/dist/esm/components/Select/selectConstants.d.ts +1 -0
  26. package/dist/esm/components/Select/selectConstants.d.ts.map +1 -1
  27. package/dist/esm/components/Select/selectConstants.js.map +1 -1
  28. package/dist/esm/components/TimePicker/TimePicker.d.ts +6 -4
  29. package/dist/esm/components/TimePicker/TimePicker.d.ts.map +1 -1
  30. package/dist/esm/components/TimePicker/TimePicker.js +15 -8
  31. package/dist/esm/components/TimePicker/TimePicker.js.map +1 -1
  32. package/dist/js/components/DescriptionList/DescriptionList.d.ts +13 -3
  33. package/dist/js/components/DescriptionList/DescriptionList.d.ts.map +1 -1
  34. package/dist/js/components/DescriptionList/DescriptionList.js +10 -6
  35. package/dist/js/components/DescriptionList/DescriptionList.js.map +1 -1
  36. package/dist/js/components/Menu/MenuContent.d.ts.map +1 -1
  37. package/dist/js/components/Menu/MenuContent.js +21 -2
  38. package/dist/js/components/Menu/MenuContent.js.map +1 -1
  39. package/dist/js/components/MenuToggle/MenuToggle.d.ts +1 -1
  40. package/dist/js/components/MenuToggle/MenuToggle.d.ts.map +1 -1
  41. package/dist/js/components/MenuToggle/MenuToggle.js +1 -1
  42. package/dist/js/components/MenuToggle/MenuToggle.js.map +1 -1
  43. package/dist/js/components/Popover/Popover.d.ts +1 -1
  44. package/dist/js/components/Select/Select.d.ts +5 -3
  45. package/dist/js/components/Select/Select.d.ts.map +1 -1
  46. package/dist/js/components/Select/Select.js +36 -17
  47. package/dist/js/components/Select/Select.js.map +1 -1
  48. package/dist/js/components/Select/SelectOption.d.ts.map +1 -1
  49. package/dist/js/components/Select/SelectOption.js +3 -3
  50. package/dist/js/components/Select/SelectOption.js.map +1 -1
  51. package/dist/js/components/Select/SelectToggle.d.ts +1 -1
  52. package/dist/js/components/Select/SelectToggle.d.ts.map +1 -1
  53. package/dist/js/components/Select/SelectToggle.js +14 -14
  54. package/dist/js/components/Select/SelectToggle.js.map +1 -1
  55. package/dist/js/components/Select/selectConstants.d.ts +1 -0
  56. package/dist/js/components/Select/selectConstants.d.ts.map +1 -1
  57. package/dist/js/components/Select/selectConstants.js.map +1 -1
  58. package/dist/js/components/TimePicker/TimePicker.d.ts +6 -4
  59. package/dist/js/components/TimePicker/TimePicker.d.ts.map +1 -1
  60. package/dist/js/components/TimePicker/TimePicker.js +15 -8
  61. package/dist/js/components/TimePicker/TimePicker.js.map +1 -1
  62. package/dist/umd/react-core.css +31 -2
  63. package/dist/umd/react-core.js +107 -53
  64. package/dist/umd/react-core.min.css +31 -2
  65. package/dist/umd/react-core.min.js +2 -2
  66. package/package.json +6 -6
  67. package/src/components/DescriptionList/DescriptionList.tsx +52 -31
  68. package/src/components/DescriptionList/examples/DescriptionList.md +87 -28
  69. package/src/components/Menu/MenuContent.tsx +27 -2
  70. package/src/components/MenuToggle/MenuToggle.tsx +2 -1
  71. package/src/components/MenuToggle/examples/MenuToggle.css +3 -0
  72. package/src/components/MenuToggle/examples/MenuToggle.md +53 -11
  73. package/src/components/Popover/Popover.tsx +1 -1
  74. package/src/components/Select/Select.tsx +39 -18
  75. package/src/components/Select/SelectOption.tsx +7 -4
  76. package/src/components/Select/SelectToggle.tsx +15 -15
  77. package/src/components/Select/__tests__/__snapshots__/Select.test.tsx.snap +2 -0
  78. package/src/components/Select/examples/Select.md +93 -40
  79. package/src/components/Select/selectConstants.tsx +1 -0
  80. package/src/components/TimePicker/TimePicker.tsx +20 -11
  81. package/src/components/TimePicker/examples/TimePicker.md +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "4.201.2",
3
+ "version": "4.202.2",
4
4
  "description": "This library provides a set of common React components for use with the PatternFly reference implementation.",
5
5
  "main": "dist/js/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -34,16 +34,16 @@
34
34
  "generate": "node scripts/copyStyles.js"
35
35
  },
36
36
  "dependencies": {
37
- "@patternfly/react-icons": "^4.52.2",
38
- "@patternfly/react-styles": "^4.51.2",
39
- "@patternfly/react-tokens": "^4.53.2",
37
+ "@patternfly/react-icons": "^4.53.2",
38
+ "@patternfly/react-styles": "^4.52.2",
39
+ "@patternfly/react-tokens": "^4.54.2",
40
40
  "focus-trap": "6.2.2",
41
41
  "react-dropzone": "9.0.0",
42
42
  "tippy.js": "5.1.2",
43
43
  "tslib": "^2.0.0"
44
44
  },
45
45
  "devDependencies": {
46
- "@patternfly/patternfly": "4.183.2",
46
+ "@patternfly/patternfly": "4.184.1",
47
47
  "@rollup/plugin-commonjs": "^21.0.0",
48
48
  "@rollup/plugin-node-resolve": "^13.0.0",
49
49
  "@rollup/plugin-replace": "^3.0.0",
@@ -60,5 +60,5 @@
60
60
  "react": "^16.8.0 || ^17.0.0",
61
61
  "react-dom": "^16.8.0 || ^17.0.0"
62
62
  },
63
- "gitHead": "c7164830706215f812e1982fdad6c9903229e71f"
63
+ "gitHead": "91da841142369098e1ef2936b69fd90e4379a1e6"
64
64
  }
@@ -3,7 +3,7 @@ import { css } from '@patternfly/react-styles';
3
3
  import styles from '@patternfly/react-styles/css/components/DescriptionList/description-list';
4
4
  import { formatBreakpointMods } from '../../helpers';
5
5
 
6
- export interface AutoFitModifiers {
6
+ export interface BreakpointModifiers {
7
7
  default?: string;
8
8
  md?: string;
9
9
  lg?: string;
@@ -30,7 +30,7 @@ export interface DescriptionListProps extends Omit<React.HTMLProps<HTMLDListElem
30
30
  isFluid?: boolean;
31
31
  /** Sets the the default placement of description list groups to fill from top to bottom. */
32
32
  isFillColumns?: boolean;
33
- /** Sets the number of columns on the description list */
33
+ /** Sets the number of columns on the description list at various breakpoints */
34
34
  columnModifier?: {
35
35
  default?: '1Col' | '2Col' | '3Col';
36
36
  sm?: '1Col' | '2Col' | '3Col';
@@ -39,7 +39,7 @@ export interface DescriptionListProps extends Omit<React.HTMLProps<HTMLDListElem
39
39
  xl?: '1Col' | '2Col' | '3Col';
40
40
  '2xl'?: '1Col' | '2Col' | '3Col';
41
41
  };
42
- /** Indicates how the menu will align at screen size breakpoints. Default alignment is set via the position property. */
42
+ /** Indicates how the menu will align at various breakpoints. */
43
43
  orientation?: {
44
44
  sm?: 'vertical' | 'horizontal';
45
45
  md?: 'vertical' | 'horizontal';
@@ -47,6 +47,7 @@ export interface DescriptionListProps extends Omit<React.HTMLProps<HTMLDListElem
47
47
  xl?: 'vertical' | 'horizontal';
48
48
  '2xl'?: 'vertical' | 'horizontal';
49
49
  };
50
+ /** Sets the minimum column size for the auto-fit (isAutoFit) layout at various breakpoints. */
50
51
  autoFitMinModifier?: {
51
52
  default?: string;
52
53
  sm?: string;
@@ -55,11 +56,19 @@ export interface DescriptionListProps extends Omit<React.HTMLProps<HTMLDListElem
55
56
  xl?: string;
56
57
  '2xl'?: string;
57
58
  };
59
+ /** Sets the horizontal description list's term column width at various breakpoints. */
60
+ horizontalTermWidthModifier?: {
61
+ default?: string;
62
+ sm?: string;
63
+ md?: string;
64
+ lg?: string;
65
+ xl?: string;
66
+ '2xl'?: string;
67
+ };
58
68
  }
59
69
 
60
- const setAutoFitMinModifiers = (autoFitMinModifier: AutoFitModifiers) => {
61
- const prefix = '--pf-c-description-list--GridTemplateColumns--min';
62
- const mods = autoFitMinModifier as Partial<{ [k: string]: string }>;
70
+ const setBreakpointModifiers = (prefix: string, modifiers: BreakpointModifiers) => {
71
+ const mods = modifiers as Partial<{ [k: string]: string }>;
63
72
  return Object.keys(mods || {}).reduce(
64
73
  (acc, curr) =>
65
74
  curr === 'default' ? { ...acc, [prefix]: mods[curr] } : { ...acc, [`${prefix}-on-${curr}`]: mods[curr] },
@@ -79,33 +88,45 @@ export const DescriptionList: React.FunctionComponent<DescriptionListProps> = ({
79
88
  isFillColumns,
80
89
  columnModifier,
81
90
  autoFitMinModifier,
91
+ horizontalTermWidthModifier,
82
92
  orientation,
83
93
  style,
84
94
  ...props
85
- }: DescriptionListProps) => (
86
- <dl
87
- className={css(
88
- styles.descriptionList,
89
- (isHorizontal || isFluid) && styles.modifiers.horizontal,
90
- isAutoColumnWidths && styles.modifiers.autoColumnWidths,
91
- isAutoFit && styles.modifiers.autoFit,
92
- formatBreakpointMods(columnModifier, styles),
93
- formatBreakpointMods(orientation, styles),
94
- isInlineGrid && styles.modifiers.inlineGrid,
95
- isCompact && styles.modifiers.compact,
96
- isFluid && styles.modifiers.fluid,
97
- isFillColumns && styles.modifiers.fillColumns,
98
- className
99
- )}
100
- style={
101
- autoFitMinModifier || style
102
- ? { ...(isAutoFit ? setAutoFitMinModifiers(autoFitMinModifier) : {}), ...style }
103
- : undefined
104
- }
105
- {...props}
106
- >
107
- {children}
108
- </dl>
109
- );
95
+ }: DescriptionListProps) => {
96
+ if (isAutoFit && autoFitMinModifier) {
97
+ style = {
98
+ ...style,
99
+ ...setBreakpointModifiers('--pf-c-description-list--GridTemplateColumns--min', autoFitMinModifier)
100
+ };
101
+ }
102
+ if (isHorizontal && horizontalTermWidthModifier) {
103
+ style = {
104
+ ...style,
105
+ ...setBreakpointModifiers('--pf-c-description-list--m-horizontal__term--width', horizontalTermWidthModifier)
106
+ };
107
+ }
108
+
109
+ return (
110
+ <dl
111
+ className={css(
112
+ styles.descriptionList,
113
+ (isHorizontal || isFluid) && styles.modifiers.horizontal,
114
+ isAutoColumnWidths && styles.modifiers.autoColumnWidths,
115
+ isAutoFit && styles.modifiers.autoFit,
116
+ formatBreakpointMods(columnModifier, styles),
117
+ formatBreakpointMods(orientation, styles),
118
+ isInlineGrid && styles.modifiers.inlineGrid,
119
+ isCompact && styles.modifiers.compact,
120
+ isFluid && styles.modifiers.fluid,
121
+ isFillColumns && styles.modifiers.fillColumns,
122
+ className
123
+ )}
124
+ style={style}
125
+ {...props}
126
+ >
127
+ {children}
128
+ </dl>
129
+ );
130
+ };
110
131
 
111
132
  DescriptionList.displayName = 'DescriptionList';
@@ -239,34 +239,93 @@ import {
239
239
  } from '@patternfly/react-core';
240
240
  import PlusCircleIcon from '@patternfly/react-icons/dist/esm/icons/plus-circle-icon';
241
241
 
242
- <DescriptionList isHorizontal>
243
- <DescriptionListGroup>
244
- <DescriptionListTerm>Name</DescriptionListTerm>
245
- <DescriptionListDescription>Example</DescriptionListDescription>
246
- </DescriptionListGroup>
247
- <DescriptionListGroup>
248
- <DescriptionListTerm>Namespace</DescriptionListTerm>
249
- <DescriptionListDescription>
250
- <a href="#">mary-test</a>
251
- </DescriptionListDescription>
252
- </DescriptionListGroup>
253
- <DescriptionListGroup>
254
- <DescriptionListTerm>Labels</DescriptionListTerm>
255
- <DescriptionListDescription>example</DescriptionListDescription>
256
- </DescriptionListGroup>
257
- <DescriptionListGroup>
258
- <DescriptionListTerm>Pod selector</DescriptionListTerm>
259
- <DescriptionListDescription>
260
- <Button variant="link" isInline icon={<PlusCircleIcon />}>
261
- app=MyApp
262
- </Button>
263
- </DescriptionListDescription>
264
- </DescriptionListGroup>
265
- <DescriptionListGroup>
266
- <DescriptionListTerm>Annotation</DescriptionListTerm>
267
- <DescriptionListDescription>2 Annotations</DescriptionListDescription>
268
- </DescriptionListGroup>
269
- </DescriptionList>;
242
+ const DescriptionListHorizontal = () => {
243
+ return (
244
+ <DescriptionList isHorizontal>
245
+ <DescriptionListGroup>
246
+ <DescriptionListTerm>Name</DescriptionListTerm>
247
+ <DescriptionListDescription>Example</DescriptionListDescription>
248
+ </DescriptionListGroup>
249
+ <DescriptionListGroup>
250
+ <DescriptionListTerm>Namespace</DescriptionListTerm>
251
+ <DescriptionListDescription>
252
+ <a href="#">mary-test</a>
253
+ </DescriptionListDescription>
254
+ </DescriptionListGroup>
255
+ <DescriptionListGroup>
256
+ <DescriptionListTerm>Labels</DescriptionListTerm>
257
+ <DescriptionListDescription>example</DescriptionListDescription>
258
+ </DescriptionListGroup>
259
+ <DescriptionListGroup>
260
+ <DescriptionListTerm>Pod selector</DescriptionListTerm>
261
+ <DescriptionListDescription>
262
+ <Button variant="link" isInline icon={<PlusCircleIcon />}>
263
+ app=MyApp
264
+ </Button>
265
+ </DescriptionListDescription>
266
+ </DescriptionListGroup>
267
+ <DescriptionListGroup>
268
+ <DescriptionListTerm>Annotation</DescriptionListTerm>
269
+ <DescriptionListDescription>2 Annotations</DescriptionListDescription>
270
+ </DescriptionListGroup>
271
+ </DescriptionList>
272
+ )
273
+ }
274
+ ```
275
+
276
+ ### Horizontal using custom term width modifier
277
+
278
+ ```js
279
+ import React from 'react';
280
+ import {
281
+ Button,
282
+ DescriptionList,
283
+ DescriptionListTerm,
284
+ DescriptionListText,
285
+ DescriptionListGroup,
286
+ DescriptionListDescription,
287
+ } from '@patternfly/react-core';
288
+ import PlusCircleIcon from '@patternfly/react-icons/dist/esm/icons/plus-circle-icon';
289
+
290
+ const DescriptionListHorizontalTermWidthModifier = () => {
291
+ return (
292
+ <DescriptionList isHorizontal horizontalTermWidthModifier={{
293
+ default: '12ch',
294
+ sm: '15ch',
295
+ md: '20ch',
296
+ lg: '28ch',
297
+ xl: '30ch',
298
+ '2xl': '35ch'
299
+ }}>
300
+ <DescriptionListGroup>
301
+ <DescriptionListTerm>Name longer than the default term width</DescriptionListTerm>
302
+ <DescriptionListDescription>Example</DescriptionListDescription>
303
+ </DescriptionListGroup>
304
+ <DescriptionListGroup>
305
+ <DescriptionListTerm>Namespace</DescriptionListTerm>
306
+ <DescriptionListDescription>
307
+ <a href="#">mary-test</a>
308
+ </DescriptionListDescription>
309
+ </DescriptionListGroup>
310
+ <DescriptionListGroup>
311
+ <DescriptionListTerm>Labels</DescriptionListTerm>
312
+ <DescriptionListDescription>example</DescriptionListDescription>
313
+ </DescriptionListGroup>
314
+ <DescriptionListGroup>
315
+ <DescriptionListTerm>Pod selector</DescriptionListTerm>
316
+ <DescriptionListDescription>
317
+ <Button variant="link" isInline icon={<PlusCircleIcon />}>
318
+ app=MyApp
319
+ </Button>
320
+ </DescriptionListDescription>
321
+ </DescriptionListGroup>
322
+ <DescriptionListGroup>
323
+ <DescriptionListTerm>Annotation</DescriptionListTerm>
324
+ <DescriptionListDescription>2 Annotations</DescriptionListDescription>
325
+ </DescriptionListGroup>
326
+ </DescriptionList>
327
+ )
328
+ }
270
329
  ```
271
330
 
272
331
  ### Horizontal 2 col
@@ -21,8 +21,33 @@ export const MenuContent = React.forwardRef((props: MenuContentProps, ref: React
21
21
  const menuContentRef = React.createRef<HTMLDivElement>();
22
22
  const refCallback = (el: HTMLElement, menuId: string, onGetMenuHeight: (menuId: string, height: number) => void) => {
23
23
  if (el) {
24
- onGetMenuHeight && onGetMenuHeight(menuId, el.clientHeight);
25
- getHeight && getHeight(el.clientHeight.toString());
24
+ let clientHeight = el.clientHeight;
25
+
26
+ // if this menu is a submenu, we need to account for the root menu list's padding and root menu content's border.
27
+ let rootMenuList = null;
28
+ let parentEl = el.closest(`.${styles.menuList}`);
29
+ while (parentEl !== null && parentEl.nodeType === 1) {
30
+ if (parentEl.classList.contains(styles.menuList)) {
31
+ rootMenuList = parentEl;
32
+ }
33
+ parentEl = parentEl.parentElement;
34
+ }
35
+
36
+ if (rootMenuList) {
37
+ const rootMenuListStyles = getComputedStyle(rootMenuList);
38
+ const rootMenuListPaddingOffset =
39
+ parseFloat(rootMenuListStyles.getPropertyValue('padding-top').replace(/px/g, '')) +
40
+ parseFloat(rootMenuListStyles.getPropertyValue('padding-bottom').replace(/px/g, '')) +
41
+ parseFloat(
42
+ getComputedStyle(rootMenuList.parentElement)
43
+ .getPropertyValue('border-bottom-width')
44
+ .replace(/px/g, '')
45
+ );
46
+ clientHeight = clientHeight + rootMenuListPaddingOffset;
47
+ }
48
+
49
+ onGetMenuHeight && onGetMenuHeight(menuId, clientHeight);
50
+ getHeight && getHeight(clientHeight.toString());
26
51
  }
27
52
  return ref || menuContentRef;
28
53
  };
@@ -17,7 +17,7 @@ export interface MenuToggleProps
17
17
  /** Flag indicating the toggle is full height */
18
18
  isFullHeight?: boolean;
19
19
  /** Variant styles of the menu toggle */
20
- variant?: 'default' | 'plain' | 'primary' | 'plainText';
20
+ variant?: 'default' | 'plain' | 'primary' | 'plainText' | 'secondary';
21
21
  /** Optional icon rendered inside the toggle, before the children content */
22
22
  icon?: React.ReactNode;
23
23
  /** Optional badge rendered inside the toggle, after the children content */
@@ -71,6 +71,7 @@ export class MenuToggleBase extends React.Component<MenuToggleProps> {
71
71
  styles.menuToggle,
72
72
  isExpanded && styles.modifiers.expanded,
73
73
  variant === 'primary' && styles.modifiers.primary,
74
+ variant === 'secondary' && styles.modifiers.secondary,
74
75
  (isPlain || isPlainText) && styles.modifiers.plain,
75
76
  isPlainText && styles.modifiers.text,
76
77
  isFullHeight && styles.modifiers.fullHeight,
@@ -0,0 +1,3 @@
1
+ #ws-react-c-menu-toggle-primary .pf-c-menu-toggle, #ws-react-c-menu-toggle-secondary .pf-c-menu-toggle {
2
+ vertical-align: bottom;
3
+ }
@@ -6,8 +6,11 @@ propComponents: ['MenuToggle']
6
6
  beta: true
7
7
  ---
8
8
 
9
+ import './MenuToggle.css'
10
+
9
11
  import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
10
12
  import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon';
13
+ import imgAvatar from '@patternfly/react-core/src/components/Avatar/examples/avatarImg.svg';
11
14
 
12
15
  ## Examples
13
16
 
@@ -41,17 +44,6 @@ import { MenuToggle } from '@patternfly/react-core';
41
44
 
42
45
  ```
43
46
 
44
- ### Icon
45
-
46
- ```ts
47
- import React from 'react';
48
- import { MenuToggle } from '@patternfly/react-core';
49
- import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
50
-
51
- <MenuToggle icon={<CogIcon />}>Icon</MenuToggle>;
52
-
53
- ```
54
-
55
47
  ### Count
56
48
 
57
49
  ```ts
@@ -84,6 +76,28 @@ import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
84
76
 
85
77
  ```
86
78
 
79
+ ### Secondary
80
+
81
+ ```ts
82
+ import React from 'react';
83
+ import { MenuToggle } from '@patternfly/react-core';
84
+ import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
85
+
86
+ <React.Fragment>
87
+ <MenuToggle variant="secondary">Collapsed</MenuToggle>{' '}
88
+ <MenuToggle variant="secondary" icon={<CogIcon />}>
89
+ Icon
90
+ </MenuToggle>{' '}
91
+ <MenuToggle variant="secondary" isExpanded>
92
+ Expanded
93
+ </MenuToggle>{' '}
94
+ <MenuToggle variant="secondary" isDisabled>
95
+ Disabled
96
+ </MenuToggle>
97
+ </React.Fragment>
98
+
99
+ ```
100
+
87
101
  ### Plain
88
102
 
89
103
  ```ts
@@ -123,6 +137,34 @@ import { MenuToggle } from '@patternfly/react-core';
123
137
  </React.Fragment>
124
138
  ```
125
139
 
140
+
141
+ ### With icon/image and text
142
+
143
+ ```ts
144
+ import React from 'react';
145
+ import { MenuToggle, Avatar } from '@patternfly/react-core';
146
+ import CogIcon from '@patternfly/react-icons/dist/esm/icons/cog-icon';
147
+
148
+ <React.Fragment>
149
+ <MenuToggle icon={<CogIcon />} variant="secondary">Icon</MenuToggle>{' '}
150
+ <MenuToggle icon={<CogIcon />} variant="secondary" isDisabled>Icon</MenuToggle>
151
+ </React.Fragment>
152
+ ```
153
+
154
+ ### With avatar and text
155
+
156
+ ```ts
157
+ import React from 'react';
158
+ import { MenuToggle, Avatar } from '@patternfly/react-core';
159
+ import imgAvatar from '@patternfly/react-core/src/components/Avatar/examples/avatarImg.svg';
160
+
161
+ <React.Fragment>
162
+ <MenuToggle icon={<Avatar src={imgAvatar} alt="avatar" />}>Ned Username</MenuToggle>{' '}
163
+ <MenuToggle icon={<Avatar src={imgAvatar} alt="avatar" />} isExpanded>Ned Username</MenuToggle>{' '}
164
+ <MenuToggle icon={<Avatar src={imgAvatar} alt="avatar" />} isDisabled>Ned Username</MenuToggle>
165
+ </React.Fragment>
166
+ ```
167
+
126
168
  ### Full height
127
169
 
128
170
  ```ts
@@ -67,7 +67,7 @@ export interface PopoverProps {
67
67
  /** Distance of the popover to its target, defaults to 25 */
68
68
  distance?: number;
69
69
  /**
70
- * If true, tries to keep the popover in view by flipping it if necessary
70
+ * If true, tries to keep the popover in view by flipping it if necessary.
71
71
  * If the position is set to 'auto', this prop is ignored
72
72
  */
73
73
  enableFlip?: boolean;
@@ -122,7 +122,7 @@ export interface SelectProps
122
122
  isPlaceholder?: boolean
123
123
  ) => void;
124
124
  /** Callback for toggle button behavior */
125
- onToggle: (isExpanded: boolean) => void;
125
+ onToggle: (isExpanded: boolean, event: React.MouseEvent | React.ChangeEvent | React.KeyboardEvent | Event) => void;
126
126
  /** Callback for typeahead clear button */
127
127
  onClear?: (event: React.MouseEvent) => void;
128
128
  /** Optional callback for custom filtering */
@@ -159,6 +159,8 @@ export interface SelectProps
159
159
  isInputValuePersisted?: boolean;
160
160
  /** @beta Flag for retaining filter results on blur from keyboard-entered typeahead text */
161
161
  isInputFilterPersisted?: boolean;
162
+ /** Flag indicating the typeahead input value should reset upon selection */
163
+ shouldResetOnSelect?: boolean;
162
164
  /** Content rendered in the footer of the select menu */
163
165
  footer?: React.ReactNode;
164
166
  }
@@ -232,7 +234,8 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
232
234
  chipGroupComponent: null,
233
235
  isInputValuePersisted: false,
234
236
  isInputFilterPersisted: false,
235
- isCreateSelectOptionObject: false
237
+ isCreateSelectOptionObject: false,
238
+ shouldResetOnSelect: true
236
239
  };
237
240
 
238
241
  state: SelectState = {
@@ -328,7 +331,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
328
331
  this.setState({ focusFirstOption: true });
329
332
  };
330
333
 
331
- onToggle = (isExpanded: boolean) => {
334
+ onToggle = (isExpanded: boolean, e: React.MouseEvent | React.ChangeEvent | React.KeyboardEvent | Event) => {
332
335
  const { isInputValuePersisted, onSelect, onToggle, hasInlineFilter } = this.props;
333
336
  if (!isExpanded && isInputValuePersisted && onSelect) {
334
337
  onSelect(undefined, this.inputRef.current ? this.inputRef.current.value : '');
@@ -338,7 +341,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
338
341
  focusFirstOption: true
339
342
  });
340
343
  }
341
- onToggle(isExpanded);
344
+ onToggle(isExpanded, e);
342
345
  };
343
346
 
344
347
  onClose = () => {
@@ -358,7 +361,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
358
361
 
359
362
  onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
360
363
  if (e.target.value.toString() !== '' && !this.props.isOpen) {
361
- this.onToggle(true);
364
+ this.onToggle(true, e);
362
365
  }
363
366
 
364
367
  if (this.props.onTypeaheadInputChanged) {
@@ -503,9 +506,9 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
503
506
  });
504
507
  };
505
508
 
506
- onClick = (_e: React.MouseEvent) => {
509
+ onClick = (e: React.MouseEvent) => {
507
510
  if (!this.props.isOpen) {
508
- this.onToggle(true);
511
+ this.onToggle(true, e);
509
512
  }
510
513
  };
511
514
 
@@ -678,10 +681,20 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
678
681
  typeaheadCurrIndex !== -1 && // do not allow selection without moving to an initial option
679
682
  (typeaheadActiveChild || (this.refCollection[0] && this.refCollection[0][0]))
680
683
  ) {
681
- this.setState({
682
- typeaheadInputValue:
683
- (typeaheadActiveChild && typeaheadActiveChild.innerText) || this.refCollection[0][0].innerText
684
- });
684
+ if (typeaheadActiveChild) {
685
+ const hasDescriptionElm = typeaheadActiveChild.childElementCount > 1;
686
+ const typeaheadActiveChildText = hasDescriptionElm
687
+ ? (typeaheadActiveChild.firstChild as HTMLElement).innerText
688
+ : typeaheadActiveChild.innerText;
689
+ this.setState({
690
+ typeaheadInputValue: typeaheadActiveChildText
691
+ });
692
+ } else {
693
+ this.setState({
694
+ typeaheadInputValue: this.refCollection[0][0].innerText
695
+ });
696
+ }
697
+
685
698
  if (typeaheadActiveChild) {
686
699
  typeaheadActiveChild.click();
687
700
  } else {
@@ -755,7 +768,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
755
768
  } else {
756
769
  // Close if there is no footer
757
770
  if (!this.props.footer) {
758
- this.onToggle(false);
771
+ this.onToggle(false, null);
759
772
  this.onClose();
760
773
  } else {
761
774
  // has footer
@@ -764,14 +777,14 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
764
777
  if (this.inputRef.current === document.activeElement) {
765
778
  if (shiftKey) {
766
779
  // close toggle if shift key and tab on input
767
- this.onToggle(false);
780
+ this.onToggle(false, null);
768
781
  this.onClose();
769
782
  } else {
770
783
  // tab to first tabbable item in footer
771
784
  if (tabbableItems[0]) {
772
785
  tabbableItems[0].focus();
773
786
  } else {
774
- this.onToggle(false);
787
+ this.onToggle(false, null);
775
788
  this.onClose();
776
789
  }
777
790
  }
@@ -791,7 +804,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
791
804
  tabbableItems[currentElementIndex + 1].focus();
792
805
  } else {
793
806
  // no next item, close toggle
794
- this.onToggle(false);
807
+ this.onToggle(false, null);
795
808
  this.inputRef.current.focus();
796
809
  this.onClose();
797
810
  }
@@ -947,6 +960,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
947
960
  footer,
948
961
  loadingVariant,
949
962
  isCreateSelectOptionObject,
963
+ shouldResetOnSelect,
950
964
  ...props
951
965
  } = this.props;
952
966
  const {
@@ -1085,7 +1099,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
1085
1099
  } else if (event.key === KeyTypes.Tab && variant !== SelectVariant.checkbox && this.props.footer) {
1086
1100
  // tab to footer or close menu if shift key
1087
1101
  if (event.shiftKey) {
1088
- this.onToggle(false);
1102
+ this.onToggle(false, event);
1089
1103
  } else {
1090
1104
  const tabbableItems = findTabbableElements(this.footerRef, SelectFooterTabbableItems);
1091
1105
  if (tabbableItems.length > 0) {
@@ -1093,7 +1107,7 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
1093
1107
  event.stopPropagation();
1094
1108
  event.preventDefault();
1095
1109
  } else {
1096
- this.onToggle(false);
1110
+ this.onToggle(false, event);
1097
1111
  }
1098
1112
  }
1099
1113
  } else if (event.key === KeyTypes.Tab && variant === SelectVariant.checkbox) {
@@ -1367,7 +1381,14 @@ export class Select extends React.Component<SelectProps & OUIAProps, SelectState
1367
1381
  <GenerateId>
1368
1382
  {randomId => (
1369
1383
  <SelectContext.Provider
1370
- value={{ onSelect, onFavorite, onClose: this.onClose, variant, inputIdPrefix: inputIdPrefix || randomId }}
1384
+ value={{
1385
+ onSelect,
1386
+ onFavorite,
1387
+ onClose: this.onClose,
1388
+ variant,
1389
+ inputIdPrefix: inputIdPrefix || randomId,
1390
+ shouldResetOnSelect
1391
+ }}
1371
1392
  >
1372
1393
  {menuAppendTo === 'inline' ? (
1373
1394
  mainContainer
@@ -245,7 +245,8 @@ export class SelectOption extends React.Component<SelectOptionProps> {
245
245
  onClose: () => void,
246
246
  variant: string,
247
247
  inputIdPrefix: string,
248
- onFavorite: (itemId: string, isFavorite: boolean) => void
248
+ onFavorite: (itemId: string, isFavorite: boolean) => void,
249
+ shouldResetOnSelect: boolean
249
250
  ) => {
250
251
  if (variant !== SelectVariant.checkbox && isLoading && isGrouped) {
251
252
  return (
@@ -323,7 +324,7 @@ export class SelectOption extends React.Component<SelectOptionProps> {
323
324
  if (!isDisabled) {
324
325
  onClick(event);
325
326
  onSelect(event, value, isPlaceholder);
326
- onClose();
327
+ shouldResetOnSelect && onClose();
327
328
  }
328
329
  }}
329
330
  role="option"
@@ -449,8 +450,10 @@ export class SelectOption extends React.Component<SelectOptionProps> {
449
450
 
450
451
  return (
451
452
  <SelectConsumer>
452
- {({ onSelect, onClose, variant, inputIdPrefix, onFavorite }) => (
453
- <React.Fragment>{renderOption(onSelect, onClose, variant, inputIdPrefix, onFavorite)}</React.Fragment>
453
+ {({ onSelect, onClose, variant, inputIdPrefix, onFavorite, shouldResetOnSelect }) => (
454
+ <React.Fragment>
455
+ {renderOption(onSelect, onClose, variant, inputIdPrefix, onFavorite, shouldResetOnSelect)}
456
+ </React.Fragment>
454
457
  )}
455
458
  </SelectConsumer>
456
459
  );