Skip to content

Page Header

ComponentMantine ≥ 9

Page title, description and right-aligned action slot with an optional divider.

Install

One command copies the item's source into your project, where you own and edit it.

Terminal window
npx manteen add @house/page-header

Dependencies

  • @mantine/core@^9npm

Preview

Usage

A copy-ready example published by the registry author. Imports use the aliases Manteen configures at init.

page-header.usage.tsx
import { Button } from "@mantine/core";
import { PageHeader } from "@/components/ui/page-header";
export function ProjectSettingsHeader() {
return (
<PageHeader
title="Project settings"
description="Manage members, billing, and integrations for this project."
actions={
<Button variant="default" onClick={() => console.log("invite clicked")}>
Invite member
</Button>
}
/>
);
}

Props

Author-documented props, carried verbatim from the registry item.

PropTypeDefaultDescription
title*stringRenders as the header's order-2 title text.
descriptionReactNodeRenders dimmed helper text beneath the title when provided.
actionsReactNodeRenders action controls in a trailing group aligned opposite the title.
withDividerbooleantrueControls whether a divider is rendered beneath the header content.
...othersBoxProps & ElementProps<"div", "title">All other props are forwarded to the root <Stack>, so passthrough props can override its hardcoded gap/mb. Mantine Styles API props (classNames, styles, unstyled) are also accepted.

* required

Styling

PageHeader exposes these parts through the public classNames/styles interface:

  • root
  • header
  • titleWrapper
  • title
  • description
  • actions
  • divider

Author-declared; Manteen reports the declaration but does not verify each selector is wired.

Source

2 installable files ship with this item.

registry/ui/page-header.tsxcomponent · 2.3 kB · tsx
import {
type BoxProps,
Divider,
type ElementProps,
type Factory,
factory,
Group,
Stack,
type StylesApiProps,
Text,
Title,
useProps,
useStyles,
} from "@mantine/core";
import type { ReactNode } from "react";
import classes from "./page-header.module.css";
export type PageHeaderStylesNames =
| "root"
| "header"
| "titleWrapper"
| "title"
| "description"
| "actions"
| "divider";
export interface PageHeaderProps
extends BoxProps,
StylesApiProps<PageHeaderFactory>,
ElementProps<"div", "title"> {
title: string;
description?: ReactNode;
actions?: ReactNode;
withDivider?: boolean;
}
export type PageHeaderFactory = Factory<{
props: PageHeaderProps;
ref: HTMLDivElement;
stylesNames: PageHeaderStylesNames;
}>;
export const PageHeader = factory<PageHeaderFactory>((_props) => {
const props = useProps("PageHeader", null, _props);
const {
classNames,
className,
style,
styles,
unstyled,
vars,
attributes,
ref,
title,
description,
actions,
withDivider = true,
...others
} = props;
const getStyles = useStyles<PageHeaderFactory>({
name: "PageHeader",
classes,
props,
className,
style,
classNames,
styles,
unstyled,
attributes,
vars,
});
return (
<Stack ref={ref} gap="sm" mb="lg" unstyled={unstyled} {...getStyles("root")} {...others}>
<Group justify="space-between" align="flex-start" wrap="nowrap" {...getStyles("header")}>
<Stack gap={4} {...getStyles("titleWrapper")}>
<Title order={2} {...getStyles("title")}>
{title}
</Title>
{description && (
<Text c="dimmed" size="sm" {...getStyles("description")}>
{description}
</Text>
)}
</Stack>
{actions && (
<Group gap="xs" {...getStyles("actions")}>
{actions}
</Group>
)}
</Group>
{withDivider && <Divider {...getStyles("divider")} />}
</Stack>
);
});
PageHeader.classes = classes;
PageHeader.displayName = "PageHeader";
export namespace PageHeader {
export type Props = PageHeaderProps;
export type StylesNames = PageHeaderStylesNames;
export type Factory = PageHeaderFactory;
}
registry/ui/page-header.module.cssstyle · 813 B · css
/*
* PageHeader's Styles API selectors. None of them carry default visual
* styling of their own — every layout property (gap, spacing, alignment,
* wrap) is set via Mantine style props directly on each element, exactly as
* it was before this file existed. Each rule below only declares an unused
* custom property (no visual effect) so the selector has a real class in
* this stylesheet to anchor to; the classes exist purely as override
* targets for instance classNames/styles and theme .extend.
*/
.root {
--page-header-root: 1;
}
.header {
--page-header-header: 1;
}
.titleWrapper {
--page-header-title-wrapper: 1;
}
.title {
--page-header-title: 1;
}
.description {
--page-header-description: 1;
}
.actions {
--page-header-actions: 1;
}
.divider {
--page-header-divider: 1;
}