Skip to content

Commit 5b0320f

Browse files
tay1orjonesheloiseluikennylam
authored
feat(pageheader): initial components, exports, stories, styles, tests (#18788)
* feat(pageheader): initial components, exports, stories, styles, tests * chore: update copyright, remove old component files * chore: ignore stylelint * chore: update snaps * fix(snapshots): config jest to use prettier2 * chore(sb): update includeStories to prevent showing in prod --------- Co-authored-by: Heloise Lui <71858203+heloiselui@users.noreply.github.com> Co-authored-by: Kenny Lam <909118+kennylam@users.noreply.github.com>
1 parent 6d2c791 commit 5b0320f

File tree

16 files changed

+521
-3
lines changed

16 files changed

+521
-3
lines changed

jest.config.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright IBM Corp. 2018, 2023
2+
* Copyright IBM Corp. 2018, 2025
33
*
44
* This source code is licensed under the Apache-2.0 license found in the
55
* LICENSE file in the root directory of this source tree.
@@ -31,4 +31,8 @@ module.exports = {
3131
nanoid: require.resolve('nanoid'),
3232
},
3333
reporters: ['default', 'jest-junit'],
34+
35+
// This is a temporary workaround until Jest supports Prettier 3 (and ESM)
36+
// @see https://jestjs.io/docs/configuration#prettierpath-string
37+
prettierPath: require.resolve('prettier2'),
3438
};

packages/react/.storybook/main.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright IBM Corp. 2016, 2023
2+
* Copyright IBM Corp. 2016, 2025
33
*
44
* This source code is licensed under the Apache-2.0 license found in the
55
* LICENSE file in the root directory of this source tree.
@@ -151,6 +151,7 @@ const config = {
151151
path.resolve(__dirname, '..', 'node_modules'),
152152
path.resolve(__dirname, '..', '..', '..', 'node_modules'),
153153
],
154+
// quietDeps: true,
154155
},
155156
warnRuleAsWarning: true,
156157
sourceMap: true,

packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10862,6 +10862,40 @@ Map {
1086210862
},
1086310863
"render": [Function],
1086410864
},
10865+
"unstable__PageHeader" => Object {
10866+
"BreadcrumbBar": Object {
10867+
"$$typeof": Symbol(react.forward_ref),
10868+
"render": [Function],
10869+
},
10870+
"Content": Object {
10871+
"$$typeof": Symbol(react.forward_ref),
10872+
"render": [Function],
10873+
},
10874+
"PageHeader": Object {
10875+
"$$typeof": Symbol(react.forward_ref),
10876+
"render": [Function],
10877+
},
10878+
"PageHeaderBreadcrumbBar": Object {
10879+
"$$typeof": Symbol(react.forward_ref),
10880+
"render": [Function],
10881+
},
10882+
"PageHeaderContent": Object {
10883+
"$$typeof": Symbol(react.forward_ref),
10884+
"render": [Function],
10885+
},
10886+
"PageHeaderTabBar": Object {
10887+
"$$typeof": Symbol(react.forward_ref),
10888+
"render": [Function],
10889+
},
10890+
"Root": Object {
10891+
"$$typeof": Symbol(react.forward_ref),
10892+
"render": [Function],
10893+
},
10894+
"TabBar": Object {
10895+
"$$typeof": Symbol(react.forward_ref),
10896+
"render": [Function],
10897+
},
10898+
},
1086510899
"unstable__ShapeIndicator" => Object {
1086610900
"$$typeof": Symbol(react.forward_ref),
1086710901
"propTypes": Object {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Code generated by @carbon/react. DO NOT EDIT.
2+
//
3+
// Copyright IBM Corp. 2025
4+
//
5+
// This source code is licensed under the Apache-2.0 license found in the
6+
// LICENSE file in the root directory of this source tree.
7+
//
8+
9+
@forward '@carbon/styles/scss/components/page-header';
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Code generated by @carbon/react. DO NOT EDIT.
2+
//
3+
// Copyright IBM Corp. 2025
4+
//
5+
// This source code is licensed under the Apache-2.0 license found in the
6+
// LICENSE file in the root directory of this source tree.
7+
//
8+
9+
@forward '@carbon/styles/scss/components/page-header/page-header';

packages/react/src/__tests__/index-test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ describe('Carbon Components React', () => {
285285
"unstable__FluidTimePickerSelect",
286286
"unstable__FluidTimePickerSkeleton",
287287
"unstable__IconIndicator",
288+
"unstable__PageHeader",
288289
"unstable__ShapeIndicator",
289290
"unstable__Slug",
290291
"unstable__SlugActions",
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/**
2+
* Copyright IBM Corp. 2025
3+
*
4+
* This source code is licensed under the Apache-2.0 license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
import { render, screen } from '@testing-library/react';
8+
import userEvent from '@testing-library/user-event';
9+
import React from 'react';
10+
import { unstable__PageHeader as PageHeader } from '../../';
11+
import {
12+
PageHeader as PageHeaderDirect,
13+
PageHeaderBreadcrumbBar as PageHeaderBreadcrumbBarDirect,
14+
PageHeaderContent as PageHeaderContentDirect,
15+
PageHeaderTabBar as PageHeaderTabBarDirect,
16+
} from '../PageHeader';
17+
18+
describe('PageHeader', () => {
19+
describe('export configuration', () => {
20+
it('supports dot notation component namespacing from the main entrypoint', () => {
21+
const { container } = render(
22+
<PageHeader.Root>
23+
<PageHeader.BreadcrumbBar />
24+
<PageHeader.Content />
25+
<PageHeader.TabBar />
26+
</PageHeader.Root>
27+
);
28+
expect(container.firstChild).toBeInTheDocument();
29+
});
30+
31+
it('supports direct component imports from the PageHeader path', () => {
32+
const { container } = render(
33+
<PageHeaderDirect>
34+
<PageHeaderBreadcrumbBarDirect />
35+
<PageHeaderContentDirect />
36+
<PageHeaderTabBarDirect />
37+
</PageHeaderDirect>
38+
);
39+
expect(container.firstChild).toBeInTheDocument();
40+
});
41+
});
42+
43+
describe('PageHeader.Root component api', () => {
44+
it('should render', () => {
45+
const { container } = render(<PageHeader.Root />);
46+
expect(container.firstChild).toBeInTheDocument();
47+
});
48+
49+
it('should place className on the outermost element', () => {
50+
const { container } = render(
51+
<PageHeader.Root className="custom-class" />
52+
);
53+
expect(container.firstChild).toHaveClass('custom-class');
54+
});
55+
});
56+
57+
describe('PageHeader.BreadcrumbBar component api', () => {
58+
it('should render', () => {
59+
const { container } = render(<PageHeader.BreadcrumbBar />);
60+
expect(container.firstChild).toBeInTheDocument();
61+
});
62+
63+
it('should place className on the outermost element', () => {
64+
const { container } = render(
65+
<PageHeader.BreadcrumbBar className="custom-class" />
66+
);
67+
expect(container.firstChild).toHaveClass('custom-class');
68+
});
69+
});
70+
71+
describe('PageHeader.Content component api', () => {
72+
it('should render', () => {
73+
const { container } = render(<PageHeader.Content />);
74+
expect(container.firstChild).toBeInTheDocument();
75+
});
76+
77+
it('should place className on the outermost element', () => {
78+
const { container } = render(
79+
<PageHeader.Content className="custom-class" />
80+
);
81+
expect(container.firstChild).toHaveClass('custom-class');
82+
});
83+
});
84+
85+
describe('PageHeader.TabBar component api', () => {
86+
it('should render', () => {
87+
const { container } = render(<PageHeader.TabBar />);
88+
expect(container.firstChild).toBeInTheDocument();
89+
});
90+
91+
it('should place className on the outermost element', () => {
92+
const { container } = render(
93+
<PageHeader.TabBar className="custom-class" />
94+
);
95+
expect(container.firstChild).toHaveClass('custom-class');
96+
});
97+
});
98+
});
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { Story, ArgTypes, Canvas, Meta } from '@storybook/blocks';
2+
import * as PageHeaderStories from './PageHeader.stories';
3+
import { stackblitzPrefillConfig } from '../../../previewer/codePreviewer';
4+
5+
<Meta isTemplate />
6+
7+
# PageHeader
8+
9+
[Source code](https://github.com/carbon-design-system/carbon/tree/main/packages/react/src/components/PageHeader)
10+
&nbsp;|&nbsp;
11+
[Usage guidelines](https://www.carbondesignsystem.com/components/page-header/usage)
12+
&nbsp;|&nbsp;
13+
[Accessibility](https://www.carbondesignsystem.com/components/page-header/accessibility)
14+
15+
## Table of Contents
16+
17+
## Overview
18+
19+
The page header is a large family of components.
20+
21+
<Canvas
22+
of={PageHeaderStories.Default}
23+
additionalActions={[
24+
{
25+
title: 'Open in Stackblitz',
26+
onClick: () => stackblitzPrefillConfig(PageHeaderStories.Default),
27+
},
28+
]}
29+
/>
30+
31+
## Component API
32+
33+
<ArgTypes />
34+
35+
## Feedback
36+
37+
Help us improve this component by providing feedback, asking questions on Slack,
38+
or updating this file on
39+
[GitHub](https://github.com/carbon-design-system/carbon/edit/main/packages/react/src/components/PageHeader/PageHeader.mdx).
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/**
2+
* Copyright IBM Corp. 2025
3+
*
4+
* This source code is licensed under the Apache-2.0 license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
import React from 'react';
8+
import { unstable__PageHeader as PageHeader } from '../../';
9+
import {
10+
PageHeader as PageHeaderDirect,
11+
PageHeaderBreadcrumbBar,
12+
PageHeaderContent,
13+
PageHeaderTabBar,
14+
} from '../PageHeader';
15+
import mdx from './PageHeader.mdx';
16+
17+
export default {
18+
title: 'Patterns/unstable__PageHeader',
19+
component: PageHeader,
20+
subcomponents: {
21+
PageHeaderBreadcrumbBar,
22+
PageHeaderContent,
23+
PageHeaderTabBar,
24+
},
25+
includeStories: [],
26+
argTypes: {
27+
children: {
28+
control: false, // ReactNode props don't work in the controls pane
29+
},
30+
},
31+
parameters: {
32+
docs: {
33+
page: mdx,
34+
},
35+
},
36+
};
37+
38+
export const Default = (args) => (
39+
<PageHeader.Root {...args}>
40+
<PageHeader.BreadcrumbBar />
41+
<PageHeader.Content />
42+
<PageHeader.TabBar />
43+
</PageHeader.Root>
44+
);
45+
46+
export const BreadcrumbBar = (args) => (
47+
<PageHeader.Root>
48+
<PageHeader.BreadcrumbBar {...args} />
49+
</PageHeader.Root>
50+
);
51+
52+
export const Content = (args) => (
53+
<PageHeader.Root>
54+
<PageHeader.Content {...args} />
55+
</PageHeader.Root>
56+
);
57+
58+
export const TabBar = (args) => (
59+
<PageHeader.Root>
60+
<PageHeader.TabBar {...args} />
61+
</PageHeader.Root>
62+
);
63+
64+
export const DirectExports = (args) => (
65+
<PageHeaderDirect {...args}>
66+
<PageHeaderBreadcrumbBar />
67+
<PageHeaderContent />
68+
<PageHeaderTabBar />
69+
</PageHeaderDirect>
70+
);

0 commit comments

Comments
 (0)