From b6a63ef3fc1956f4bff5312f54475cb8327ef486 Mon Sep 17 00:00:00 2001 From: Rebecca Alpert Date: Thu, 10 Sep 2026 20:23:07 -0400 Subject: [PATCH 1/2] chore(Page): Header, footer, and plain docs should match Core Assisted-by: Cursor --- .../src/components/Page/examples/Page.md | 36 +- .../Page/examples/PageCustomFooter.tsx | 59 +++ .../Page/examples/PageCustomHeader.tsx | 17 + .../examples/PageHeaderAndFooterContent.tsx | 20 - .../components/Page/examples/PagePlain.tsx | 58 +++ .../react-core/src/demos/CardView/CardView.md | 2 +- .../src/demos/CardView/examples/CardView.tsx | 2 +- packages/react-core/src/demos/Page.md | 27 +- .../src/demos/examples/Page/PagePlain.tsx | 402 ++++++++++++++++++ .../PageStickySectionGroupUsingPageHeader.tsx | 0 10 files changed, 587 insertions(+), 36 deletions(-) create mode 100644 packages/react-core/src/components/Page/examples/PageCustomFooter.tsx create mode 100644 packages/react-core/src/components/Page/examples/PageCustomHeader.tsx delete mode 100644 packages/react-core/src/components/Page/examples/PageHeaderAndFooterContent.tsx create mode 100644 packages/react-core/src/components/Page/examples/PagePlain.tsx create mode 100644 packages/react-core/src/demos/examples/Page/PagePlain.tsx delete mode 100644 packages/react-core/src/demos/examples/Page/PageStickySectionGroupUsingPageHeader.tsx diff --git a/packages/react-core/src/components/Page/examples/Page.md b/packages/react-core/src/components/Page/examples/Page.md index 280e5ec2e48..44dbce566f4 100644 --- a/packages/react-core/src/components/Page/examples/Page.md +++ b/packages/react-core/src/components/Page/examples/Page.md @@ -33,18 +33,6 @@ The `` component includes the smaller area that typically contains - 1 or more `` components inside `` for vertical navigation or other sidebar content - 1 or more `` components -### Page header and footer - -To use a page header instead of passing a [masthead](/components/masthead) directly, pass a `` to the `masthead` property. `` should only be used to wrap custom header content. - -`` can be passed to the `footer` property, and should be used to wrap custom footer content. - -When using a custom `` and ``, the `isPlain` flag should be passed to ``. 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. - -```ts file="./PageHeaderAndFooterContent.tsx" - -``` - ### Vertical navigation To add a vertical sidebar to a ``, pass a `` component into the `sidebar` property. To render navigation in the sidebar, pass a `` component to ``. @@ -162,3 +150,27 @@ In this example, a scroll event listener on the scroll parent container toggles ```ts file="./PageDynamicStickySection.tsx" ``` + +### Custom header + +To use a page header instead of passing a [masthead](/components/masthead) directly, pass a `` to the `masthead` property. `` should only be used to wrap custom header content. + +```ts isBeta file="./PageCustomHeader.tsx" + +``` + +### Footer + +`` can be passed to the `footer` property, and should be used to wrap custom footer content. + +```ts isBeta file="./PageCustomFooter.tsx" + +``` + +### Plain page + +When a page should not have the default content area background or overflow scrolling, pass the `isPlain` property to ``. + +```ts isBeta file="./PagePlain.tsx" + +``` diff --git a/packages/react-core/src/components/Page/examples/PageCustomFooter.tsx b/packages/react-core/src/components/Page/examples/PageCustomFooter.tsx new file mode 100644 index 00000000000..fa5cafc6f84 --- /dev/null +++ b/packages/react-core/src/components/Page/examples/PageCustomFooter.tsx @@ -0,0 +1,59 @@ +import { useState } from 'react'; +import { + Masthead, + MastheadMain, + MastheadToggle, + MastheadBrand, + MastheadLogo, + MastheadContent, + Page, + PageFooter, + PageSection, + PageSidebar, + PageSidebarBody, + PageToggleButton +} from '@patternfly/react-core'; + +export const PageCustomFooter: React.FunctionComponent = () => { + const [isSidebarOpen, setIsSidebarOpen] = useState(true); + + const onSidebarToggle = () => { + setIsSidebarOpen(!isSidebarOpen); + }; + + const masthead = ( + + + + + + + + Logo + + + + Content + + ); + + const sidebar = ( + + Navigation + + ); + + return ( + Page footer} masthead={masthead} sidebar={sidebar}> + + + + + ); +}; diff --git a/packages/react-core/src/components/Page/examples/PageCustomHeader.tsx b/packages/react-core/src/components/Page/examples/PageCustomHeader.tsx new file mode 100644 index 00000000000..b65d56a58b1 --- /dev/null +++ b/packages/react-core/src/components/Page/examples/PageCustomHeader.tsx @@ -0,0 +1,17 @@ +import { Page, PageHeader, PageSection, PageSidebar, PageSidebarBody } from '@patternfly/react-core'; + +export const PageCustomHeader: React.FunctionComponent = () => { + const sidebar = ( + + Navigation + + ); + + return ( + Custom page header} sidebar={sidebar}> + +

