@patternfly/react-core 4.228.0 → 4.230.0

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 (102) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/esm/components/DescriptionList/DescriptionList.d.ts +4 -0
  3. package/dist/esm/components/DescriptionList/DescriptionList.d.ts.map +1 -1
  4. package/dist/esm/components/DescriptionList/DescriptionList.js +5 -2
  5. package/dist/esm/components/DescriptionList/DescriptionList.js.map +1 -1
  6. package/dist/esm/components/DescriptionList/DescriptionListGroup.js.map +1 -1
  7. package/dist/esm/components/Menu/MenuItem.d.ts.map +1 -1
  8. package/dist/esm/components/Menu/MenuItem.js +5 -3
  9. package/dist/esm/components/Menu/MenuItem.js.map +1 -1
  10. package/dist/esm/components/Nav/NavItem.d.ts.map +1 -1
  11. package/dist/esm/components/Nav/NavItem.js +5 -1
  12. package/dist/esm/components/Nav/NavItem.js.map +1 -1
  13. package/dist/esm/components/Page/Page.d.ts +13 -0
  14. package/dist/esm/components/Page/Page.d.ts.map +1 -1
  15. package/dist/esm/components/Page/Page.js +18 -19
  16. package/dist/esm/components/Page/Page.js.map +1 -1
  17. package/dist/esm/components/Page/PageBreadcrumb.d.ts +11 -2
  18. package/dist/esm/components/Page/PageBreadcrumb.d.ts.map +1 -1
  19. package/dist/esm/components/Page/PageBreadcrumb.js +5 -2
  20. package/dist/esm/components/Page/PageBreadcrumb.js.map +1 -1
  21. package/dist/esm/components/Page/PageGroup.d.ts +11 -2
  22. package/dist/esm/components/Page/PageGroup.d.ts.map +1 -1
  23. package/dist/esm/components/Page/PageGroup.js +5 -2
  24. package/dist/esm/components/Page/PageGroup.js.map +1 -1
  25. package/dist/esm/components/Page/PageNavigation.d.ts +11 -2
  26. package/dist/esm/components/Page/PageNavigation.d.ts.map +1 -1
  27. package/dist/esm/components/Page/PageNavigation.js +5 -2
  28. package/dist/esm/components/Page/PageNavigation.js.map +1 -1
  29. package/dist/esm/components/Page/PageSection.d.ts +10 -1
  30. package/dist/esm/components/Page/PageSection.d.ts.map +1 -1
  31. package/dist/esm/components/Page/PageSection.js +4 -2
  32. package/dist/esm/components/Page/PageSection.js.map +1 -1
  33. package/dist/esm/helpers/constants.d.ts +14 -0
  34. package/dist/esm/helpers/constants.d.ts.map +1 -1
  35. package/dist/esm/helpers/constants.js +24 -0
  36. package/dist/esm/helpers/constants.js.map +1 -1
  37. package/dist/esm/helpers/util.d.ts +8 -1
  38. package/dist/esm/helpers/util.d.ts.map +1 -1
  39. package/dist/esm/helpers/util.js +36 -9
  40. package/dist/esm/helpers/util.js.map +1 -1
  41. package/dist/js/components/DescriptionList/DescriptionList.d.ts +4 -0
  42. package/dist/js/components/DescriptionList/DescriptionList.d.ts.map +1 -1
  43. package/dist/js/components/DescriptionList/DescriptionList.js +5 -2
  44. package/dist/js/components/DescriptionList/DescriptionList.js.map +1 -1
  45. package/dist/js/components/DescriptionList/DescriptionListGroup.js.map +1 -1
  46. package/dist/js/components/Menu/MenuItem.d.ts.map +1 -1
  47. package/dist/js/components/Menu/MenuItem.js +5 -3
  48. package/dist/js/components/Menu/MenuItem.js.map +1 -1
  49. package/dist/js/components/Nav/NavItem.d.ts.map +1 -1
  50. package/dist/js/components/Nav/NavItem.js +5 -1
  51. package/dist/js/components/Nav/NavItem.js.map +1 -1
  52. package/dist/js/components/Page/Page.d.ts +13 -0
  53. package/dist/js/components/Page/Page.d.ts.map +1 -1
  54. package/dist/js/components/Page/Page.js +17 -18
  55. package/dist/js/components/Page/Page.js.map +1 -1
  56. package/dist/js/components/Page/PageBreadcrumb.d.ts +11 -2
  57. package/dist/js/components/Page/PageBreadcrumb.d.ts.map +1 -1
  58. package/dist/js/components/Page/PageBreadcrumb.js +5 -2
  59. package/dist/js/components/Page/PageBreadcrumb.js.map +1 -1
  60. package/dist/js/components/Page/PageGroup.d.ts +11 -2
  61. package/dist/js/components/Page/PageGroup.d.ts.map +1 -1
  62. package/dist/js/components/Page/PageGroup.js +5 -2
  63. package/dist/js/components/Page/PageGroup.js.map +1 -1
  64. package/dist/js/components/Page/PageNavigation.d.ts +11 -2
  65. package/dist/js/components/Page/PageNavigation.d.ts.map +1 -1
  66. package/dist/js/components/Page/PageNavigation.js +5 -2
  67. package/dist/js/components/Page/PageNavigation.js.map +1 -1
  68. package/dist/js/components/Page/PageSection.d.ts +10 -1
  69. package/dist/js/components/Page/PageSection.d.ts.map +1 -1
  70. package/dist/js/components/Page/PageSection.js +4 -2
  71. package/dist/js/components/Page/PageSection.js.map +1 -1
  72. package/dist/js/helpers/constants.d.ts +14 -0
  73. package/dist/js/helpers/constants.d.ts.map +1 -1
  74. package/dist/js/helpers/constants.js +26 -1
  75. package/dist/js/helpers/constants.js.map +1 -1
  76. package/dist/js/helpers/util.d.ts +8 -1
  77. package/dist/js/helpers/util.d.ts.map +1 -1
  78. package/dist/js/helpers/util.js +37 -9
  79. package/dist/js/helpers/util.js.map +1 -1
  80. package/dist/umd/react-core.js +170 -71
  81. package/dist/umd/react-core.min.js +6 -5
  82. package/package.json +5 -5
  83. package/src/components/DescriptionList/DescriptionList.tsx +14 -0
  84. package/src/components/DescriptionList/DescriptionListGroup.tsx +1 -0
  85. package/src/components/DescriptionList/examples/DescriptionList.md +31 -1
  86. package/src/components/DescriptionList/examples/DescriptionListDisplaySizeAndCard.tsx +63 -0
  87. package/src/components/DescriptionList/examples/DescriptionListDisplaySizeAndCardHorizontalTermWidth.tsx +34 -0
  88. package/src/components/DescriptionList/examples/DescriptionListDisplaySizeAndCardThreeColumn.tsx +34 -0
  89. package/src/components/DescriptionList/examples/DescriptionListWithCard.tsx +62 -0
  90. package/src/components/DescriptionList/examples/DescriptionListWithDisplaySize.tsx +63 -0
  91. package/src/components/Menu/MenuItem.tsx +7 -5
  92. package/src/components/Nav/NavItem.tsx +6 -0
  93. package/src/components/Page/Page.tsx +58 -21
  94. package/src/components/Page/PageBreadcrumb.tsx +37 -20
  95. package/src/components/Page/PageGroup.tsx +35 -19
  96. package/src/components/Page/PageNavigation.tsx +37 -20
  97. package/src/components/Page/PageSection.tsx +41 -25
  98. package/src/components/Page/__tests__/Page.test.tsx +126 -2
  99. package/src/components/Page/__tests__/__snapshots__/Page.test.tsx.snap +683 -14
  100. package/src/demos/Page/Page.md +356 -3
  101. package/src/helpers/constants.ts +28 -0
  102. package/src/helpers/util.ts +44 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "4.228.0",
