diff --git a/packages/react-core/package.json b/packages/react-core/package.json index 656a87c6ec3..cd0a8749ae0 100644 --- a/packages/react-core/package.json +++ b/packages/react-core/package.json @@ -54,7 +54,7 @@ "tslib": "^2.8.1" }, "devDependencies": { - "@patternfly/patternfly": "6.6.0-prerelease.20", + "@patternfly/patternfly": "6.6.0-prerelease.39", "case-anything": "^3.1.2", "css": "^3.0.0", "fs-extra": "^11.3.3" diff --git a/packages/react-core/src/components/Page/Page.tsx b/packages/react-core/src/components/Page/Page.tsx index 034c72f9787..595ac6a5c07 100644 --- a/packages/react-core/src/components/Page/Page.tsx +++ b/packages/react-core/src/components/Page/Page.tsx @@ -28,7 +28,10 @@ export interface PageProps extends React.HTMLProps { * will handle toggling the visibility of the text in individual isDocked components. */ isDockTextExpanded?: boolean; - /** The horizontal masthead content (e.g. ). When using the docked variant, this content will only render at mobile viewports. */ + /** The horizontal masthead content (e.g. or ). PageHeader is an alternative to Masthead + * and should only be used to wrap custom header content. When using the docked variant, this content will only render at + * mobile viewports. + */ masthead?: React.ReactNode; /** @beta Content to render in the vertical dock when variant of docked is used. At mobile viewports, this content will be replaced with the content passed to masthead. */ dockContent?: React.ReactNode; diff --git a/packages/react-core/src/components/Page/PageHeader.tsx b/packages/react-core/src/components/Page/PageHeader.tsx new file mode 100644 index 00000000000..e2a5df417c1 --- /dev/null +++ b/packages/react-core/src/components/Page/PageHeader.tsx @@ -0,0 +1,28 @@ +import styles from '@patternfly/react-styles/css/components/Page/page'; +import { css } from '@patternfly/react-styles'; + +export interface PageHeaderProps extends React.HTMLProps { + /** Content rendered inside the page header. This should be custom header content, rather than the PatternFly Masthead. */ + children?: React.ReactNode; + /** Additional classes added to the page header */ + className?: string; + /** Sets the base component to render. Defaults to header */ + component?: keyof React.JSX.IntrinsicElements; +} + +export const PageHeader: React.FunctionComponent = ({ + className, + children, + component = 'header', + ...props +}: PageHeaderProps) => { + const Component = component as any; + + return ( + + {children} + + ); +}; + +PageHeader.displayName = 'PageHeader'; diff --git a/packages/react-core/src/components/Page/__tests__/Page.test.tsx b/packages/react-core/src/components/Page/__tests__/Page.test.tsx index c97e699685c..bb76d3408dc 100644 --- a/packages/react-core/src/components/Page/__tests__/Page.test.tsx +++ b/packages/react-core/src/components/Page/__tests__/Page.test.tsx @@ -9,6 +9,7 @@ import { Nav, NavList, NavItem } from '../../Nav'; import { SkipToContent } from '../../SkipToContent'; import { PageBreadcrumb } from '../PageBreadcrumb'; import { PageGroup } from '../PageGroup'; +import { PageHeader } from '../PageHeader'; import { Masthead } from '../../Masthead'; import styles from '@patternfly/react-styles/css/components/Page/page'; @@ -487,4 +488,16 @@ describe('Page docked variant', () => { const pageDockMain = screen.getByText('Dock content').closest(`.${styles.pageDockMain}`); expect(pageDockMain).toBeInTheDocument(); }); + + test('Renders PageHeader when passed to the masthead prop', () => { + render( + Custom header}> + Custom content + + ); + + const header = screen.getByText('Custom header'); + expect(header).toHaveClass(styles.pageHeader); + expect(header.parentElement).toHaveClass(styles.page); + }); }); diff --git a/packages/react-core/src/components/Page/__tests__/PageHeader.test.tsx b/packages/react-core/src/components/Page/__tests__/PageHeader.test.tsx new file mode 100644 index 00000000000..80dd18483c3 --- /dev/null +++ b/packages/react-core/src/components/Page/__tests__/PageHeader.test.tsx @@ -0,0 +1,33 @@ +import { render, screen } from '@testing-library/react'; +import styles from '@patternfly/react-styles/css/components/Page/page'; +import { PageHeader } from '../PageHeader'; + +test('Renders children', () => { + render(Header content); + expect(screen.getByText('Header content')).toBeVisible(); +}); + +test(`Renders with class ${styles.pageHeader} by default`, () => { + render(Header content); + expect(screen.getByText('Header content')).toHaveClass(styles.pageHeader, { exact: true }); +}); + +test('Renders as a div by default', () => { + render(Header content); + expect(screen.getByText('Header content').tagName).toBe('HEADER'); +}); + +test('Renders as a custom component when component is passed', () => { + render(Header content); + expect(screen.getByText('Header content').tagName).toBe('DIV'); +}); + +test('Renders with custom classes when className is passed', () => { + render(Header content); + expect(screen.getByText('Header content')).toHaveClass('custom-class'); +}); + +test('Renders with spread props', () => { + render(Header content); + expect(screen.getByText('Header content')).toHaveAttribute('id', 'custom-id'); +}); diff --git a/packages/react-core/src/components/Page/examples/Page.md b/packages/react-core/src/components/Page/examples/Page.md index 5f4d491e7a2..943ea3acd73 100644 --- a/packages/react-core/src/components/Page/examples/Page.md +++ b/packages/react-core/src/components/Page/examples/Page.md @@ -3,7 +3,16 @@ id: Page section: components cssPrefix: pf-v6-c-page propComponents: - ['Page', 'PageSidebar', 'PageSidebarBody', 'PageSection', 'PageGroup', 'PageBreadcrumb', 'PageToggleButton'] + [ + 'Page', + 'PageHeader', + 'PageSidebar', + 'PageSidebarBody', + 'PageSection', + 'PageGroup', + 'PageBreadcrumb', + 'PageToggleButton' + ] --- import { useState, useLayoutEffect, useRef } from 'react'; @@ -16,7 +25,7 @@ import pageSectionWidthLimitMaxWidth from '@patternfly/react-tokens/dist/esm/c_p A page will typically contain the following components: -- A `` with a `masthead` prop that often contains a [masthead](/components/masthead) component +- A `` with a `masthead` prop that often contains a [masthead](/components/masthead) or a `` The `` component includes the smaller area that typically contains the `` and a ``. `` represents the main portion of the masthead, and will typically contain a `` or other menu-like components, like a ``. @@ -24,6 +33,14 @@ 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 + +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 file="./PageHeaderContent.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 ``. diff --git a/packages/react-core/src/components/Page/examples/PageHeaderContent.tsx b/packages/react-core/src/components/Page/examples/PageHeaderContent.tsx new file mode 100644 index 00000000000..27b0be187dd --- /dev/null +++ b/packages/react-core/src/components/Page/examples/PageHeaderContent.tsx @@ -0,0 +1,19 @@ +import { Page, PageHeader, PageSection } from '@patternfly/react-core'; + +export const PageHeaderContent: React.FunctionComponent = () => { + const pageHeader = Page header; + + 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/index.ts b/packages/react-core/src/components/Page/index.ts index 5afe6f03b36..55f94c2bffe 100644 --- a/packages/react-core/src/components/Page/index.ts +++ b/packages/react-core/src/components/Page/index.ts @@ -2,6 +2,7 @@ export * from './Page'; export * from './PageBody'; export * from './PageBreadcrumb'; export * from './PageGroup'; +export * from './PageHeader'; export * from './PageSidebar'; export * from './PageSidebarBody'; export * from './PageSection'; diff --git a/packages/react-docs/package.json b/packages/react-docs/package.json index 5523c77d741..7f367583d8f 100644 --- a/packages/react-docs/package.json +++ b/packages/react-docs/package.json @@ -23,7 +23,7 @@ "test:a11y": "patternfly-a11y --config patternfly-a11y.config" }, "dependencies": { - "@patternfly/patternfly": "6.6.0-prerelease.20", + "@patternfly/patternfly": "6.6.0-prerelease.39", "@patternfly/react-charts": "workspace:^", "@patternfly/react-code-editor": "workspace:^", "@patternfly/react-core": "workspace:^", diff --git a/packages/react-icons/package.json b/packages/react-icons/package.json index 297ec4b959c..018c9991ee5 100644 --- a/packages/react-icons/package.json +++ b/packages/react-icons/package.json @@ -38,7 +38,7 @@ "@fortawesome/free-brands-svg-icons": "^5.15.4", "@fortawesome/free-regular-svg-icons": "^5.15.4", "@fortawesome/free-solid-svg-icons": "^5.15.4", - "@patternfly/patternfly": "6.6.0-prerelease.20", + "@patternfly/patternfly": "6.6.0-prerelease.39", "@rhds/icons": "^2.2.0", "fs-extra": "^11.3.3" }, diff --git a/packages/react-styles/package.json b/packages/react-styles/package.json index 8dd1cf585e2..7c2b0a5fb71 100644 --- a/packages/react-styles/package.json +++ b/packages/react-styles/package.json @@ -19,7 +19,7 @@ "clean": "rimraf dist css" }, "devDependencies": { - "@patternfly/patternfly": "6.6.0-prerelease.20", + "@patternfly/patternfly": "6.6.0-prerelease.39", "change-case": "^5.4.4", "fs-extra": "^11.3.3" }, diff --git a/packages/react-tokens/package.json b/packages/react-tokens/package.json index e1794978b7a..9d873fe7e60 100644 --- a/packages/react-tokens/package.json +++ b/packages/react-tokens/package.json @@ -30,7 +30,7 @@ }, "devDependencies": { "@adobe/css-tools": "^4.4.4", - "@patternfly/patternfly": "6.6.0-prerelease.20", + "@patternfly/patternfly": "6.6.0-prerelease.39", "fs-extra": "^11.3.3" } } diff --git a/yarn.lock b/yarn.lock index 224de12951b..35bef1a5ca6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5070,10 +5070,10 @@ __metadata: languageName: node linkType: hard -"@patternfly/patternfly@npm:6.6.0-prerelease.20": - version: 6.6.0-prerelease.20 - resolution: "@patternfly/patternfly@npm:6.6.0-prerelease.20" - checksum: 10c0/6bcc0015bb994ff29b6bdb66b7b83e8e91d8ea94278264c985bf40326b084c6c44606e4224f348e646d0e20b9545c4ffa4de6a1d33f697bf5f6f76fa74202951 +"@patternfly/patternfly@npm:6.6.0-prerelease.39": + version: 6.6.0-prerelease.39 + resolution: "@patternfly/patternfly@npm:6.6.0-prerelease.39" + checksum: 10c0/e3ad085429507c23912bf50b84a178c9b2f05fe58dbbecce9eb76be9f70eb4b116e81a611f5eaa8dc388d4081ae5f36ab09725268041e5557a85c20cb07200c3 languageName: node linkType: hard @@ -5171,7 +5171,7 @@ __metadata: version: 0.0.0-use.local resolution: "@patternfly/react-core@workspace:packages/react-core" dependencies: - "@patternfly/patternfly": "npm:6.6.0-prerelease.20" + "@patternfly/patternfly": "npm:6.6.0-prerelease.39" "@patternfly/react-icons": "workspace:^" "@patternfly/react-styles": "workspace:^" "@patternfly/react-tokens": "workspace:^" @@ -5192,7 +5192,7 @@ __metadata: resolution: "@patternfly/react-docs@workspace:packages/react-docs" dependencies: "@patternfly/documentation-framework": "npm:^6.40.0" - "@patternfly/patternfly": "npm:6.6.0-prerelease.20" + "@patternfly/patternfly": "npm:6.6.0-prerelease.39" "@patternfly/patternfly-a11y": "npm:5.2.1" "@patternfly/react-charts": "workspace:^" "@patternfly/react-code-editor": "workspace:^" @@ -5232,7 +5232,7 @@ __metadata: "@fortawesome/free-brands-svg-icons": "npm:^5.15.4" "@fortawesome/free-regular-svg-icons": "npm:^5.15.4" "@fortawesome/free-solid-svg-icons": "npm:^5.15.4" - "@patternfly/patternfly": "npm:6.6.0-prerelease.20" + "@patternfly/patternfly": "npm:6.6.0-prerelease.39" "@rhds/icons": "npm:^2.2.0" fs-extra: "npm:^11.3.3" tslib: "npm:^2.8.1" @@ -5319,7 +5319,7 @@ __metadata: version: 0.0.0-use.local resolution: "@patternfly/react-styles@workspace:packages/react-styles" dependencies: - "@patternfly/patternfly": "npm:6.6.0-prerelease.20" + "@patternfly/patternfly": "npm:6.6.0-prerelease.39" change-case: "npm:^5.4.4" fs-extra: "npm:^11.3.3" languageName: unknown @@ -5361,7 +5361,7 @@ __metadata: resolution: "@patternfly/react-tokens@workspace:packages/react-tokens" dependencies: "@adobe/css-tools": "npm:^4.4.4" - "@patternfly/patternfly": "npm:6.6.0-prerelease.20" + "@patternfly/patternfly": "npm:6.6.0-prerelease.39" fs-extra: "npm:^11.3.3" languageName: unknown linkType: soft