Page content

+
+ + ); +}; diff --git a/packages/react-core/src/components/Page/examples/PageHeaderAndFooterContent.tsx b/packages/react-core/src/components/Page/examples/PageHeaderAndFooterContent.tsx deleted file mode 100644 index 3dd2160b419..00000000000 --- a/packages/react-core/src/components/Page/examples/PageHeaderAndFooterContent.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { Page, PageHeader, PageFooter, PageSection } from '@patternfly/react-core'; - -export const PageHeaderAndFooterContent: React.FunctionComponent = () => { - const pageHeader = Page header; - const pageFooter = Page footer; - - return ( - - -

Page header example section 1

-
- -

Page header example section 2 with secondary variant styling

-
- -

Page header example section 3

-
-
- ); -}; diff --git a/packages/react-core/src/components/Page/examples/PagePlain.tsx b/packages/react-core/src/components/Page/examples/PagePlain.tsx new file mode 100644 index 00000000000..2b51227ce8e --- /dev/null +++ b/packages/react-core/src/components/Page/examples/PagePlain.tsx @@ -0,0 +1,58 @@ +import { useState } from 'react'; +import { + Masthead, + MastheadMain, + MastheadToggle, + MastheadBrand, + MastheadLogo, + MastheadContent, + Page, + PageSection, + PageSidebar, + PageSidebarBody, + PageToggleButton +} from '@patternfly/react-core'; + +export const PagePlain: React.FunctionComponent = () => { + const [isSidebarOpen, setIsSidebarOpen] = useState(true); + + const onSidebarToggle = () => { + setIsSidebarOpen(!isSidebarOpen); + }; + + const masthead = ( + + + + + + + + Logo + + + + Content + + ); + + const sidebar = ( + + Navigation + + ); + + return ( + + +

Page content

+
+
+ ); +}; diff --git a/packages/react-core/src/demos/CardView/CardView.md b/packages/react-core/src/demos/CardView/CardView.md index 58eeb5eb539..9dfa99173f8 100644 --- a/packages/react-core/src/demos/CardView/CardView.md +++ b/packages/react-core/src/demos/CardView/CardView.md @@ -6,7 +6,7 @@ section: patterns import { Fragment, useState } from 'react'; import RhUiTrashFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-trash-fill-icon'; import RhUiAddCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-add-circle-fill-icon'; -import pfIcon from '../assets/pf-logo-small.svg'; +import pfIcon from '@patternfly/react-core/src/demos/assets/PF-IconLogo.svg'; import activeMQIcon from '../assets/activemq-core_200x150.png'; import avroIcon from '../assets/camel-avro_200x150.png'; import dropBoxIcon from '../assets/camel-dropbox_200x150.png'; diff --git a/packages/react-core/src/demos/CardView/examples/CardView.tsx b/packages/react-core/src/demos/CardView/examples/CardView.tsx index 86e499e96c5..92f4508d016 100644 --- a/packages/react-core/src/demos/CardView/examples/CardView.tsx +++ b/packages/react-core/src/demos/CardView/examples/CardView.tsx @@ -36,7 +36,7 @@ import { } from '@patternfly/react-core'; import RhUiTrashFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-trash-fill-icon'; import RhUiAddCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-add-circle-fill-icon'; -import pfIcon from './assets/pf-logo-small.svg'; +import pfIcon from '@patternfly/react-core/src/demos/assets/PF-IconLogo.svg'; import activeMQIcon from './assets/activemq-core_200x150.png'; import avroIcon from './assets/camel-avro_200x150.png'; import dropBoxIcon from './assets/camel-dropbox_200x150.png'; diff --git a/packages/react-core/src/demos/Page.md b/packages/react-core/src/demos/Page.md index 9e58569df3b..1dabd29153d 100644 --- a/packages/react-core/src/demos/Page.md +++ b/packages/react-core/src/demos/Page.md @@ -12,10 +12,27 @@ import imgAvatar from '@patternfly/react-core/src/components/assets/avatarImg.sv import RhUiMenuBarsIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-menu-bars-icon'; import LightbulbIcon from '@patternfly/react-icons/dist/esm/icons/lightbulb-icon'; import RhUiEllipsisVerticalFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-ellipsis-vertical-fill-icon'; -import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon'; +import RhUiContainerIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-container-icon'; import RhUiCloudFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-cloud-fill-icon'; +import RhUiPortIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-port-icon'; +import RhUiAutomationIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-automation-icon'; +import RhUiConnectedIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-connected-icon'; +import RhUiArrowRightIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-arrow-right-icon'; +import RhUiAddCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-add-circle-fill-icon'; +import RhUiTrashFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-trash-fill-icon'; +import RhUiThumbnailViewSmallFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-thumbnail-view-small-fill-icon'; import pfLogo from '@patternfly/react-core/src/demos/assets/PF-HorizontalLogo-Color.svg'; -import pfIconLogo from '@patternfly/react-core/src/demos/assets/PF-IconLogo-color.svg'; +import pfIcon from '@patternfly/react-core/src/demos/assets/PF-IconLogo.svg'; +import activeMQIcon from '@patternfly/react-core/src/demos/assets/activemq-core_200x150.png'; +import avroIcon from '@patternfly/react-core/src/demos/assets/camel-avro_200x150.png'; +import dropBoxIcon from '@patternfly/react-core/src/demos/assets/camel-dropbox_200x150.png'; +import infinispanIcon from '@patternfly/react-core/src/demos/assets/camel-infinispan_200x150.png'; +import saxonIcon from '@patternfly/react-core/src/demos/assets/camel-saxon_200x150.png'; +import sparkIcon from '@patternfly/react-core/src/demos/assets/camel-spark_200x150.png'; +import swaggerIcon from '@patternfly/react-core/src/demos/assets/camel-swagger-java_200x150.png'; +import azureIcon from '@patternfly/react-core/src/demos/assets/FuseConnector_Icons_AzureServices.png'; +import restIcon from '@patternfly/react-core/src/demos/assets/FuseConnector_Icons_REST.png'; +import { data } from '@patternfly/react-core/src/demos/CardView/examples/CardViewData.jsx'; - 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: 1. Add an onNavToggle callback to PageHeader @@ -50,3 +67,9 @@ When adding a context selector/perspective switcher in a `PageSidebar`, you must ```ts file='./examples/Page/PageContextSelector.tsx' isFullscreen ``` + +### Plain + +```ts file='./examples/Page/PagePlain.tsx' isFullscreen + +``` diff --git a/packages/react-core/src/demos/examples/Page/PagePlain.tsx b/packages/react-core/src/demos/examples/Page/PagePlain.tsx new file mode 100644 index 00000000000..8c3ff2cfffd --- /dev/null +++ b/packages/react-core/src/demos/examples/Page/PagePlain.tsx @@ -0,0 +1,402 @@ +import { useState } from 'react'; +import { + Brand, + Bullseye, + Button, + ButtonVariant, + Card, + CardBody, + CardExpandableContent, + CardFooter, + CardHeader, + CardTitle, + Content, + Divider, + Dropdown, + DropdownItem, + DropdownList, + EmptyState, + EmptyStateActions, + EmptyStateFooter, + EmptyStateVariant, + Flex, + FlexItem, + Gallery, + GalleryItem, + Icon, + Label, + LabelColor, + LabelGroup, + LabelStatus, + Masthead, + MastheadBrand, + MastheadContent, + MastheadLogo, + MastheadMain, + MastheadToggle, + MenuToggle, + MenuToggleElement, + Page, + PageBody, + PageFooter, + PageSection, + PageToggleButton, + Panel, + PanelMain, + PanelMainBody, + SkipToContent, + Title, + Toolbar, + ToolbarContent, + ToolbarGroup, + ToolbarItem +} from '@patternfly/react-core'; +import RhUiEllipsisVerticalFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-ellipsis-vertical-fill-icon'; +import RhUiQuestionMarkCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-question-mark-circle-fill-icon'; +import RhUiAddCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-add-circle-fill-icon'; +import RhUiTrashFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-trash-fill-icon'; +import RhUiThumbnailViewSmallFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-thumbnail-view-small-fill-icon'; +import RhUiPortIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-port-icon'; +import RhUiContainerIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-container-icon'; +import RhUiAutomationIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-automation-icon'; +import RhUiConnectedIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-connected-icon'; +import RhUiArrowRightIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-arrow-right-icon'; +import pfLogo from '@patternfly/react-core/src/demos/assets/PF-HorizontalLogo-Color.svg'; +import pfIcon from '@patternfly/react-core/src/demos/assets/PF-IconLogo.svg'; +import activeMQIcon from '@patternfly/react-core/src/demos/assets/activemq-core_200x150.png'; +import avroIcon from '@patternfly/react-core/src/demos/assets/camel-avro_200x150.png'; +import dropBoxIcon from '@patternfly/react-core/src/demos/assets/camel-dropbox_200x150.png'; +import infinispanIcon from '@patternfly/react-core/src/demos/assets/camel-infinispan_200x150.png'; +import saxonIcon from '@patternfly/react-core/src/demos/assets/camel-saxon_200x150.png'; +import sparkIcon from '@patternfly/react-core/src/demos/assets/camel-spark_200x150.png'; +import swaggerIcon from '@patternfly/react-core/src/demos/assets/camel-swagger-java_200x150.png'; +import azureIcon from '@patternfly/react-core/src/demos/assets/FuseConnector_Icons_AzureServices.png'; +import restIcon from '@patternfly/react-core/src/demos/assets/FuseConnector_Icons_REST.png'; +import { data } from '@patternfly/react-core/src/demos/CardView/examples/CardViewData.jsx'; + +export const PagePlain: React.FunctionComponent = () => { + const [isToolbarMenuOpen, setIsToolbarMenuOpen] = useState(false); + const [isPathwayExpanded, setIsPathwayExpanded] = useState(true); + const [isPathwayKebabOpen, setIsPathwayKebabOpen] = useState(false); + const [selectedItems, setSelectedItems] = useState([]); + const [openCardMenu, setOpenCardMenu] = useState(null); + const mainContainerId = 'main-content-page-demo-plain'; + + const toolbar = ( + + + + + + + + +