3
+ "version": "4.230.0",
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,9 +34,9 @@
34
34
  "generate": "node scripts/copyStyles.js"
35
35
  },
36
36
  "dependencies": {
37
- "@patternfly/react-icons": "^4.79.0",
38
- "@patternfly/react-styles": "^4.78.0",
39
- "@patternfly/react-tokens": "^4.80.0",
37
+ "@patternfly/react-icons": "^4.81.0",
38
+ "@patternfly/react-styles": "^4.80.0",
39
+ "@patternfly/react-tokens": "^4.82.0",
40
40
  "focus-trap": "6.9.2",
41
41
  "react-dropzone": "9.0.0",
42
42
  "tippy.js": "5.1.2",
@@ -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": "f02b0e0e72ea0aa326e1d512b1da0397b10e7f9a"
63
+ "gitHead": "2d27d7f9f3eddbd9a38b6e8574d18deeb0a87c7b"
64
64
  }
@@ -30,6 +30,8 @@ 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 display size of the descriptions in the description list.*/
34
+ displaySize?: 'lg' | '2xl';
33
35
  /** Sets the number of columns on the description list at various breakpoints */
34
36
  columnModifier?: {
35
37
  default?: '1Col' | '2Col' | '3Col';
@@ -56,6 +58,8 @@ export interface DescriptionListProps extends Omit<React.HTMLProps<HTMLDListElem
56
58
  xl?: string;
57
59
  '2xl'?: string;
58
60
  };
61
+ /** Sets the description list's term column width.*/
62
+ termWidth?: string;
59
63
  /** Sets the horizontal description list's term column width at various breakpoints. */
