@patternfly/react-core 6.6.1-prerelease.8 → 6.6.1-prerelease.9

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 (159) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/components/package.json +1 -1
  3. package/deprecated/package.json +1 -1
  4. package/dist/dynamic/components/AboutModal/package.json +1 -1
  5. package/dist/dynamic/components/Accordion/package.json +1 -1
  6. package/dist/dynamic/components/ActionList/package.json +1 -1
  7. package/dist/dynamic/components/Alert/package.json +1 -1
  8. package/dist/dynamic/components/Avatar/package.json +1 -1
  9. package/dist/dynamic/components/BackToTop/package.json +1 -1
  10. package/dist/dynamic/components/Backdrop/package.json +1 -1
  11. package/dist/dynamic/components/BackgroundImage/package.json +1 -1
  12. package/dist/dynamic/components/Badge/package.json +1 -1
  13. package/dist/dynamic/components/Banner/package.json +1 -1
  14. package/dist/dynamic/components/Brand/package.json +1 -1
  15. package/dist/dynamic/components/Breadcrumb/package.json +1 -1
  16. package/dist/dynamic/components/Button/package.json +1 -1
  17. package/dist/dynamic/components/CalendarMonth/package.json +1 -1
  18. package/dist/dynamic/components/Card/package.json +1 -1
  19. package/dist/dynamic/components/Checkbox/package.json +1 -1
  20. package/dist/dynamic/components/ClipboardCopy/package.json +1 -1
  21. package/dist/dynamic/components/CodeBlock/package.json +1 -1
  22. package/dist/dynamic/components/Compass/package.json +1 -1
  23. package/dist/dynamic/components/Content/package.json +1 -1
  24. package/dist/dynamic/components/DataList/package.json +1 -1
  25. package/dist/dynamic/components/DatePicker/package.json +1 -1
  26. package/dist/dynamic/components/DescriptionList/package.json +1 -1
  27. package/dist/dynamic/components/Divider/package.json +1 -1
  28. package/dist/dynamic/components/Drawer/package.json +1 -1
  29. package/dist/dynamic/components/Dropdown/package.json +1 -1
  30. package/dist/dynamic/components/DualListSelector/package.json +1 -1
  31. package/dist/dynamic/components/EmptyState/package.json +1 -1
  32. package/dist/dynamic/components/ExpandableSection/package.json +1 -1
  33. package/dist/dynamic/components/FileUpload/package.json +1 -1
  34. package/dist/dynamic/components/Form/package.json +1 -1
  35. package/dist/dynamic/components/FormSelect/package.json +1 -1
  36. package/dist/dynamic/components/HelperText/package.json +1 -1
  37. package/dist/dynamic/components/Hero/package.json +1 -1
  38. package/dist/dynamic/components/Hint/package.json +1 -1
  39. package/dist/dynamic/components/Icon/package.json +1 -1
  40. package/dist/dynamic/components/InputGroup/package.json +1 -1
  41. package/dist/dynamic/components/JumpLinks/package.json +1 -1
  42. package/dist/dynamic/components/Label/package.json +1 -1
  43. package/dist/dynamic/components/List/package.json +1 -1
  44. package/dist/dynamic/components/LoginPage/package.json +1 -1
  45. package/dist/dynamic/components/Masthead/package.json +1 -1
  46. package/dist/dynamic/components/Menu/package.json +1 -1
  47. package/dist/dynamic/components/MenuToggle/package.json +1 -1
  48. package/dist/dynamic/components/Modal/package.json +1 -1
  49. package/dist/dynamic/components/MultipleFileUpload/package.json +1 -1
  50. package/dist/dynamic/components/Nav/package.json +1 -1
  51. package/dist/dynamic/components/NotificationBadge/package.json +1 -1
  52. package/dist/dynamic/components/NotificationDrawer/package.json +1 -1
  53. package/dist/dynamic/components/NumberInput/package.json +1 -1
  54. package/dist/dynamic/components/OverflowMenu/package.json +1 -1
  55. package/dist/dynamic/components/Page/package.json +1 -1
  56. package/dist/dynamic/components/Pagination/package.json +1 -1
  57. package/dist/dynamic/components/Panel/package.json +1 -1
  58. package/dist/dynamic/components/Popover/package.json +1 -1
  59. package/dist/dynamic/components/Progress/package.json +1 -1
  60. package/dist/dynamic/components/ProgressStepper/package.json +1 -1
  61. package/dist/dynamic/components/Radio/package.json +1 -1
  62. package/dist/dynamic/components/SearchInput/package.json +1 -1
  63. package/dist/dynamic/components/Select/package.json +1 -1
  64. package/dist/dynamic/components/Sidebar/package.json +1 -1
  65. package/dist/dynamic/components/SimpleList/package.json +1 -1
  66. package/dist/dynamic/components/Skeleton/package.json +1 -1
  67. package/dist/dynamic/components/SkipToContent/package.json +1 -1
  68. package/dist/dynamic/components/Slider/package.json +1 -1
  69. package/dist/dynamic/components/Spinner/package.json +1 -1
  70. package/dist/dynamic/components/Switch/package.json +1 -1
  71. package/dist/dynamic/components/Tabs/package.json +1 -1
  72. package/dist/dynamic/components/TextArea/package.json +1 -1
  73. package/dist/dynamic/components/TextInput/package.json +1 -1
  74. package/dist/dynamic/components/TextInputGroup/package.json +1 -1
  75. package/dist/dynamic/components/TimePicker/package.json +1 -1
  76. package/dist/dynamic/components/Timestamp/package.json +1 -1
  77. package/dist/dynamic/components/Title/package.json +1 -1
  78. package/dist/dynamic/components/ToggleGroup/package.json +1 -1
  79. package/dist/dynamic/components/Toolbar/package.json +1 -1
  80. package/dist/dynamic/components/Tooltip/package.json +1 -1
  81. package/dist/dynamic/components/TreeView/package.json +1 -1
  82. package/dist/dynamic/components/Truncate/package.json +1 -1
  83. package/dist/dynamic/components/Wizard/hooks/package.json +1 -1
  84. package/dist/dynamic/components/Wizard/package.json +1 -1
  85. package/dist/dynamic/deprecated/components/Chip/package.json +1 -1
  86. package/dist/dynamic/deprecated/components/DragDrop/package.json +1 -1
  87. package/dist/dynamic/deprecated/components/DualListSelector/package.json +1 -1
  88. package/dist/dynamic/deprecated/components/Modal/package.json +1 -1
  89. package/dist/dynamic/deprecated/components/Tile/package.json +1 -1
  90. package/dist/dynamic/deprecated/components/Wizard/package.json +1 -1
  91. package/dist/dynamic/deprecated/components/package.json +1 -1
  92. package/dist/dynamic/helpers/AnimationsProvider/AnimationsProvider/package.json +1 -1
  93. package/dist/dynamic/helpers/AnimationsProvider/package.json +1 -1
  94. package/dist/dynamic/helpers/FocusTrap/FocusTrap/package.json +1 -1
  95. package/dist/dynamic/helpers/GenerateId/GenerateId/package.json +1 -1
  96. package/dist/dynamic/helpers/KeyboardHandler/package.json +1 -1
  97. package/dist/dynamic/helpers/OUIA/ouia/package.json +1 -1
  98. package/dist/dynamic/helpers/Popper/Popper/package.json +1 -1
  99. package/dist/dynamic/helpers/SSRSafeIds/SSRSafeIds/package.json +1 -1
  100. package/dist/dynamic/helpers/constants/package.json +1 -1
  101. package/dist/dynamic/helpers/datetimeUtils/package.json +1 -1
  102. package/dist/dynamic/helpers/fileUtils/package.json +1 -1
  103. package/dist/dynamic/helpers/htmlConstants/package.json +1 -1
  104. package/dist/dynamic/helpers/inert/package.json +1 -1
  105. package/dist/dynamic/helpers/package.json +1 -1
  106. package/dist/dynamic/helpers/resizeObserver/package.json +1 -1
  107. package/dist/dynamic/helpers/typeUtils/package.json +1 -1
  108. package/dist/dynamic/helpers/useInterval/package.json +1 -1
  109. package/dist/dynamic/helpers/useIsomorphicLayout/package.json +1 -1
  110. package/dist/dynamic/helpers/useSSRSafeId/package.json +1 -1
  111. package/dist/dynamic/helpers/useUnmountEffect/package.json +1 -1
  112. package/dist/dynamic/helpers/util/package.json +1 -1
  113. package/dist/dynamic/layouts/Bullseye/package.json +1 -1
  114. package/dist/dynamic/layouts/Flex/package.json +1 -1
  115. package/dist/dynamic/layouts/Gallery/package.json +1 -1
  116. package/dist/dynamic/layouts/Grid/package.json +1 -1
  117. package/dist/dynamic/layouts/Level/package.json +1 -1
  118. package/dist/dynamic/layouts/Split/package.json +1 -1
  119. package/dist/dynamic/layouts/Stack/package.json +1 -1
  120. package/dist/dynamic/styles/package.json +1 -1
  121. package/dist/esm/components/Drawer/Drawer.d.ts +3 -0
  122. package/dist/esm/components/Drawer/Drawer.d.ts.map +1 -1
  123. package/dist/esm/components/Drawer/Drawer.js +4 -3
  124. package/dist/esm/components/Drawer/Drawer.js.map +1 -1
  125. package/dist/esm/components/Drawer/DrawerContent.d.ts +1 -1
  126. package/dist/esm/components/Drawer/DrawerContent.d.ts.map +1 -1
  127. package/dist/esm/components/Drawer/DrawerPanelContent.js +22 -25
  128. package/dist/esm/components/Drawer/DrawerPanelContent.js.map +1 -1
  129. package/dist/js/components/Drawer/Drawer.d.ts +3 -0
  130. package/dist/js/components/Drawer/Drawer.d.ts.map +1 -1
  131. package/dist/js/components/Drawer/Drawer.js +4 -3
  132. package/dist/js/components/Drawer/Drawer.js.map +1 -1
  133. package/dist/js/components/Drawer/DrawerContent.d.ts +1 -1
  134. package/dist/js/components/Drawer/DrawerContent.d.ts.map +1 -1
  135. package/dist/js/components/Drawer/DrawerPanelContent.js +22 -25
  136. package/dist/js/components/Drawer/DrawerPanelContent.js.map +1 -1
  137. package/dist/umd/assets/{output-DfsTC8Iz.css → output-B35Oc6dG.css} +20268 -20257
  138. package/dist/umd/react-core.min.js +1 -1
  139. package/helpers/package.json +1 -1
  140. package/layouts/package.json +1 -1
  141. package/next/package.json +1 -1
  142. package/package.json +6 -6
  143. package/src/components/Drawer/Drawer.tsx +10 -2
  144. package/src/components/Drawer/DrawerContent.tsx +1 -1
  145. package/src/components/Drawer/DrawerPanelContent.tsx +25 -25
  146. package/src/components/Drawer/__tests__/Drawer.test.tsx +53 -0
  147. package/src/components/Drawer/examples/Drawer.md +1 -1
  148. package/src/components/Page/examples/Page.md +24 -12
  149. package/src/components/Page/examples/PageCustomFooter.tsx +59 -0
  150. package/src/components/Page/examples/PageCustomHeader.tsx +17 -0
  151. package/src/components/Page/examples/PagePlain.tsx +9 -0
  152. package/src/demos/CardView/CardView.md +1 -1
  153. package/src/demos/CardView/examples/CardView.tsx +1 -1
  154. package/src/demos/Drawer/Drawer.md +16 -0
  155. package/src/demos/Drawer/examples/DrawerViewport.tsx +112 -0
  156. package/src/demos/Page.md +24 -11
  157. package/src/demos/examples/Page/PagePlain.tsx +342 -0
  158. package/src/components/Page/examples/PageHeaderAndFooterContent.tsx +0 -20
  159. package/src/demos/examples/Page/PageStickySectionGroupUsingPageHeader.tsx +0 -0