{description}

+
+ + {hasIncident && ( + + + + )} + + + + +

+ System reboot {rebootRequired ? 'is' : 'is not'} required +

+
+
+ + + + + + + + ); + + const recommendedPathwaysCard = ( + + setIsPathwayExpanded(!isPathwayExpanded)} + toggleButtonProps={{ + id: 'page-demo-plain-expandable-status-card-1-toggle', + 'aria-label': 'Details', + 'aria-labelledby': + 'page-demo-plain-expandable-status-card-1-title page-demo-plain-expandable-status-card-1-toggle', + 'aria-expanded': isPathwayExpanded + }} + actions={{ + actions: ( + setIsPathwayKebabOpen(isOpen)} + toggle={(toggleRef: React.Ref) => ( + setIsPathwayKebabOpen(!isPathwayKebabOpen)} + isExpanded={isPathwayKebabOpen} + icon={} + /> + )} + > + + setIsPathwayKebabOpen(false)}>Action + + + ) + }} + > + + + Improve recommended pathways + + + + + + {renderPathwayCard( + + + , + 378, + 'Upgrade your kernel version to remediate ntpd time sync issues, kernel panics, network instabilities and issues with system performance', + true, + true + )} + + {renderPathwayCard( + + + + , + 211, + 'Adjust your networking configuration to get ahead of network performance degradations and packet losses', + false, + false + )} + + {renderPathwayCard( + + + , + 166, + 'Fine tune your Oracle DB configuration to improve database performance and avoid process failure', + true, + true + )} + + + + ); + + return ( + Skip to content} + mainContainerId={mainContainerId} + > + + + + + +