60
64
  horizontalTermWidthModifier?: {
61
65
  default?: string;
@@ -86,8 +90,10 @@ export const DescriptionList: React.FunctionComponent<DescriptionListProps> = ({
86
90
  isCompact,
87
91
  isFluid,
88
92
  isFillColumns,
93
+ displaySize,
89
94
  columnModifier,
90
95
  autoFitMinModifier,
96
+ termWidth,
91
97
  horizontalTermWidthModifier,
92
98
  orientation,
93
99
  style,
@@ -99,6 +105,12 @@ export const DescriptionList: React.FunctionComponent<DescriptionListProps> = ({
99
105
  ...setBreakpointModifiers('--pf-c-description-list--GridTemplateColumns--min', autoFitMinModifier)
100
106
  };
101
107
  }
108
+ if (termWidth) {
109
+ style = {
110
+ ...style,
111
+ ...{ '--pf-c-description-list__term--width': termWidth }
112
+ };
113
+ }
102
114
  if (isHorizontal && horizontalTermWidthModifier) {
103
115
  style = {
104
116
  ...style,
@@ -119,6 +131,8 @@ export const DescriptionList: React.FunctionComponent<DescriptionListProps> = ({
119
131
  isCompact && styles.modifiers.compact,
120
132
  isFluid && styles.modifiers.fluid,
121
133
  isFillColumns && styles.modifiers.fillColumns,
134
+ displaySize === 'lg' && styles.modifiers.displayLg,
135
+ displaySize === '2xl' && styles.modifiers.display_2xl,
122
136
  className
123
137
  )}
124
138
  style={style}
@@ -18,4 +18,5 @@ export const DescriptionListGroup: React.FunctionComponent<DescriptionListGroupP
18
18
  {children}
19
19
  </div>
20
20
  );
21
+
21
22
  DescriptionListGroup.displayName = 'DescriptionListGroup';
@@ -11,10 +11,11 @@ propComponents:
11
11
  'DescriptionListTermHelpText',
12
12
  'DescriptionListTermHelpTextButton',
13
13
  'Popover',
14
+ 'Card'
14
15
  ]
15
16
  ---
16
17
 
17
- import { Button, DescriptionList, DescriptionListTerm, DescriptionListDescription, DescriptionListGroup, DescriptionListTermHelpText, DescriptionListTermHelpTextButton, Popover } from '@patternfly/react-core';
18
+ import { Button, DescriptionList, DescriptionListTerm, DescriptionListDescription, DescriptionListGroup, DescriptionListTermHelpText, DescriptionListTermHelpTextButton, Popover, Checkbox, Card } from '@patternfly/react-core';
18
19
  import PlusCircleIcon from '@patternfly/react-icons/dist/esm/icons/plus-circle-icon';
19
20
  import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
20
21
  import BookIcon from '@patternfly/react-icons/dist/esm/icons/book-icon';
@@ -84,6 +85,11 @@ import FlagIcon from '@patternfly/react-icons/dist/esm/icons/flag-icon';
84
85
  ```ts file='./DescriptionListColumnFill.tsx'
85
86
  ```
86
87
 
88
+ ### Display size
89
+
90
+ ```ts file='./DescriptionListWithDisplaySize.tsx'
91
+ ```
92
+
87
93
  ## Responsive column definitions
88
94
 
89
95
  ### Default responsive columns
@@ -120,6 +126,30 @@ import FlagIcon from '@patternfly/react-icons/dist/esm/icons/flag-icon';
120
126
  ```ts file='./DescriptionListDefaultInlineGrid.tsx'
121
127
  ```
122
128
 
129
+ ## Card variants
130
+
131
+ A [card component](/components/card) can be used in place of a description list group.
132
+
133
+ ### Description list with card
134
+
135
+ ```ts file='./DescriptionListWithCard.tsx'
136
+ ```
137
+
138
+ ### Description list with display size and card
139
+
140
+ ```ts file='./DescriptionListDisplaySizeAndCard.tsx'
141
+ ```
142
+
143
+ ### Display size with card, three column on large breakpoint
144
+
145
+ ```ts file='./DescriptionListDisplaySizeAndCardThreeColumn.tsx'
146
+ ```
147
+
148
+ ### Display size with card, horizontal, modified term width
149
+
150
+ ```ts file='./DescriptionListDisplaySizeAndCardHorizontalTermWidth.tsx'
151
+ ```
152
+
123
153
  ## Auto fit
124
154
 
125
155
  ### Auto-fit basic
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import {
3
+ Button,
4
+ DescriptionList,
5
+ DescriptionListTerm,
6
+ DescriptionListDescription,
7
+ Card,
8
+ Checkbox
9
+ } from '@patternfly/react-core';
10
+ import PlusCircleIcon from '@patternfly/react-icons/dist/esm/icons/plus-circle-icon';
11
+
12
+ export const DescriptionListDisplaySizeAndCard: React.FunctionComponent = () => {
13
+ const [isChecked, setIsChecked] = React.useState<boolean>(false);
14
+ const [displaySize, setDisplaySize] = React.useState<'lg' | '2xl'>('lg');
15
+
16
+ const toggleDisplaySize = (checked: boolean) => {
17
+ setDisplaySize(checked ? '2xl' : 'lg');
18
+ setIsChecked(checked);
19
+ };
20
+
21
+ return (
22
+ <>
23
+ <div style={{ marginBottom: '12px' }}>
24
+ <Checkbox
25
+ label="displaySize 2xl"
26
+ isChecked={isChecked}
27
+ onChange={toggleDisplaySize}
28
+ aria-label="set display size 2xl"
29
+ id="toggle-display-size-with-card"
30
+ name="toggle-display-size-with-card"
31
+ />
32
+ </div>
33
+ <DescriptionList displaySize={displaySize} columnModifier={{ lg: '2Col' }}>
34
+ <Card component="div">
35
+ <DescriptionListTerm>Name</DescriptionListTerm>
36
+ <DescriptionListDescription>Example</DescriptionListDescription>
37
+ </Card>
38
+ <Card component="div">
39
+ <DescriptionListTerm>Namespace</DescriptionListTerm>
40
+ <DescriptionListDescription>
41
+ <a href="#">mary-test</a>
42
+ </DescriptionListDescription>
43
+ </Card>
44
+ <Card component="div">
45
+ <DescriptionListTerm>Labels</DescriptionListTerm>
46
+ <DescriptionListDescription>example</DescriptionListDescription>
47
+ </Card>
48
+ <Card component="div">
49
+ <DescriptionListTerm>Pod selector</DescriptionListTerm>
50
+ <DescriptionListDescription>
51
+ <Button variant="link" isInline icon={<PlusCircleIcon />}>
52
+ app=MyApp
53
+ </Button>
54
+ </DescriptionListDescription>
55
+ </Card>
56
+ <Card component="div">
57
+ <DescriptionListTerm>Annotation</DescriptionListTerm>
58
+ <DescriptionListDescription>2 Annotations</DescriptionListDescription>
59
+ </Card>
60
+ </DescriptionList>
61
+ </>
62
+ );
63
+ };
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { Button, DescriptionList, DescriptionListTerm, DescriptionListDescription, Card } from '@patternfly/react-core';
3
+ import PlusCircleIcon from '@patternfly/react-icons/dist/esm/icons/plus-circle-icon';
4
+
5
+ export const DescriptionListDisplaySizeAndCardHorizontalTermWidth: React.FunctionComponent = () => (
6
+ <DescriptionList displaySize="lg" isHorizontal columnModifier={{ lg: '2Col' }} termWidth="10ch">
7
+ <Card component="div">
8
+ <DescriptionListTerm>Name</DescriptionListTerm>
9
+ <DescriptionListDescription>Example</DescriptionListDescription>
10
+ </Card>
11
+ <Card component="div">
12
+ <DescriptionListTerm>Namespace</DescriptionListTerm>
13
+ <DescriptionListDescription>
14
+ <a href="#">mary-test</a>
15
+ </DescriptionListDescription>
16
+ </Card>
17
+ <Card component="div">
18
+ <DescriptionListTerm>Labels</DescriptionListTerm>
19
+ <DescriptionListDescription>example</DescriptionListDescription>
20
+ </Card>
21
+ <Card component="div">
22
+ <DescriptionListTerm>Pod selector</DescriptionListTerm>
23
+ <DescriptionListDescription>
24
+ <Button variant="link" isInline icon={<PlusCircleIcon />}>
25
+ app=MyApp
26
+ </Button>
27
+ </DescriptionListDescription>
28
+ </Card>
29
+ <Card component="div">
30
+ <DescriptionListTerm>Annotation</DescriptionListTerm>
31
+ <DescriptionListDescription>2 Annotations</DescriptionListDescription>
32
+ </Card>
33
+ </DescriptionList>
34
+ );
@@ -0,0 +1,34 @@
1
+ import React from 'react';
2
+ import { Button, DescriptionList, DescriptionListTerm, DescriptionListDescription, Card } from '@patternfly/react-core';
3
+ import PlusCircleIcon from '@patternfly/react-icons/dist/esm/icons/plus-circle-icon';
4
+
5
+ export const DescriptionListDisplayLgAndCardThreeColumn: React.FunctionComponent = () => (
6
+ <DescriptionList displaySize="lg" columnModifier={{ lg: '3Col' }}>
7
+ <Card component="div">
8
+ <DescriptionListTerm>Name</DescriptionListTerm>
9
+ <DescriptionListDescription>Example</DescriptionListDescription>
10
+ </Card>
11
+ <Card component="div">
12
+ <DescriptionListTerm>Namespace</DescriptionListTerm>
13
+ <DescriptionListDescription>
14
+ <a href="#">mary-test</a>
15
+ </DescriptionListDescription>
16
+ </Card>
17
+ <Card component="div">
18
+ <DescriptionListTerm>Labels</DescriptionListTerm>
19
+ <DescriptionListDescription>example</DescriptionListDescription>
20
+ </Card>
21
+ <Card component="div">
22
+ <DescriptionListTerm>Pod selector</DescriptionListTerm>
23
+ <DescriptionListDescription>
24
+ <Button variant="link" isInline icon={<PlusCircleIcon />}>
25
+ app=MyApp
26
+ </Button>
27
+ </DescriptionListDescription>
28
+ </Card>
29
+ <Card component="div">
30
+ <DescriptionListTerm>Annotation</DescriptionListTerm>
31
+ <DescriptionListDescription>2 Annotations</DescriptionListDescription>
32
+ </Card>
33
+ </DescriptionList>
34
+ );
@@ -0,0 +1,62 @@
1
+ import React from 'react';
2
+ import {
3
+ Button,
4
+ DescriptionList,
5
+ DescriptionListTerm,
6
+ DescriptionListDescription,
7
+ Card,
8
+ Checkbox
9
+ } from '@patternfly/react-core';
10
+ import PlusCircleIcon from '@patternfly/react-icons/dist/esm/icons/plus-circle-icon';
11
+
12
+ export const DescriptionListWithCard: React.FunctionComponent = () => {
13
+ const [isChecked, setIsChecked] = React.useState<boolean>(false);
14
+ const [isSelectable, setSelectable] = React.useState<boolean>(false);
15
+
16
+ const toggleSelectable = (checked: boolean) => {
17
+ setSelectable(checked ? true : false);
18
+ setIsChecked(checked);
19
+ };
20
+ return (
21
+ <>
22
+ <div style={{ marginBottom: '12px' }}>
23
+ <Checkbox
24
+ label="isSelectable"
25
+ isChecked={isChecked}
26
+ onChange={toggleSelectable}
27
+ aria-label="set isSelectable"
28
+ id="toggle-isSelectable"
29
+ name="toggle-isSelectable"
30
+ />
31
+ </div>
32
+ <DescriptionList columnModifier={{ lg: '2Col' }}>
33
+ <Card component="div" isSelectable={isSelectable}>
34
+ <DescriptionListTerm>Name</DescriptionListTerm>
35
+ <DescriptionListDescription>Example</DescriptionListDescription>
36
+ </Card>
37
+ <Card component="div" isSelectable={isSelectable}>
38
+ <DescriptionListTerm>Namespace</DescriptionListTerm>
39
+ <DescriptionListDescription>
40
+ <a href="#">mary-test</a>
41
+ </DescriptionListDescription>
42
+ </Card>
43
+ <Card component="div" isSelectable={isSelectable}>
44
+ <DescriptionListTerm>Labels</DescriptionListTerm>
45
+ <DescriptionListDescription>example</DescriptionListDescription>
46
+ </Card>
47
+ <Card component="div" isSelectable={isSelectable}>
48
+ <DescriptionListTerm>Pod selector</DescriptionListTerm>
49
+ <DescriptionListDescription>
50
+ <Button variant="link" isInline icon={<PlusCircleIcon />}>
51
+ app=MyApp
52
+ </Button>
53
+ </DescriptionListDescription>
54
+ </Card>
55
+ <Card component="div" isSelectable={isSelectable}>
56
+ <DescriptionListTerm>Annotation</DescriptionListTerm>
57
+ <DescriptionListDescription>2 Annotations</DescriptionListDescription>
58
+ </Card>
59
+ </DescriptionList>
60
+ </>
61
+ );
62
+ };
@@ -0,0 +1,63 @@
1
+ import React from 'react';
2
+ import {
3
+ Button,
4
+ DescriptionList,
5
+ DescriptionListTerm,
6
+ DescriptionListGroup,
7
+ DescriptionListDescription,
8
+ Checkbox
9
+ } from '@patternfly/react-core';
10
+ import PlusCircleIcon from '@patternfly/react-icons/dist/esm/icons/plus-circle-icon';
11
+
12
+ export const DescriptionListWithDisplaySize: React.FunctionComponent = () => {
13
+ const [isChecked, setIsChecked] = React.useState<boolean>(false);
14
+ const [displaySize, setDisplaySize] = React.useState<'lg' | '2xl'>('lg');
15
+
16
+ const toggleDisplaySize = (checked: boolean) => {
17
+ setDisplaySize(checked ? '2xl' : 'lg');
18
+ setIsChecked(checked);
19
+ };
20
+
21
+ return (
22
+ <>
23
+ <div style={{ marginBottom: '12px' }}>
24
+ <Checkbox
25
+ label="displaySize 2xl"
26
+ isChecked={isChecked}
27
+ onChange={toggleDisplaySize}
28
+ aria-label="set display size 2xl"
29
+ id="toggle-display-size"
30
+ name="toggle-display-size"
31
+ />
32
+ </div>
33
+ <DescriptionList displaySize={displaySize} columnModifier={{ lg: '2Col' }}>
34
+ <DescriptionListGroup>
35
+ <DescriptionListTerm>Name</DescriptionListTerm>
36
+ <DescriptionListDescription>Example</DescriptionListDescription>
37
+ </DescriptionListGroup>
38
+ <DescriptionListGroup>
39
+ <DescriptionListTerm>Namespace</DescriptionListTerm>
40
+ <DescriptionListDescription>
41
+ <a href="#">mary-test</a>
42
+ </DescriptionListDescription>
43
+ </DescriptionListGroup>
44
+ <DescriptionListGroup>
45
+ <DescriptionListTerm>Labels</DescriptionListTerm>
46
+ <DescriptionListDescription>example</DescriptionListDescription>
47
+ </DescriptionListGroup>
48
+ <DescriptionListGroup>
49
+ <DescriptionListTerm>Pod selector</DescriptionListTerm>
50
+ <DescriptionListDescription>
51
+ <Button variant="link" isInline icon={<PlusCircleIcon />}>
52
+ app=MyApp
53
+ </Button>
54
+ </DescriptionListDescription>
55
+ </DescriptionListGroup>
56
+ <DescriptionListGroup>
57
+ <DescriptionListTerm>Annotation</DescriptionListTerm>
58
+ <DescriptionListDescription>2 Annotations</DescriptionListDescription>
59
+ </DescriptionListGroup>
60
+ </DescriptionList>
61
+ </>
62
+ );
63
+ };
@@ -192,11 +192,12 @@ const MenuItemBase: React.FunctionComponent<MenuItemProps> = ({
192
192
  }
193
193
  }, [flyoutVisible, flyoutTarget]);
194
194
 
195
- const handleFlyout = (event: React.KeyboardEvent) => {
196
- const key = event.key;
195
+ const handleFlyout = (event: React.KeyboardEvent | React.MouseEvent) => {
196
+ const key = (event as React.KeyboardEvent).key;
197
197
  const target = event.target;
198
+ const type = event.type;
198
199
 
199
- if (key === ' ' || key === 'Enter' || key === 'ArrowRight') {
200
+ if (key === ' ' || key === 'Enter' || key === 'ArrowRight' || type === 'click') {
200
201
  event.stopPropagation();
201
202
  if (!flyoutVisible) {
202
203
  showFlyout(true);
@@ -251,7 +252,7 @@ const MenuItemBase: React.FunctionComponent<MenuItemProps> = ({
251
252
  if (isOnPath) {
252
253
  additionalProps['aria-expanded'] = true;
253
254
  } else if (hasFlyout) {
254
- additionalProps['aria-haspopup'] = true;
255
+ additionalProps['aria-haspopup'] = 'menu';
255
256
  additionalProps['aria-expanded'] = flyoutVisible;
256
257
  }
257
258
  const getAriaCurrent = () => {
@@ -309,12 +310,13 @@ const MenuItemBase: React.FunctionComponent<MenuItemProps> = ({
309
310
  className={css(styles.menuItem, getIsSelected() && !hasCheck && styles.modifiers.selected, className)}
310
311
  aria-current={getAriaCurrent()}
311
312
  {...(!hasCheck && { disabled: isDisabled })}
312
- {...(!hasCheck && { role: 'menuitem' })}
313
+ {...(!hasCheck && !flyoutMenu && { role: 'menuitem' })}
313
314
  ref={innerRef}
314
315
  {...(!hasCheck && {
315
316
  onClick: (event: any) => {
316
317
  onItemSelect(event, onSelect);
317
318
  _drill && _drill();
319
+ flyoutMenu && handleFlyout(event);
318
320
  }
319
321
  })}
320
322
  {...(hasCheck && { htmlFor: randomId })}
@@ -150,6 +150,11 @@ export const NavItem: React.FunctionComponent<NavItemProps> = ({
150
150
  </span>
151
151
  );
152
152
 
153
+ const ariaFlyoutProps = {
154
+ 'aria-haspopup': 'menu',
155
+ 'aria-expanded': flyoutVisible
156
+ };
157
+
153
158
  const renderDefaultLink = (context: any): React.ReactNode => {
154
159
  const preventLinkDefault = preventDefault || !to;
155
160
  return (
@@ -164,6 +169,7 @@ export const NavItem: React.FunctionComponent<NavItemProps> = ({
164
169
  )}
165
170
  aria-current={isActive ? 'page' : null}
166
171
  tabIndex={isNavOpen ? null : '-1'}
172
+ {...(hasFlyout && { ...ariaFlyoutProps })}
167
173
  {...props}
168
174
  >
169
175
  {children}
@@ -4,9 +4,10 @@ import { css } from '@patternfly/react-styles';
4
4
  import globalBreakpointXl from '@patternfly/react-tokens/dist/esm/global_breakpoint_xl';
5
5
  import { debounce, canUseDOM } from '../../helpers/util';
6
6
  import { Drawer, DrawerContent, DrawerContentBody, DrawerPanelContent } from '../Drawer';
7
- import { PageGroup, PageGroupProps } from './PageGroup';
7
+ import { PageBreadcrumbProps } from './PageBreadcrumb';
8
+ import { PageGroupProps } from './PageGroup';
8
9
  import { getResizeObserver } from '../../helpers/resizeObserver';
9
- import { getBreakpoint } from '../../helpers/util';
10
+ import { formatBreakpointMods, getBreakpoint, getVerticalBreakpoint } from '../../helpers/util';
10
11
 
11
12
  export enum PageLayouts {
12
13
  vertical = 'vertical',
@@ -18,14 +19,19 @@ export interface PageContextProps {
18
19
  onNavToggle: () => void;
19
20
  isNavOpen: boolean;
20
21
  width: number;
22
+ height: number;
21
23
  getBreakpoint: (width: number | null) => 'default' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
24
+ getVerticalBreakpoint: (height: number | null) => 'default' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
22
25
  }
26
+
23
27
  export const pageContextDefaults: PageContextProps = {
24
28
  isManagedSidebar: false,
25
29
  isNavOpen: false,
26
30
  onNavToggle: () => null,
27
31
  width: null,
28
- getBreakpoint
32
+ height: null,
33
+ getBreakpoint,
34
+ getVerticalBreakpoint
29
35
  };
30
36
  export const PageContext = React.createContext<PageContextProps>(pageContextDefaults);
31
37
 
@@ -80,6 +86,13 @@ export interface PageProps extends React.HTMLProps<HTMLDivElement> {
80
86
  * https://github.com/patternfly/patternfly-react/blob/main/packages/react-core/src/helpers/util.ts
81
87
  */
82
88
  getBreakpoint?: (width: number | null) => 'default' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
89
+ /**
90
+ * The page resize observer uses the breakpoints returned from this function when adding the pf-m-breakpoint-[default|sm|md|lg|xl|2xl] class
91
+ * You can override the default getVerticalBreakpoint function to return breakpoints at different sizes than the default
92
+ * You can view the default getVerticalBreakpoint function here:
93
+ * https://github.com/patternfly/patternfly-react/blob/main/packages/react-core/src/helpers/util.ts
94
+ */
95
+ getVerticalBreakpoint?: (height: number | null) => 'default' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
83
96
  /** Breadcrumb component for the page */
84
97
  breadcrumb?: React.ReactNode;
85
98
  /** Tertiary nav component for the page */
@@ -94,6 +107,8 @@ export interface PageProps extends React.HTMLProps<HTMLDivElement> {
94
107
  additionalGroupedContent?: React.ReactNode;
95
108
  /** Additional props of the group */
96
109
  groupProps?: PageGroupProps;
110
+ /** Additional props of the breadcrumb */
111
+ breadcrumbProps?: PageBreadcrumbProps;
97
112
  }
98
113
 
99
114
  export interface PageState {
@@ -101,6 +116,7 @@ export interface PageState {
101
116
  mobileIsNavOpen: boolean;
102
117
  mobileView: boolean;
103
118
  width: number;
119
+ height: number;
104
120
  }
105
121
 
106
122
  export class Page extends React.Component<PageProps, PageState> {
@@ -113,7 +129,8 @@ export class Page extends React.Component<PageProps, PageState> {
113
129
  mainTabIndex: -1,
114
130
  isNotificationDrawerExpanded: false,
115
131
  onNotificationDrawerExpand: () => null,
116
- getBreakpoint
132
+ getBreakpoint,
133
+ getVerticalBreakpoint
117
134
  };
118
135
  mainRef = React.createRef<HTMLDivElement>();
119
136
  pageRef = React.createRef<HTMLDivElement>();
@@ -128,7 +145,8 @@ export class Page extends React.Component<PageProps, PageState> {
128
145
  desktopIsNavOpen: managedSidebarOpen,
129
146
  mobileIsNavOpen: false,
130
147
  mobileView: false,
131
- width: null
148
+ width: null,
149
+ height: null
132
150
  };
133
151
  }
134
152
 
@@ -179,7 +197,8 @@ export class Page extends React.Component<PageProps, PageState> {
179
197
  if (mobileView !== this.state.mobileView) {
180
198
  this.setState({ mobileView });
181
199
  }
182
- this.pageRef.current && this.setState({ width: this.pageRef.current.clientWidth });
200
+ this.pageRef.current &&
201
+ this.setState({ width: this.pageRef.current.clientWidth, height: this.pageRef.current.clientHeight });
183
202
  };
184
203
 
185
204
  handleResize = debounce(this.resize, 250);
@@ -223,6 +242,7 @@ export class Page extends React.Component<PageProps, PageState> {
223
242
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
224
243
  onPageResize,
225
244
  getBreakpoint,
245
+ getVerticalBreakpoint,
226
246
  mainAriaLabel,
227
247
  mainTabIndex,
228
248
  tertiaryNav,
@@ -230,16 +250,19 @@ export class Page extends React.Component<PageProps, PageState> {
230
250
  isBreadcrumbGrouped,
231
251
  additionalGroupedContent,
232
252
  groupProps,
253
+ breadcrumbProps,
233
254
  ...rest
234
255
  } = this.props;
235
- const { mobileView, mobileIsNavOpen, desktopIsNavOpen, width } = this.state;
256
+ const { mobileView, mobileIsNavOpen, desktopIsNavOpen, width, height } = this.state;
236
257
 
237
258
  const context = {
238
259
  isManagedSidebar,
239
260
  onNavToggle: mobileView ? this.onNavToggleMobile : this.onNavToggleDesktop,
240
261
  isNavOpen: mobileView ? mobileIsNavOpen : desktopIsNavOpen,
241
262
  width,
242
- getBreakpoint
263
+ height,
264
+ getBreakpoint,
265
+ getVerticalBreakpoint
243
266
  };
244
267
 
245
268
  let nav = null;
@@ -253,25 +276,38 @@ export class Page extends React.Component<PageProps, PageState> {
253
276
  nav = <div className={css(styles.pageMainNav)}>{tertiaryNav}</div>;
254
277
  }
255
278
 
256
- let crumb = null;
257
- if (breadcrumb && isBreadcrumbWidthLimited) {
258
- crumb = (
259
- <section className={css(styles.pageMainBreadcrumb, styles.modifiers.limitWidth)}>
260
- <div className={css(styles.pageMainBody)}>{breadcrumb}</div>
261
- </section>
262
- );
263
- } else if (breadcrumb) {
264
- crumb = <section className={css(styles.pageMainBreadcrumb)}>{breadcrumb}</section>;
265
- }
279
+ const crumb = breadcrumb ? (
280
+ <section
281
+ className={css(
282
+ styles.pageMainBreadcrumb,
283
+ isBreadcrumbWidthLimited && styles.modifiers.limitWidth,
284
+ formatBreakpointMods(
285
+ breadcrumbProps?.stickyOnBreakpoint,
286
+ styles,
287
+ 'sticky-',
288
+ getVerticalBreakpoint(height),
289
+ true
290
+ )
291
+ )}
292
+ >
293
+ {isBreadcrumbWidthLimited ? <div className={css(styles.pageMainBody)}>{breadcrumb}</div> : breadcrumb}
294
+ </section>
295
+ ) : null;
266
296
 
267
297
  const isGrouped = isTertiaryNavGrouped || isBreadcrumbGrouped || additionalGroupedContent;
268
298
 
269
299
  const group = isGrouped ? (
270
- <PageGroup {...groupProps}>
300
+ <div
301
+ className={css(
302
+ styles.pageMainGroup,
303
+ formatBreakpointMods(groupProps?.stickyOnBreakpoint, styles, 'sticky-', getVerticalBreakpoint(height), true)
304
+ )}
305
+ {...groupProps}
306
+ >
271
307
  {isTertiaryNavGrouped && nav}
272
308
  {isBreadcrumbGrouped && crumb}
273
309
  {additionalGroupedContent}
274
- </PageGroup>
310
+ </div>
275
311
  ) : null;
276
312
 
277
313
  const main = (
@@ -299,8 +335,9 @@ export class Page extends React.Component<PageProps, PageState> {
299
335
  {...rest}
300
336
  className={css(
301
337
  styles.page,
302
- width !== null && 'pf-m-resize-observer',
338
+ width !== null && height !== null && 'pf-m-resize-observer',
303
339
  width !== null && `pf-m-breakpoint-${getBreakpoint(width)}`,
340
+ height !== null && `pf-m-height-breakpoint-${getVerticalBreakpoint(height)}`,
304
341
  className
305
342
  )}
306
343
  >