@@ -1 +1 @@
1
- {"name":"@patternfly/react-core-helpers","main":"../dist/js/helpers/index.js","module":"../dist/esm/helpers/index.js","typings":"../dist/esm/helpers/index.d.ts","version":"6.6.1-prerelease.7","private":true}
1
+ {"name":"@patternfly/react-core-helpers","main":"../dist/js/helpers/index.js","module":"../dist/esm/helpers/index.js","typings":"../dist/esm/helpers/index.d.ts","version":"6.6.1-prerelease.8","private":true}
@@ -1 +1 @@
1
- {"name":"@patternfly/react-core-layouts","main":"../dist/js/layouts/index.js","module":"../dist/esm/layouts/index.js","typings":"../dist/esm/layouts/index.d.ts","version":"6.6.1-prerelease.7","private":true}
1
+ {"name":"@patternfly/react-core-layouts","main":"../dist/js/layouts/index.js","module":"../dist/esm/layouts/index.js","typings":"../dist/esm/layouts/index.d.ts","version":"6.6.1-prerelease.8","private":true}
package/next/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"@patternfly/react-core-next","main":"../dist/js/next/index.js","module":"../dist/esm/next/index.js","typings":"../dist/esm/next/index.d.ts","version":"6.6.1-prerelease.7","private":true}
1
+ {"name":"@patternfly/react-core-next","main":"../dist/js/next/index.js","module":"../dist/esm/next/index.js","typings":"../dist/esm/next/index.d.ts","version":"6.6.1-prerelease.8","private":true}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@patternfly/react-core",
3
- "version": "6.6.1-prerelease.8",
3
+ "version": "6.6.1-prerelease.9",
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",
@@ -46,15 +46,15 @@
46
46
  "subpaths": "node ../../scripts/exportSubpaths.mjs --config subpaths.config.json"