Page title

+

This is a full page demo.

+
+
+
+
+
+ + {recommendedPathwaysCard} + + + + + + + + + + + + + + + {cards} + + + + custom footer + +
+ ); +}; diff --git a/packages/react-core/src/demos/examples/Page/PageStickySectionGroupUsingPageHeader.tsx b/packages/react-core/src/demos/examples/Page/PageStickySectionGroupUsingPageHeader.tsx deleted file mode 100644 index e69de29bb2d..00000000000 From bb914b53e21821204e7b7edcd960a69524fda8ae Mon Sep 17 00:00:00 2001 From: Rebecca Alpert Date: Thu, 10 Sep 2026 22:05:42 -0400 Subject: [PATCH 2/2] Fix CodeRabbit review issues --- .../components/Page/examples/PagePlain.tsx | 2 +- .../src/demos/examples/Page/PagePlain.tsx | 68 +++++++++++++++---- 2 files changed, 57 insertions(+), 13 deletions(-) diff --git a/packages/react-core/src/components/Page/examples/PagePlain.tsx b/packages/react-core/src/components/Page/examples/PagePlain.tsx index 2b51227ce8e..a052d8501e3 100644 --- a/packages/react-core/src/components/Page/examples/PagePlain.tsx +++ b/packages/react-core/src/components/Page/examples/PagePlain.tsx @@ -51,7 +51,7 @@ export const PagePlain: React.FunctionComponent = () => { return ( -

Page content

+

Page content

); diff --git a/packages/react-core/src/demos/examples/Page/PagePlain.tsx b/packages/react-core/src/demos/examples/Page/PagePlain.tsx index 8c3ff2cfffd..eb1b09ddca3 100644 --- a/packages/react-core/src/demos/examples/Page/PagePlain.tsx +++ b/packages/react-core/src/demos/examples/Page/PagePlain.tsx @@ -53,6 +53,7 @@ import { } from '@patternfly/react-core'; import RhUiEllipsisVerticalFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-ellipsis-vertical-fill-icon'; import RhUiQuestionMarkCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-question-mark-circle-fill-icon'; +import RhUiSettingsFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-settings-fill-icon'; import RhUiAddCircleFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-add-circle-fill-icon'; import RhUiTrashFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-trash-fill-icon'; import RhUiThumbnailViewSmallFillIcon from '@patternfly/react-icons/dist/esm/icons/rh-ui-thumbnail-view-small-fill-icon'; @@ -82,6 +83,18 @@ export const PagePlain: React.FunctionComponent = () => { const [openCardMenu, setOpenCardMenu] = useState(null); const mainContainerId = 'main-content-page-demo-plain'; + const onApplicationLauncher = () => { + setIsToolbarMenuOpen(false); + }; + + const onSettings = () => { + setIsToolbarMenuOpen(false); + }; + + const onHelp = () => { + setIsToolbarMenuOpen(false); + }; + const toolbar = ( @@ -96,23 +109,50 @@ export const PagePlain: React.FunctionComponent = () => { aria-label="Application launcher" variant={ButtonVariant.plain} icon={} + onClick={onApplicationLauncher} />
-