Skip to Content

Page Header

The page header bar is fixed to the top of the page. At its core, the page header is simply a container with set padding and any number of page level elements within.

The PageHeader component follows this same idea, acting merely as a container (<header />) with some padding, and two callbacks (leftContent and rightContent) with a dynamic breakpoint argument, making implementing responsive behavior straight forward.

Loading...

import { Tabs as TabsContext } from '@camp/tabs'; // The encasing "Tabs" serves as a context provider for the TabLists and TabTrigger components import { LeftContent } from './LeftContent.tsx'; import { RightContent } from './RightContent.tsx'; import { PageHeader } from '@camp/page-header'; <TabsContext> <PageHeader leftContent={LeftContent} rightContent={RightContent} /> </TabsContext>;
// LeftContent.tsx import { TabLists, TabTrigger } from '@camp/tabs'; import { MoreMenuMedium } from '@camp/icon'; import { Text } from '@camp/text'; export const LeftContent = ({ breakpoint }) => { return ( <div style={{ display: 'flex', flexDirection: 'column', justifyContent: 'center', gap: '12px' }} > <Text type="heading" as="h1"> Campaigns ({breakpoint}) </Text> <TabLists> <TabTrigger value="tab 1">Tab 1</TabTrigger> <TabTrigger value="tab 2">Tab 2</TabTrigger> <TabTrigger value="tab 3">Tab 3</TabTrigger> <TabTrigger value="tab 4">Tab 4</TabTrigger> </TabLists> </div> ); };
// RightContent.tsx import Button from '@activecampaign/camp-components-button'; import { IconButton } from '@camp/icon-button'; import { MoreMenuMedium } from '@camp/icon'; export const RightContent = ({ breakpoint }) => { switch (breakpoint) { case 'small': return ( <div> <IconButton> <MoreMenuMedium title="title" /> </IconButton> </div> ); default: return ( <div> <Button>Button</Button> </div> ); } };

Overview

NameTypeDescription
leftContentReact.FC<{ breakpoint: 'small' | 'medium' | 'large' }>Component rendered on the left side of the header.
rightContentReact.FC<{ breakpoint: 'small' | 'medium' | 'large' }>Component rendered on the right side of the header.
position'sticky' | 'relative'Specifies the positioning of the header.

Resources

Install

yarn add @camp/page-header

Left Content & Right Content

Being that the PageHeader is merely a container with some padding, the left and right content can be any component. The example above shows a Flex component with a Text component and a TabLists component on the left side and a Button component on the right side.

Here’s another example rendering Breadcrumbs:

Loading...

import { PageHeader } from '@camp/page-header'; import { LeftContentWithBreadcrumbs } from './LeftContentWithBreadcrumbs.tsx'; import { RightContent } from './RightContent.tsx'; <PageHeader leftContent={LeftContentWithBreadcrumbs} rightContent={RightContent} />;
// LeftContentWithBreadcrumbs.tsx import Flex from '@activecampaign/camp-components-flex'; import { Breadcrumbs, CrumbType } from '@camp/breadcrumbs'; import { IconButton } from '@camp/icon-button'; import { PencilEditSmall } from '@camp/icon'; const crumbs: CrumbType[] = [ { as: 'a', children: 'First Crumb', href: 'https://www.activecampaign.com/' }, { as: 'a', children: 'Second Crumb', href: 'https://www.activecampaign.com/', }, { as: 'a', children: 'Third Crumb', href: 'https://www.activecampaign.com/' }, { as: 'a', children: 'Fourth Crumb', href: 'https://www.activecampaign.com/' }, { as: 'button', children: 'Fifth Crumb' }, { as: 'button', children: 'Sixth Crumb' }, ]; export const LeftContentWithBreadcrumbs = () => { return ( <Flex gap="sp200" alignItems="center"> <Breadcrumbs crumbs={crumbs} currentPage="New Campaign" /> <IconButton appearance="floating"> <PencilEditSmall title="title" /> </IconButton> </Flex> ); };
// RightContent.tsx import Button from '@activecampaign/camp-components-button'; import { IconButton } from '@camp/icon-button'; import { MoreMenuMedium } from '@camp/icon'; export const RightContent = ({ breakpoint }) => { switch (breakpoint) { case 'small': return ( <div> <IconButton> <MoreMenuMedium title="title" /> </IconButton> </div> ); default: return ( <div> <Button>Button</Button> </div> ); } };

Responsive Breakpoints

The breakpoint argument passed to the leftContent and rightContent components can be used to render different content based on the screen size. A clean way to do this can be to use a switch statement to render different content based on the breakpoint case:

const RightContent = ({ breakpoint }) => { switch (breakpoint) { case 'small': return ( <div style={{ display: 'flex', alignItems: 'center', gap: '12px' }}> <IconButton> <MoreMenuMedium title="title" /> </IconButton> </div> ); case 'medium': return ( <div style={{ display: 'flex', gap: '12px', alignItems: 'center', justifyContent: 'center' }} > <Text type="body">Saved 7 minutes ago</Text> <PageHeaderPipeSeparator /> <IconButton> <MoreMenuMedium title="title" /> </IconButton> <Button>Send now</Button> </div> ); default: return ( <div style={{ display: 'flex', gap: '12px', alignItems: 'center', justifyContent: 'center' }} > <Text type="body">Saved 7 minutes ago</Text> <PageHeaderPipeSeparator /> <Button appearance="text">Test and preview</Button> <Button appearance="secondary">Save and exit</Button> <Button>Send now</Button> </div> ); } };

Position

The PageHeader component has a position prop that can be set to sticky or relative. By default, the position prop is set to sticky.


Sticky Page Header Example:


import { PageHeader } from '@camp/page-header'; import { LeftContent } from './LeftContent.tsx'; import { RightContent } from './RightContent.tsx'; <PageHeader position="sticky" leftContent={LeftContent} rightContent={RightContent} />;

Relative Page Header Example:


import { PageHeader } from '@camp/page-header'; import { LeftContent } from './LeftContent.tsx'; import { RightContent } from './RightContent.tsx'; <PageHeader position="relative" leftContent={LeftContent} rightContent={RightContent} />;
Last updated on