Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Masthead): Updates for new masthead structure in Penta #10809

Merged
merged 7 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/react-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"tslib": "^2.6.2"
},
"devDependencies": {
"@patternfly/patternfly": "6.0.0-alpha.201",
"@patternfly/patternfly": "6.0.0-alpha.203",
"case-anything": "^2.1.13",
"css": "^3.0.0",
"fs-extra": "^11.2.0"
Expand Down
26 changes: 6 additions & 20 deletions packages/react-core/src/components/Masthead/MastheadBrand.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,20 @@ import * as React from 'react';
import styles from '@patternfly/react-styles/css/components/Masthead/masthead';
import { css } from '@patternfly/react-styles';

export interface MastheadBrandProps
extends React.DetailedHTMLProps<React.HTMLProps<HTMLAnchorElement>, HTMLAnchorElement> {
export interface MastheadBrandProps extends React.DetailedHTMLProps<React.HTMLProps<HTMLDivElement>, HTMLDivElement> {
/** Content rendered inside of the masthead brand. */
children?: React.ReactNode;
/** Additional classes added to the masthead brand. */
className?: string;
/** Component type of the masthead brand. */
component?: React.ElementType<any> | React.ComponentType<any>;
}

export const MastheadBrand: React.FunctionComponent<MastheadBrandProps> = ({
children,
className,
component,
...props
}: MastheadBrandProps) => {
let Component = component as any;
if (!component) {
if (props?.href !== undefined) {
Component = 'a';
} else {
Component = 'span';
}
}
return (
<Component className={css(styles.mastheadBrand, className)} {...(Component === 'a' && { tabIndex: 0 })} {...props}>
{children}
</Component>
);
};
}: MastheadBrandProps) => (
<div className={css(styles.mastheadBrand, className)} {...props}>
{children}
</div>
);
MastheadBrand.displayName = 'MastheadBrand';
35 changes: 35 additions & 0 deletions packages/react-core/src/components/Masthead/MastheadLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as React from 'react';
import styles from '@patternfly/react-styles/css/components/Masthead/masthead';
import { css } from '@patternfly/react-styles';

export interface MastheadLogoProps
extends React.DetailedHTMLProps<React.HTMLProps<HTMLAnchorElement>, HTMLAnchorElement> {
/** Content rendered inside of the masthead logo. */
children?: React.ReactNode;
/** Additional classes added to the masthead logo. */
className?: string;
/** Component type of the masthead logo. */
component?: React.ElementType<any> | React.ComponentType<any>;
}

export const MastheadLogo: React.FunctionComponent<MastheadLogoProps> = ({
children,
className,
component,
...props
}: MastheadLogoProps) => {
let Component = component as any;
if (!component) {
if (props?.href !== undefined) {
Component = 'a';
} else {
Component = 'span';
}
}
return (
<Component className={css(styles.mastheadLogo, className)} {...(Component === 'a' && { tabIndex: 0 })} {...props}>
{children}
</Component>
);
};
MastheadLogo.displayName = 'MastheadLogo';
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { render } from '@testing-library/react';
import { Masthead, MastheadBrand, MastheadContent, MastheadMain, MastheadToggle } from '../index';
import { Masthead, MastheadMain, MastheadLogo, MastheadContent, MastheadBrand, MastheadToggle } from '../index';