47
47
  },
48
48
  "dependencies": {
49
- "@patternfly/react-icons": "^6.6.1-prerelease.3",
50
- "@patternfly/react-styles": "^6.6.1-prerelease.2",
51
- "@patternfly/react-tokens": "^6.6.1-prerelease.2",
49
+ "@patternfly/react-icons": "^6.6.1-prerelease.4",
50
+ "@patternfly/react-styles": "^6.6.1-prerelease.3",
51
+ "@patternfly/react-tokens": "^6.6.1-prerelease.3",
52
52
  "focus-trap": "7.6.6",
53
53
  "react-dropzone": "^14.3.5",
54
54
  "tslib": "^2.8.1"
55
55
  },
56
56
  "devDependencies": {
57
- "@patternfly/patternfly": "6.6.0-prerelease.40",
57
+ "@patternfly/patternfly": "6.6.0-prerelease.41",
58
58
  "case-anything": "^3.1.2",
59
59
  "css": "^3.0.0",
60
60
  "fs-extra": "^11.3.3"
@@ -63,5 +63,5 @@
63
63
  "react": "^17 || ^18 || ^19",
64
64
  "react-dom": "^17 || ^18 || ^19"
65
65
  },
66
- "gitHead": "008744f97e0d226d41c0bec0b78ec938943392e3"
66
+ "gitHead": "103c595fefeee9e6cf6209cc94154b0551702f18"
67
67
  }
@@ -23,6 +23,8 @@ export interface DrawerProps extends React.HTMLProps<HTMLDivElement>, OUIAProps
23
23
  isInline?: boolean;
24
24
  /** @beta Indicates if the drawer will have pill styles */
25
25
  isPill?: boolean;
26
+ /** @beta Positions the drawer as fixed to fill the viewport. Place the drawer after Page as a sibling. */
27
+ isViewport?: boolean;
26
28
  /** Indicates if the drawer will always show both content and panel. */
