Skip to content

Commit 1f7485b

Browse files
feat(Page): added styles for glass (#12293)
* feat(Page): added styles for glass * Added console warning * Added plain example * Updated unit tests * Removed console warning * Updated test names per coderabbit * Bumped core for page sidebar fix * Updated noPlainOnGlsss description
1 parent a7a847c commit 1f7485b

File tree

19 files changed

+350
-127
lines changed

19 files changed

+350
-127
lines changed

packages/react-core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@
5454
"tslib": "^2.8.1"
5555
},
5656
"devDependencies": {
57-
"@patternfly/patternfly": "6.5.0-prerelease.62",
57+
"@patternfly/patternfly": "6.5.0-prerelease.65",
5858
"case-anything": "^3.1.2",
5959
"css": "^3.0.0",
6060
"fs-extra": "^11.3.3"

packages/react-core/src/components/Page/Page.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,13 @@ class Page extends Component<PageProps, PageState> {
348348
)}
349349
>
350350
{skipToContent}
351-
{variant === 'docked' ? <div className={css(styles.pageDock)}>{masthead}</div> : masthead}
351+
{variant === 'docked' ? (
352+
<div className={css(styles.pageDock)}>
353+
<div className={css(styles.pageDockMain)}>{masthead}</div>
354+
</div>
355+
) : (
356+
masthead
357+
)}
352358
{sidebar}
353359
{notificationDrawer && (
354360
<div className={css(styles.pageDrawer)}>

packages/react-core/src/components/Page/PageGroup.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ export interface PageGroupProps extends React.HTMLProps<HTMLDivElement> {
2727
hasOverflowScroll?: boolean;
2828
/** Adds an accessible name to the page group when the hasOverflowScroll prop is set to true. */
2929
'aria-label'?: string;
30+
/** Adds plain styling to the page group. */
31+
isPlain?: boolean;
32+
/** @beta Prevents the page group from automatically applying plain styling when glass theme is enabled. */
33+
isNoPlainOnGlass?: boolean;
3034
}
3135

3236
export const PageGroup = ({
@@ -38,6 +42,8 @@ export const PageGroup = ({
3842
hasShadowBottom = false,
3943
hasOverflowScroll = false,
4044
'aria-label': ariaLabel,
45+
isPlain = false,
46+
isNoPlainOnGlass = false,
4147
...props
4248
}: PageGroupProps) => {
4349
const { height, getVerticalBreakpoint } = useContext(PageContext);
@@ -60,6 +66,8 @@ export const PageGroup = ({
6066
hasShadowTop && styles.modifiers.shadowTop,
6167
hasShadowBottom && styles.modifiers.shadowBottom,
6268
hasOverflowScroll && styles.modifiers.overflowScroll,
69+
isPlain && styles.modifiers.plain,
70+
isNoPlainOnGlass && styles.modifiers.noPlainOnGlass,
6371
className
6472
)}
6573
{...(hasOverflowScroll && { tabIndex: 0, role: 'region', 'aria-label': ariaLabel })}

packages/react-core/src/components/Page/PageSection.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ export interface PageSectionProps extends React.HTMLProps<HTMLDivElement> {
6767
'aria-label'?: string;
6868
/** Sets the base component to render. Defaults to section */
6969
component?: keyof React.JSX.IntrinsicElements;
70+
/** Adds plain styling to the page section. */
71+
isPlain?: boolean;
72+
/** @beta Prevents the page section from automatically applying plain styling when glass theme is enabled. */
73+
isNoPlainOnGlass?: boolean;
7074
}
7175

7276
const variantType = {
@@ -98,6 +102,8 @@ export const PageSection: React.FunctionComponent<PageSectionProps> = ({
98102
'aria-label': ariaLabel,
99103
component = 'section',
100104
hasBodyWrapper = true,
105+
isPlain = false,
106+
isNoPlainOnGlass = false,
101107
...props
102108
}: PageSectionProps) => {
103109
const { height, getVerticalBreakpoint } = useContext(PageContext);
@@ -126,6 +132,8 @@ export const PageSection: React.FunctionComponent<PageSectionProps> = ({
126132
hasShadowTop && styles.modifiers.shadowTop,
127133
hasShadowBottom && styles.modifiers.shadowBottom,
128134
hasOverflowScroll && styles.modifiers.overflowScroll,
135+
isPlain && styles.modifiers.plain,
136+
isNoPlainOnGlass && styles.modifiers.noPlainOnGlass,
129137
className
130138
)}
131139
{...(hasOverflowScroll && { tabIndex: 0 })}

packages/react-core/src/components/Page/PageSidebar.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ export const PageSidebar: React.FunctionComponent<PageSidebarProps> = ({
5050
aria-hidden={!sidebarOpen}
5151
{...props}
5252
>
53-
<PageSidebarContext.Provider value={{ isSidebarOpen: sidebarOpen }}>{children}</PageSidebarContext.Provider>
53+
<PageSidebarContext.Provider value={{ isSidebarOpen: sidebarOpen }}>
54+
<div className={css(styles.pageSidebarMain)}>{children}</div>
55+
</PageSidebarContext.Provider>
5456
</div>
5557
);
5658
}}

packages/react-core/src/components/Page/__tests__/Generated/__snapshots__/PageSidebar.test.tsx.snap

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ exports[`PageSidebar should match snapshot (auto-generated) 1`] = `
77
class="pf-v6-c-page__sidebar ''"
88
id="page-sidebar"
99
>
10-
<div>
11-
ReactNode
10+
<div
11+
class="pf-v6-c-page__sidebar-main"
12+
>
13+
<div>
14+
ReactNode
15+
</div>
1216
</div>
1317
</div>
1418
</DocumentFragment>

packages/react-core/src/components/Page/__tests__/Page.test.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,4 +406,11 @@ describe('Page', () => {
406406
render(<Page data-testid="page"></Page>);
407407
expect(screen.getByTestId('page')).not.toHaveClass(styles.modifiers.dock);
408408
});
409+
410+
test(`Renders with ${styles.pageDockMain} wrapper when variant is docked`, () => {
411+
render(<Page variant="docked" masthead={<>Masthead</>} data-testid="page"></Page>);
412+
413+
const pageDockMain = screen.getByText('Masthead').closest(`.${styles.pageDockMain}`);
414+
expect(pageDockMain).toBeInTheDocument();
415+
});
409416
});

packages/react-core/src/components/Page/__tests__/PageGroup.test.tsx

Lines changed: 98 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -2,92 +2,102 @@ import { render, screen } from '@testing-library/react';
22
import { PageGroup } from '../PageGroup';
33
import styles from '@patternfly/react-styles/css/components/Page/page';
44

5-
describe('page group', () => {
6-
test('Verify basic render', () => {
7-
const { asFragment } = render(<PageGroup>test</PageGroup>);
8-
expect(asFragment()).toMatchSnapshot();
9-
});
10-
test('Verify top sticky', () => {
11-
const { asFragment } = render(<PageGroup stickyOnBreakpoint={{ default: 'top' }}>test</PageGroup>);
12-
expect(asFragment()).toMatchSnapshot();
13-
});
14-
test('Verify bottom sticky', () => {
15-
const { asFragment } = render(<PageGroup stickyOnBreakpoint={{ default: 'bottom' }}>test</PageGroup>);
16-
expect(asFragment()).toMatchSnapshot();
17-
});
18-
test('Verify top shadow', () => {
19-
const { asFragment } = render(<PageGroup hasShadowTop>test</PageGroup>);
20-
expect(asFragment()).toMatchSnapshot();
21-
});
22-
test('Verify bottom shadow', () => {
23-
const { asFragment } = render(<PageGroup hasShadowBottom>test</PageGroup>);
24-
expect(asFragment()).toMatchSnapshot();
25-
});
26-
test('Verify overflow scroll', () => {
27-
const { asFragment } = render(<PageGroup hasOverflowScroll>test</PageGroup>);
28-
expect(asFragment()).toMatchSnapshot();
29-
});
30-
31-
test('Renders without an aria-label by default', () => {
32-
render(<PageGroup>test</PageGroup>);
33-
34-
expect(screen.getByText('test')).not.toHaveAccessibleName('Test label');
35-
});
36-
37-
test('Renders with the passed aria-label applied', () => {
38-
render(
39-
<PageGroup aria-label="Test label" hasOverflowScroll>
40-
test
41-
</PageGroup>
42-
);
43-
44-
expect(screen.getByText('test')).toHaveAccessibleName('Test label');
45-
});
46-
47-
test('Does not log a warning in the console by default', () => {
48-
const consoleWarning = jest.spyOn(console, 'warn').mockImplementation();
49-
50-
render(<PageGroup>test</PageGroup>);
51-
52-
expect(consoleWarning).not.toHaveBeenCalled();
53-
});
54-
55-
test('Does not log a warning in the console when an aria-label is included with hasOverflowScroll', () => {
56-
const consoleWarning = jest.spyOn(console, 'warn').mockImplementation();
57-
58-
render(
59-
<PageGroup hasOverflowScroll aria-label="Test label">
60-
test
61-
</PageGroup>
62-
);
63-
64-
expect(consoleWarning).not.toHaveBeenCalled();
65-
});
66-
67-
test('Logs a warning in the console when an aria-label is not included with hasOverflowScroll', () => {
68-
const consoleWarning = jest.spyOn(console, 'warn').mockImplementation();
69-
70-
render(<PageGroup hasOverflowScroll>test</PageGroup>);
71-
72-
expect(consoleWarning).toHaveBeenCalled();
73-
});
74-
75-
test(`Does not render with ${styles.modifiers.fill} or ${styles.modifiers.noFill} if isFilled is not passed`, () => {
76-
render(<PageGroup>test</PageGroup>);
77-
78-
expect(screen.getByText('test')).not.toHaveClass(styles.modifiers.fill);
79-
expect(screen.getByText('test')).not.toHaveClass(styles.modifiers.noFill);
80-
});
81-
82-
test(`Renders with ${styles.modifiers.fill} if isFilled={true} is passed`, () => {
83-
render(<PageGroup isFilled={true}>test</PageGroup>);
84-
85-
expect(screen.getByText('test')).toHaveClass(styles.modifiers.fill);
86-
});
87-
88-
test(`Renders with ${styles.modifiers.noFill} if isFilled={false} is passed`, () => {
89-
render(<PageGroup isFilled={false}>test</PageGroup>);
90-
91-
expect(screen.getByText('test')).toHaveClass(styles.modifiers.noFill);
92-
});
5+
test('Verify basic render', () => {
6+
const { asFragment } = render(<PageGroup>test</PageGroup>);
7+
expect(asFragment()).toMatchSnapshot();
8+
});
9+
test('Verify top sticky', () => {
10+
const { asFragment } = render(<PageGroup stickyOnBreakpoint={{ default: 'top' }}>test</PageGroup>);
11+
expect(asFragment()).toMatchSnapshot();
12+
});
13+
test('Verify bottom sticky', () => {
14+
const { asFragment } = render(<PageGroup stickyOnBreakpoint={{ default: 'bottom' }}>test</PageGroup>);
15+
expect(asFragment()).toMatchSnapshot();
16+
});
17+
test('Verify top shadow', () => {
18+
const { asFragment } = render(<PageGroup hasShadowTop>test</PageGroup>);
19+
expect(asFragment()).toMatchSnapshot();
20+
});
21+
test('Verify bottom shadow', () => {
22+
const { asFragment } = render(<PageGroup hasShadowBottom>test</PageGroup>);
23+
expect(asFragment()).toMatchSnapshot();
24+
});
25+
test('Verify overflow scroll', () => {
26+
const { asFragment } = render(<PageGroup hasOverflowScroll>test</PageGroup>);
27+
expect(asFragment()).toMatchSnapshot();
28+
});
29+
30+
test('Renders without an aria-label by default', () => {
31+
render(<PageGroup>test</PageGroup>);
32+
33+
expect(screen.getByText('test')).not.toHaveAccessibleName('Test label');
34+
});
35+
36+
test('Renders with the passed aria-label applied', () => {
37+
render(
38+
<PageGroup aria-label="Test label" hasOverflowScroll>
39+
test
40+
</PageGroup>
41+
);
42+
43+
expect(screen.getByText('test')).toHaveAccessibleName('Test label');
44+
});
45+
46+
test('Does not log a warning in the console by default', () => {
47+
const consoleWarning = jest.spyOn(console, 'warn').mockImplementation();
48+
49+
render(<PageGroup>test</PageGroup>);
50+
51+
expect(consoleWarning).not.toHaveBeenCalled();
52+
});
53+
54+
test('Does not log a warning in the console when an aria-label is included with hasOverflowScroll', () => {
55+
const consoleWarning = jest.spyOn(console, 'warn').mockImplementation();
56+
57+
render(
58+
<PageGroup hasOverflowScroll aria-label="Test label">
59+
test
60+
</PageGroup>
61+
);
62+
63+
expect(consoleWarning).not.toHaveBeenCalled();
64+
});
65+
66+
test('Logs a warning in the console when an aria-label is not included with hasOverflowScroll', () => {
67+
const consoleWarning = jest.spyOn(console, 'warn').mockImplementation();
68+
69+
render(<PageGroup hasOverflowScroll>test</PageGroup>);
70+
71+
expect(consoleWarning).toHaveBeenCalled();
72+
});
73+
74+
test(`Does not render with ${styles.modifiers.fill} or ${styles.modifiers.noFill} if isFilled is not passed`, () => {
75+
render(<PageGroup>test</PageGroup>);
76+
77+
expect(screen.getByText('test')).not.toHaveClass(styles.modifiers.fill);
78+
expect(screen.getByText('test')).not.toHaveClass(styles.modifiers.noFill);
79+
});
80+
81+
test(`Renders with ${styles.modifiers.fill} if isFilled={true} is passed`, () => {
82+
render(<PageGroup isFilled={true}>test</PageGroup>);
83+
84+
expect(screen.getByText('test')).toHaveClass(styles.modifiers.fill);
85+
});
86+
87+
test(`Renders with ${styles.modifiers.noFill} if isFilled={false} is passed`, () => {
88+
render(<PageGroup isFilled={false}>test</PageGroup>);
89+
90+
expect(screen.getByText('test')).toHaveClass(styles.modifiers.noFill);
91+
});
92+
93+
test(`Renders with ${styles.modifiers.plain} class when isPlain is true`, () => {
94+
render(<PageGroup isPlain>test</PageGroup>);
95+
96+
expect(screen.getByText('test')).toHaveClass(styles.modifiers.plain);
97+
});
98+
99+
test(`Renders with ${styles.modifiers.noPlainOnGlass} class when isNoPlainOnGlass is true`, () => {
100+
render(<PageGroup isNoPlainOnGlass>test</PageGroup>);
101+
102+
expect(screen.getByText('test')).toHaveClass(styles.modifiers.noPlainOnGlass);
93103
});

packages/react-core/src/components/Page/__tests__/PageSection.test.tsx

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,23 @@ test(`Renders with ${styles.modifiers.noFill} if isFilled={false} is passed`, ()
179179

180180
expect(screen.getByRole('main')).toHaveClass(styles.modifiers.noFill);
181181
});
182+
183+
test(`Renders with ${styles.modifiers.plain} class when isPlain is true`, () => {
184+
render(
185+
<PageSection hasBodyWrapper={false} isPlain>
186+
test
187+
</PageSection>
188+
);
189+
190+
expect(screen.getByText('test')).toHaveClass(styles.modifiers.plain);
191+
});
192+
193+
test(`Renders with ${styles.modifiers.noPlainOnGlass} class when isNoPlainOnGlass is true`, () => {
194+
render(
195+
<PageSection hasBodyWrapper={false} isNoPlainOnGlass>
196+
test
197+
</PageSection>
198+
);
199+
200+
expect(screen.getByText('test')).toHaveClass(styles.modifiers.noPlainOnGlass);
201+
});
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { render, screen } from '@testing-library/react';
2+
import { PageSidebar } from '../PageSidebar';
3+
import styles from '@patternfly/react-styles/css/components/Page/page';
4+
5+
test(`Renders with ${styles.pageSidebarMain} wrapper`, () => {
6+
render(<PageSidebar data-testid="sidebar">Test</PageSidebar>);
7+
8+
expect(screen.getByText('Test')).toHaveClass(styles.pageSidebarMain);
9+
});

0 commit comments

Comments
 (0)