describe('Masthead', () => {
test('verify basic', () => {
Expand All @@ -12,9 +12,11 @@ describe('Masthead', () => {
test('verify full structure', () => {
const { asFragment } = render(
<Masthead>
<MastheadToggle>Toggle</MastheadToggle>
<MastheadMain>
<MastheadBrand>Logo</MastheadBrand>
<MastheadToggle>Toggle</MastheadToggle>
<MastheadBrand>
<MastheadLogo>Logo</MastheadLogo>
</MastheadBrand>
</MastheadMain>
<MastheadContent>
<span>Content</span>
Expand Down Expand Up @@ -72,33 +74,33 @@ describe('Masthead', () => {
});
});

describe('MastheadBrand', () => {
describe('MastheadLogo', () => {
test('verify basic', () => {
const { asFragment } = render(<MastheadBrand>test</MastheadBrand>);
const { asFragment } = render(<MastheadLogo>test</MastheadLogo>);

expect(asFragment()).toMatchSnapshot();
});

test('verify custom class', () => {
const { asFragment } = render(<MastheadBrand className="custom-css">test</MastheadBrand>);
const { asFragment } = render(<MastheadLogo className="custom-css">test</MastheadLogo>);

expect(asFragment()).toMatchSnapshot();
});

test('verify default component', () => {
const { asFragment } = render(<MastheadBrand>test</MastheadBrand>);
const { asFragment } = render(<MastheadLogo>test</MastheadLogo>);

expect(asFragment()).toMatchSnapshot();
});

test('verify custom component', () => {
const { asFragment } = render(<MastheadBrand component="div">test</MastheadBrand>);
const { asFragment } = render(<MastheadLogo component="div">test</MastheadLogo>);

expect(asFragment()).toMatchSnapshot();
});

test('verify anchor component with href', () => {
const { asFragment } = render(<MastheadBrand href="#">test</MastheadBrand>);
const { asFragment } = render(<MastheadLogo href="#">test</MastheadLogo>);

expect(asFragment()).toMatchSnapshot();
});
Expand All @@ -118,15 +120,15 @@ describe('MastheadContent', () => {
});
});

describe('MastheadMain', () => {
describe('MastheadBrand', () => {
test('verify basic', () => {
const { asFragment } = render(<MastheadMain>test</MastheadMain>);
const { asFragment } = render(<MastheadBrand>test</MastheadBrand>);

expect(asFragment()).toMatchSnapshot();
});

test('verify custom class', () => {
const { asFragment } = render(<MastheadMain className="custom-css">test</MastheadMain>);
const { asFragment } = render(<MastheadBrand className="custom-css">test</MastheadBrand>);

expect(asFragment()).toMatchSnapshot();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,23 @@ exports[`Masthead verify full structure 1`] = `
<header
class="pf-v6-c-masthead pf-m-display-inline-on-md"
>
<span
class="pf-v6-c-masthead__toggle"
>
Toggle
</span>
<div
class="pf-v6-c-masthead__main"
>
<span
class="pf-v6-c-masthead__brand"
class="pf-v6-c-masthead__toggle"
>
Logo
Toggle
</span>
<div
class="pf-v6-c-masthead__brand"
>
<span
class="pf-v6-c-masthead__logo"
>
Logo
</span>
</div>
</div>
<div
class="pf-v6-c-masthead__content"
Expand Down Expand Up @@ -150,95 +154,95 @@ exports[`Masthead verify stack display breakpoints 1`] = `
</DocumentFragment>
`;

exports[`MastheadBrand verify anchor component with href 1`] = `
exports[`MastheadBrand verify basic 1`] = `
<DocumentFragment>
<a
<div
class="pf-v6-c-masthead__brand"
href="#"
tabindex="0"
>
test
</a>
</div>
</DocumentFragment>
`;

exports[`MastheadBrand verify basic 1`] = `
exports[`MastheadBrand verify custom class 1`] = `
<DocumentFragment>
<span
class="pf-v6-c-masthead__brand"
<div
class="pf-v6-c-masthead__brand custom-css"
>
test
</span>
</div>
</DocumentFragment>
`;

exports[`MastheadBrand verify custom class 1`] = `
exports[`MastheadContent verify basic 1`] = `
<DocumentFragment>
<span
class="pf-v6-c-masthead__brand custom-css"
<div
class="pf-v6-c-masthead__content"
>
test
</span>
</div>
</DocumentFragment>
`;

exports[`MastheadBrand verify custom component 1`] = `
exports[`MastheadContent verify custom class 1`] = `
<DocumentFragment>
<div
class="pf-v6-c-masthead__brand"
class="pf-v6-c-masthead__content custom-css"
>
test
</div>
</DocumentFragment>
`;

exports[`MastheadBrand verify default component 1`] = `
exports[`MastheadLogo verify anchor component with href 1`] = `
<DocumentFragment>
<span
class="pf-v6-c-masthead__brand"
<a
class="pf-v6-c-masthead__logo"
href="#"
tabindex="0"
>
test
</span>
</a>
</DocumentFragment>
`;

exports[`MastheadContent verify basic 1`] = `
exports[`MastheadLogo verify basic 1`] = `
<DocumentFragment>
<div
class="pf-v6-c-masthead__content"
<span
class="pf-v6-c-masthead__logo"
>
test
</div>
</span>
</DocumentFragment>
`;

exports[`MastheadContent verify custom class 1`] = `
exports[`MastheadLogo verify custom class 1`] = `
<DocumentFragment>
<div
class="pf-v6-c-masthead__content custom-css"
<span
class="pf-v6-c-masthead__logo custom-css"
>
test
</div>
</span>
</DocumentFragment>
`;

exports[`MastheadMain verify basic 1`] = `
exports[`MastheadLogo verify custom component 1`] = `
<DocumentFragment>
<div
class="pf-v6-c-masthead__main"
class="pf-v6-c-masthead__logo"
>
test
</div>
</DocumentFragment>
`;

exports[`MastheadMain verify custom class 1`] = `
exports[`MastheadLogo verify default component 1`] = `
<DocumentFragment>
<div
class="pf-v6-c-masthead__main custom-css"
<span
class="pf-v6-c-masthead__logo"
>
test
</div>
</span>
</DocumentFragment>
`;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
id: Masthead
section: components
cssPrefix: pf-v5-c-masthead
propComponents: ['Masthead', 'MastheadToggle', 'MastheadMain', 'MastheadBrand', 'MastheadContent']
propComponents: ['Masthead', 'MastheadToggle', 'MastheadMain', 'MastheadBrand', MastheadLogo, 'MastheadContent']
---

import BarsIcon from '@patternfly/react-icons/dist/js/icons/bars-icon';
import { Link } from '@reach/router';
import pfIcon from '../../assets/PF-HorizontalLogo-Color.svg';

`Masthead` should contain the following components to maintain proper layout and formatting: `MastheadToggle`, `MastheadMain`, and `MastheadContent`.
To maintain proper layout and formatting, a `<Masthead>` should contain both a `<MastheadMain>` and `<MastheadContent>` component.

`MastheadMain` represents the smaller area taken up by a logo, and will typically contain a `MastheadBrand`. `MastheadContent` represents the main portion of the masthead area and will typically contain a `Toolbar` or other menu-like content such as `Dropdown`.
Mastheads contain the `<MastheadMain>` that wraps a `<PageToggleButton>` and `<MastheadBrand>`. The `<MastheadBrand>` wraps `<MastheadLogo>`. The masthead also contains the page's header toolbar within `<MastheadContent>`.

## Examples

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import React from 'react';
import { Masthead, MastheadToggle, MastheadMain, MastheadBrand, MastheadContent, Button } from '@patternfly/react-core';
import {
Masthead,
MastheadMain,
MastheadToggle,
MastheadBrand,
MastheadLogo,
MastheadContent,
Button
} from '@patternfly/react-core';
import BarsIcon from '@patternfly/react-icons/dist/js/icons/bars-icon';

export const MastheadBasic: React.FunctionComponent = () => (
<Masthead id="basic-example">
<MastheadToggle>
<Button variant="plain" onClick={() => {}} aria-label="Global navigation" icon={<BarsIcon />} />
</MastheadToggle>
<MastheadMain>
<MastheadBrand component="a">Logo</MastheadBrand>
<MastheadToggle>
<Button variant="plain" onClick={() => {}} aria-label="Global navigation" icon={<BarsIcon />} />
</MastheadToggle>
<MastheadBrand>
<MastheadLogo component="a">Logo</MastheadLogo>
</MastheadBrand>
</MastheadMain>
<MastheadContent>
<span>Content</span>
Expand Down
Loading
Loading