27
29
  isStatic?: boolean;
28
30
  /** Position of the drawer panel. left and right are deprecated, use start and end instead. */
@@ -43,6 +45,7 @@ export interface DrawerContextProps {
43
45
  drawerRef?: React.RefObject<HTMLDivElement | null>;
44
46
  drawerContentRef?: React.RefObject<HTMLDivElement | null>;
45
47
  isInline: boolean;
48
+ isViewport: boolean;
46
49
  }
47
50
 
48
51
  export const DrawerContext = createContext<Partial<DrawerContextProps>>({
@@ -52,7 +55,8 @@ export const DrawerContext = createContext<Partial<DrawerContextProps>>({
52
55
  position: 'end',
53
56
  drawerRef: null,
54
57
  drawerContentRef: null,
55
- isInline: false
58
+ isInline: false,
59
+ isViewport: false
56
60
  });
57
61
 
58
62
  export const Drawer: React.FunctionComponent<DrawerProps> = ({
@@ -61,6 +65,7 @@ export const Drawer: React.FunctionComponent<DrawerProps> = ({
61
65
  isExpanded = false,
62
66
  isInline = false,
63
67
  isPill = false,
68
+ isViewport = false,
64
69
  isStatic = false,
65
70
  position = 'end',
66
71
  onExpand = () => {},
@@ -73,13 +78,16 @@ export const Drawer: React.FunctionComponent<DrawerProps> = ({
73
78
  const drawerContentRef = useRef<HTMLDivElement>(undefined);
74
79
 
75
80
  return (
76
- <DrawerContext.Provider value={{ isExpanded, isStatic, onExpand, position, drawerRef, drawerContentRef, isInline }}>
81
+ <DrawerContext.Provider
82
+ value={{ isExpanded, isStatic, onExpand, position, drawerRef, drawerContentRef, isInline, isViewport }}
83
+ >
77
84
  <div
78
85
  className={css(
79
86
  styles.drawer,
80
87
  isExpanded && styles.modifiers.expanded,
81
88
  isInline && styles.modifiers.inline,
82
89
  isPill && styles.modifiers.pill,
90
+ isViewport && styles.modifiers.viewport,
83
91
  isStatic && styles.modifiers.static,
84
92
  (position === 'left' || position === 'start') && styles.modifiers.panelLeft,
85
93
  position === 'bottom' && styles.modifiers.panelBottom,
@@ -13,7 +13,7 @@ export enum DrawerContentColorVariant {
13
13
  export interface DrawerContentProps extends React.HTMLProps<HTMLDivElement> {
14
14
  /** Additional classes added to the Drawer. */
15
15
  className?: string;
16
- /** Content to be rendered in the drawer. */
16
+ /** Content to be rendered in the drawer. Can be omitted to leave the content container empty. */
17
17
  children?: React.ReactNode;
18
18
  /** Content rendered in the drawer panel. */
19
19
  panelContent: React.ReactNode;
@@ -100,7 +100,8 @@ export const DrawerPanelContent: React.FunctionComponent<DrawerPanelContentProps
100
100
  const panel = useRef<HTMLDivElement>(undefined);
101
101
  const splitterRef = useRef<HTMLDivElement>(undefined);
102
102
  const [separatorValue, setSeparatorValue] = useState(0);
103
- const { position, isExpanded, isStatic, onExpand, drawerRef, drawerContentRef, isInline } = useContext(DrawerContext);
103
+ const { position, isExpanded, isStatic, onExpand, drawerRef, drawerContentRef, isInline, isViewport } =
104
+ useContext(DrawerContext);
104
105
  const hidden = isStatic ? false : !isExpanded;
105
106
  const [isExpandedInternal, setIsExpandedInternal] = useState(!hidden);
106
107
  const [isFocusTrapActive, setIsFocusTrapActive] = useState(false);
@@ -126,9 +127,22 @@ export const DrawerPanelContent: React.FunctionComponent<DrawerPanelContentProps
126
127
  }
127
128
  }, [isStatic, isExpanded]);
128
129
 
130
+ const getSizeElement = () => {
131
+ if (isViewport) {
132
+ return drawerRef?.current ?? drawerContentRef?.current;
133
+ }
134
+ return drawerContentRef?.current ?? drawerRef?.current;
135
+ };
136
+
129
137
  const calcValueNow = () => {
130
138
  let splitterPos;
131
139
  let drawerSize;
140
+ const sizeEl = getSizeElement();
141
+
142
+ if (!sizeEl || !panel.current || !splitterRef.current || !drawerRef?.current) {
143
+ return 0;
144
+ }
145
+
132
146
  const isRTL = getLanguageDirection(panel.current) === 'rtl';
133
147
 
134
148
  if (isInline && (position === 'end' || position === 'right')) {
@@ -149,37 +163,23 @@ export const DrawerPanelContent: React.FunctionComponent<DrawerPanelContentProps
149
163
  }
150
164
  } else if (position === 'end' || position === 'right') {
151
165
  if (isRTL) {
152
- splitterPos =
153
- drawerContentRef.current.getBoundingClientRect().left - splitterRef.current.getBoundingClientRect().right;
154
- drawerSize =
155
- drawerContentRef.current.getBoundingClientRect().left -
156
- drawerContentRef.current.getBoundingClientRect().right;
166
+ splitterPos = sizeEl.getBoundingClientRect().left - splitterRef.current.getBoundingClientRect().right;
167
+ drawerSize = sizeEl.getBoundingClientRect().left - sizeEl.getBoundingClientRect().right;
157
168
  } else {
158
- splitterPos =
159
- drawerContentRef.current.getBoundingClientRect().right - splitterRef.current.getBoundingClientRect().left;
160
- drawerSize =
161
- drawerContentRef.current.getBoundingClientRect().right -
162
- drawerContentRef.current.getBoundingClientRect().left;
169
+ splitterPos = sizeEl.getBoundingClientRect().right - splitterRef.current.getBoundingClientRect().left;
170
+ drawerSize = sizeEl.getBoundingClientRect().right - sizeEl.getBoundingClientRect().left;
163
171
  }
164
172
  } else if (position === 'start' || position === 'left') {
165
173
  if (isRTL) {
166
- splitterPos =
167
- splitterRef.current.getBoundingClientRect().left - drawerContentRef.current.getBoundingClientRect().right;
168
- drawerSize =
169
- drawerContentRef.current.getBoundingClientRect().left -
170
- drawerContentRef.current.getBoundingClientRect().right;
174
+ splitterPos = splitterRef.current.getBoundingClientRect().left - sizeEl.getBoundingClientRect().right;
175
+ drawerSize = sizeEl.getBoundingClientRect().left - sizeEl.getBoundingClientRect().right;
171
176
  } else {
172
- splitterPos =
173
- splitterRef.current.getBoundingClientRect().right - drawerContentRef.current.getBoundingClientRect().left;
174
- drawerSize =
175
- drawerContentRef.current.getBoundingClientRect().right -
176
- drawerContentRef.current.getBoundingClientRect().left;
177
+ splitterPos = splitterRef.current.getBoundingClientRect().right - sizeEl.getBoundingClientRect().left;
178
+ drawerSize = sizeEl.getBoundingClientRect().right - sizeEl.getBoundingClientRect().left;
177
179
  }
178
180
  } else if (position === 'bottom') {
179
- splitterPos =
180
- drawerContentRef.current.getBoundingClientRect().bottom - splitterRef.current.getBoundingClientRect().top;
181
- drawerSize =
182
- drawerContentRef.current.getBoundingClientRect().bottom - drawerContentRef.current.getBoundingClientRect().top;
181
+ splitterPos = sizeEl.getBoundingClientRect().bottom - splitterRef.current.getBoundingClientRect().top;
182
+ drawerSize = sizeEl.getBoundingClientRect().bottom - sizeEl.getBoundingClientRect().top;
183
183
  }
184
184
 
185
185
  const newSplitterPos = (splitterPos / drawerSize) * 100;
@@ -231,3 +231,56 @@ test('Renders with ouiaSafe=false when specified', () => {
231
231
  );
232
232
  expect(screen.getByTestId('drawer')).toHaveAttribute('data-ouia-safe', 'false');
233
233
  });
234
+
235
+ test(`Does not render with ${styles.modifiers.viewport} class by default`, () => {
236
+ render(
237
+ <Drawer data-testid="drawer">
238
+ <DrawerContent panelContent={<DrawerPanelContent>panel</DrawerPanelContent>}>
239
+ <DrawerContentBody>content</DrawerContentBody>
240
+ </DrawerContent>
241
+ </Drawer>
242
+ );
243
+
244
+ expect(screen.getByTestId('drawer')).not.toHaveClass(styles.modifiers.viewport);
245
+ });
246
+
247
+ test(`Renders with ${styles.modifiers.viewport} when isViewport is specified`, () => {
248
+ render(
249
+ <Drawer data-testid="drawer" isViewport>
250
+ <DrawerContent panelContent={<DrawerPanelContent>panel</DrawerPanelContent>}>
251
+ <DrawerContentBody>content</DrawerContentBody>
252
+ </DrawerContent>
253
+ </Drawer>
254
+ );
255
+
256
+ expect(screen.getByTestId('drawer')).toHaveClass(styles.modifiers.viewport);
257
+ });
258
+
259
+ test('Resizeable DrawerPanelContent without drawer content does not throw', async () => {
260
+ const consoleError = jest.spyOn(console, 'error').mockImplementation();
261
+
262
+ const panelContent = (
263
+ <DrawerPanelContent isResizable>
264
+ <DrawerHead>
265
+ <span>drawer-panel</span>
266
+ <DrawerActions>
267
+ <DrawerCloseButton />
268
+ </DrawerActions>
269
+ </DrawerHead>
270
+ </DrawerPanelContent>
271
+ );
272
+
273
+ const user = userEvent.setup();
274
+
275
+ render(
276
+ <Drawer isExpanded isViewport>
277
+ <DrawerContent panelContent={panelContent} />
278
+ </Drawer>
279
+ );
280
+
281
+ await user.tab();
282
+ await user.keyboard(`{${KeyTypes.ArrowLeft}}`);
283
+
284
+ expect(consoleError).not.toHaveBeenCalled();
285
+ consoleError.mockRestore();
286
+ });
@@ -13,7 +13,7 @@ propComponents:
13
13
  DrawerCloseButton,
14
14
  DrawerPanelDescription,
15
15
  DrawerPanelBody,
16
- DrawerPanelFocusTrapObject,
16
+ DrawerPanelFocusTrapObject
17
17
  ]
18
18
  section: components
19
19
  ---
@@ -33,18 +33,6 @@ The `<MastheadMain>` component includes the smaller area that typically contains
33
33
  - 1 or more `<PageSidebarBody>` components inside `<PageSidebar>` for vertical navigation or other sidebar content
34
34
  - 1 or more `<PageSection>` components
35
35
 
36
- ### Page header and footer
37
-
38
- To use a page header instead of passing a [masthead](/components/masthead) directly, pass a `<PageHeader>` to the `masthead` property. `<PageHeader>` should only be used to wrap custom header content.
39
-
40
- `<PageFooter>` can be passed to the `footer` property, and should be used to wrap custom footer content.
41
-
42
- When using a custom `<PageHeader>` and `<PageFooter>`, the `isPlain` flag should be passed to `<Page>`. This will remove styling on the main container, the height constraints on the page wrapper (so it can grow beyond the viewport), and remove the scroll management from the content section so the window will be what scrolls.
43
-
44
- ```ts file="./PageHeaderAndFooterContent.tsx"
45
-
46
- ```
47
-
48
36
  ### Vertical navigation
49
37
 
50
38
  To add a vertical sidebar to a `<Page>`, pass a `<PageSidebar>` component into the `sidebar` property. To render navigation in the sidebar, pass a `<PageSidebarBody>` component to `<PageSidebar>`.
@@ -162,3 +150,27 @@ In this example, a scroll event listener on the scroll parent container toggles
162
150
  ```ts file="./PageDynamicStickySection.tsx"
163
151
 
164
152
  ```
153
+
154
+ ### Custom header
155
+
156
+ To use a page header instead of passing a [masthead](/components/masthead) directly, pass a `<PageHeader>` to the `masthead` property. `<PageHeader>` should only be used to wrap custom header content.
157
+
158
+ ```ts isBeta file="./PageCustomHeader.tsx"
159
+
160
+ ```
161
+
162
+ ### Footer
163
+
164
+ `<PageFooter>` can be passed to the `footer` property, and should be used to wrap custom footer content.
165
+
166
+ ```ts isBeta file="./PageCustomFooter.tsx"
167
+
168
+ ```
169
+
170
+ ### Plain
171
+
172
+ When a page should not have the default content area background or overflow scrolling, pass the `isPlain` property to `<Page>`.
173
+
174
+ ```ts isBeta file="./PagePlain.tsx"
175
+
176
+ ```
@@ -0,0 +1,59 @@
1
+ import { useState } from 'react';
2
+ import {
3
+ Masthead,
4
+ MastheadMain,
5
+ MastheadToggle,
6
+ MastheadBrand,
7
+ MastheadLogo,
8
+ MastheadContent,
9
+ Page,
10
+ PageFooter,
11
+ PageSection,
12
+ PageSidebar,
13
+ PageSidebarBody,
14
+ PageToggleButton
15
+ } from '@patternfly/react-core';
16
+
17
+ export const PageCustomFooter: React.FunctionComponent = () => {
18
+ const [isSidebarOpen, setIsSidebarOpen] = useState(true);
19
+
20
+ const onSidebarToggle = () => {
21
+ setIsSidebarOpen(!isSidebarOpen);
22
+ };
23
+
24
+ const masthead = (
25
+ <Masthead>
26
+ <MastheadMain>
27
+ <MastheadToggle>
28
+ <PageToggleButton
29
+ aria-label="Global navigation"
30
+ isSidebarOpen={isSidebarOpen}
31
+ onSidebarToggle={onSidebarToggle}
32
+ id="custom-footer-body-nav-toggle"
33
+ isHamburgerButton
34
+ />
35
+ </MastheadToggle>
36
+ <MastheadBrand>
37
+ <MastheadLogo href="https://patternfly.org" target="_blank">
38
+ Logo
39
+ </MastheadLogo>
40
+ </MastheadBrand>
41
+ </MastheadMain>
42
+ <MastheadContent>Content</MastheadContent>
43
+ </Masthead>
44
+ );
45
+
46
+ const sidebar = (
47
+ <PageSidebar isSidebarOpen={isSidebarOpen} id="custom-footer-vertical-sidebar">
48
+ <PageSidebarBody>Navigation</PageSidebarBody>
49
+ </PageSidebar>
50
+ );
51
+
52
+ return (
53
+ <Page footer={<PageFooter>Page footer</PageFooter>} masthead={masthead} sidebar={sidebar}>
54
+ <PageSection aria-labelledby="custom-footer-section">
55
+ <h2 id="custom-footer-section">Page content</h2>
56
+ </PageSection>
57
+ </Page>
58
+ );
59
+ };
@@ -0,0 +1,17 @@
1
+ import { Page, PageHeader, PageSection, PageSidebar, PageSidebarBody } from '@patternfly/react-core';
2
+
3
+ export const PageCustomHeader: React.FunctionComponent = () => {
4
+ const sidebar = (
5
+ <PageSidebar isSidebarOpen id="custom-header-vertical-sidebar">
6
+ <PageSidebarBody>Navigation</PageSidebarBody>
7
+ </PageSidebar>
8
+ );
9
+
10
+ return (
11
+ <Page masthead={<PageHeader>Custom page header</PageHeader>} sidebar={sidebar}>
12
+ <PageSection aria-labelledby="custom-header-section">
13
+ <h2 id="custom-header-section">Page content</h2>
14
+ </PageSection>
15
+ </Page>
16
+ );
17
+ };
@@ -0,0 +1,9 @@
1
+ import { Page, PageHeader, PageSection } from '@patternfly/react-core';
2
+
3
+ export const PagePlain: React.FunctionComponent = () => (
4
+ <Page isPlain masthead={<PageHeader>Custom header</PageHeader>} sidebar={null}>
5
+ <PageSection aria-labelledby="plain-page-section">
6
+ <h2 id="plain-page-section">Page content</h2>
7
+ </PageSection>
8
+ </Page>
9
+ );
@@ -6,7 +6,7 @@ section: patterns
6
6
  import { Fragment, useState } from 'react';
7
7
  import RhUiTrashFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-trash-fill-icon';
8
8
  import RhUiAddCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-add-circle-fill-icon';
9
- import pfIcon from '../assets/pf-logo-small.svg';
9
+ import pfIcon from '@patternfly/react-core/src/demos/assets/PF-IconLogo.svg';
10
10
  import activeMQIcon from '../assets/activemq-core_200x150.png';
11
11
  import avroIcon from '../assets/camel-avro_200x150.png';
12
12
  import dropBoxIcon from '../assets/camel-dropbox_200x150.png';
@@ -36,7 +36,7 @@ import {
36
36
  } from '@patternfly/react-core';
37
37
  import RhUiTrashFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-trash-fill-icon';
38
38
  import RhUiAddCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-add-circle-fill-icon';
39
- import pfIcon from './assets/pf-logo-small.svg';
39
+ import pfIcon from '@patternfly/react-core/src/demos/assets/PF-IconLogo.svg';
40
40
  import activeMQIcon from './assets/activemq-core_200x150.png';
41
41
  import avroIcon from './assets/camel-avro_200x150.png';
42
42
  import dropBoxIcon from './assets/camel-dropbox_200x150.png';
@@ -0,0 +1,16 @@
1
+ ---
2
+ id: Drawer
3
+ section: components
4
+ ---
5
+
6
+ import { Fragment, useRef, useState } from 'react';
7
+
8
+ ## Demos
9
+
10
+ ### Expanded resizable viewport drawer
11
+
12
+ Use `isViewport` to position the drawer as `fixed` so it fills the viewport. Place the drawer after `<Page>` as a sibling. Omit children of `<DrawerContent>` so the content container stays empty; the empty container is still required so the panel can overlay the page.
13
+
14
+ ```ts file="./examples/DrawerViewport.tsx" isFullscreen isBeta
15
+
16
+ ```
@@ -0,0 +1,112 @@
1
+ import { Fragment, useRef, useState } from 'react';
2
+ import {
3
+ Backdrop,
4
+ Button,
5
+ Drawer,
6
+ DrawerActions,
7
+ DrawerCloseButton,
8
+ DrawerContent,
9
+ DrawerHead,
10
+ DrawerPanelContent,
11
+ Masthead,
12
+ MastheadBrand,
13
+ MastheadContent,
14
+ MastheadLogo,
15
+ MastheadMain,
16
+ MastheadToggle,
17
+ Page,
18
+ PageSection,
19
+ PageSidebar,
20
+ PageSidebarBody,
21
+ PageToggleButton,
22
+ Toolbar,
23
+ ToolbarContent,
24
+ ToolbarItem
25
+ } from '@patternfly/react-core';
26
+
27
+ export const DrawerViewport: React.FunctionComponent = () => {
28
+ const [isExpanded, setIsExpanded] = useState(true);
29
+ const drawerRef = useRef<HTMLSpanElement>(null);
30
+
31
+ const onExpand = () => {
32
+ drawerRef.current && drawerRef.current.focus();
33
+ };
34
+
35
+ const onClick = () => {
36
+ setIsExpanded(!isExpanded);
37
+ };
38
+
39
+ const onCloseClick = () => {
40
+ setIsExpanded(false);
41
+ };
42
+
43
+ const onResize = (_event: MouseEvent | TouchEvent | React.KeyboardEvent, newWidth: number, id: string) => {
44
+ // eslint-disable-next-line no-console
45
+ console.log(`${id} has new width of: ${newWidth}`);
46
+ };
47
+
48
+ const headerToolbar = (
49
+ <Toolbar id="viewport-drawer-toolbar">
50
+ <ToolbarContent>
51
+ <ToolbarItem>
52
+ <Button aria-expanded={isExpanded} onClick={onClick}>
53
+ Toggle drawer
54
+ </Button>
55
+ </ToolbarItem>
56
+ </ToolbarContent>
57
+ </Toolbar>
58
+ );
59
+
60
+ const masthead = (
61
+ <Masthead>
62
+ <MastheadMain>
63
+ <MastheadToggle>
64
+ <PageToggleButton isHamburgerButton aria-label="Global navigation" id="viewport-drawer-nav-toggle" />
65
+ </MastheadToggle>
66
+ <MastheadBrand>
67
+ <MastheadLogo href="https://patternfly.org" target="_blank">
68
+ Logo
69
+ </MastheadLogo>
70
+ </MastheadBrand>
71
+ </MastheadMain>
72
+ <MastheadContent>{headerToolbar}</MastheadContent>
73
+ </Masthead>
74
+ );
75
+
76
+ const sidebar = (
77
+ <PageSidebar id="viewport-drawer-sidebar">
78
+ <PageSidebarBody>Navigation</PageSidebarBody>
79
+ </PageSidebar>
80
+ );
81
+
82
+ const panelContent = (
83
+ <DrawerPanelContent isResizable onResize={onResize} id="viewport-resize-panel" minSize="150px">
84
+ <DrawerHead>
85
+ <span tabIndex={isExpanded ? 0 : -1} ref={drawerRef}>
86
+ Drawer panel header
87
+ </span>
88
+ <DrawerActions>
89
+ <DrawerCloseButton onClick={onCloseClick} />
90
+ </DrawerActions>
91
+ </DrawerHead>
92
+ </DrawerPanelContent>
93
+ );
94
+
95
+ return (
96
+ <Fragment>
97
+ <Page isManagedSidebar masthead={masthead} sidebar={sidebar}>
98
+ <PageSection aria-labelledby="viewport-drawer-section">
99
+ <h2 id="viewport-drawer-section">Viewport drawer example</h2>
100
+ <p>
101
+ The viewport drawer is a sibling of Page. DrawerContent is left empty so the panel overlays the page without
102
+ affecting page layout or scrolling.
103
+ </p>
104
+ </PageSection>
105
+ </Page>
106
+ {isExpanded && <Backdrop onClick={onCloseClick}></Backdrop>}
107
+ <Drawer isExpanded={isExpanded} isViewport onExpand={onExpand}>
108
+ <DrawerContent panelContent={panelContent} />
109
+ </Drawer>
110
+ </Fragment>
111
+ );
112
+ };
package/src/demos/Page.md CHANGED
@@ -4,18 +4,25 @@ section: components
4
4
  ---
5
5
 
6
6
  import { useState, useRef, useEffect } from 'react';
7
- import RhUiNotificationFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-notification-fill-icon';
8
- import RhUiSettingsFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-settings-fill-icon';
9
- import RhUiQuestionMarkCircleIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-question-mark-circle-icon';
10
- import RhUiQuestionMarkCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-question-mark-circle-fill-icon';
11
- import imgAvatar from '@patternfly/react-core/src/components/assets/avatarImg.svg';
12
- import RhUiMenuBarsIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-menu-bars-icon';
13
- import LightbulbIcon from '@patternfly/react-icons/dist/esm/icons/lightbulb-icon';
14
7
  import RhUiEllipsisVerticalFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-ellipsis-vertical-fill-icon';
15
- import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon';
16
- import RhUiCloudFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-cloud-fill-icon';
17
- import pfLogo from '@patternfly/react-core/src/demos/assets/PF-HorizontalLogo-Color.svg';
18
- import pfIconLogo from '@patternfly/react-core/src/demos/assets/PF-IconLogo-color.svg';
8
+ import RhUiAddCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-add-circle-fill-icon';
9
+ import RhUiTrashFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-trash-fill-icon';
10
+ import RhUiPortIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-port-icon';
11
+ import RhUiContainerIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-container-icon';
12
+ import RhUiAutomationIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-automation-icon';
13
+ import RhUiConnectedIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-connected-icon';
14
+ import RhUiArrowRightIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-arrow-right-icon';
15
+ import pfIcon from '@patternfly/react-core/src/demos/assets/PF-IconLogo.svg';
16
+ import activeMQIcon from '@patternfly/react-core/src/demos/assets/activemq-core_200x150.png';
17
+ import avroIcon from '@patternfly/react-core/src/demos/assets/camel-avro_200x150.png';
18
+ import dropBoxIcon from '@patternfly/react-core/src/demos/assets/camel-dropbox_200x150.png';
19
+ import infinispanIcon from '@patternfly/react-core/src/demos/assets/camel-infinispan_200x150.png';
20
+ import saxonIcon from '@patternfly/react-core/src/demos/assets/camel-saxon_200x150.png';
21
+ import sparkIcon from '@patternfly/react-core/src/demos/assets/camel-spark_200x150.png';
22
+ import swaggerIcon from '@patternfly/react-core/src/demos/assets/camel-swagger-java_200x150.png';
23
+ import azureIcon from '@patternfly/react-core/src/demos/assets/FuseConnector_Icons_AzureServices.png';
24
+ import restIcon from '@patternfly/react-core/src/demos/assets/FuseConnector_Icons_REST.png';
25
+ import { data } from '@patternfly/react-core/src/demos/CardView/examples/CardViewData.jsx';
19
26
 
20
27
  - All examples set the `isManagedSidebar` prop on the Page component to have the sidebar automatically close for smaller screen widths. You can also manually control this behavior by not adding the `isManagedSidebar` prop and instead:
21
28
  1. Add an onNavToggle callback to PageHeader
@@ -50,3 +57,9 @@ When adding a context selector/perspective switcher in a `PageSidebar`, you must
50
57
  ```ts file='./examples/Page/PageContextSelector.tsx' isFullscreen
51
58
 
52
59
  ```
60
+
61
+ ### Plain
62
+
63
+ ```ts file='./examples/Page/PagePlain.tsx' isFullscreen
64
+
65
+ ```