Typography provides Heading and Text primitives aligned to the design
token contract (text-h*, text-p-*, text-caption, text-mono).
When to use
- Render semantic headings and body text with consistent scale.
- Keep docs/app content aligned with typography tokens across themes.
- Use convenience shortcuts (
Heading.H2,Text.PSm,Text.Caption, etc.) for common content structures.
Components
Heading- base:
Headingwithas='h1' ... 'h6' - shortcuts:
Heading.H1throughHeading.H6
- base:
Text- base:
Textwithvariant='body' | 'body-lg' | 'body-sm' | 'mini' | 'caption' | 'mono' - shortcuts:
Text.P,Text.PLg,Text.PSm,Text.PMini,Text.Caption,Text.Mono
- base:
Behavior notes
Headingapplies semantic heading tags and heading token classes.Textdefaults to paragraph semantics for body-like variants.captionandmonovariants render as inline text by default.- Override element tags with
aswhen semantic context requires it.
Example
<div className='space-y-2'>
<Heading.H2>Usage analytics</Heading.H2>
<Text.PSm className='text-muted-foreground'>
Last updated 5 minutes ago.
</Text.PSm>
<Text.Caption>Experimental</Text.Caption>
</div>
Preview
heading 1
heading 2
heading 3
heading 4
heading 5
heading 6
monospacedbody large
body large
body large medium
body large bold
paragraph regular
paragraph medium
paragraph bold
paragraph small
paragraph small medium
paragraph small bold
paragraph mini
CaptionUsage
import { Heading, Text } from '@branditdev/ui';
export function TypographyDemo() {
return (
<div className='flex flex-col gap-8'>
<Heading.H1>heading 1</Heading.H1>
{/* <Heading as='h1'>heading 1</Heading> */}
<Heading.H2>heading 2</Heading.H2>
{/* <Heading as='h2'>heading 2</Heading> */}
<Heading.H3>heading 3</Heading.H3>
{/* <Heading as='h3'>heading 3</Heading> */}
<Heading.H4>heading 4</Heading.H4>
{/* <Heading as='h4'>heading 4</Heading> */}
<Heading.H5>heading 5</Heading.H5>
{/* <Heading as='h5'>heading 5</Heading> */}
<Heading.H6>heading 6</Heading.H6>
{/* <Heading as='h6'>heading 6</Heading> */}
<Text.Mono>monospaced</Text.Mono>
{/* <Text variant='mono'>monospaced</Text> */}
<Text.PLg>body large</Text.PLg>
{/* <Text variant='body-lg'>body large</Text> */}
<Text.PLg>body large</Text.PLg>
<Text.PLg className='font-medium'>body large medium</Text.PLg>
<Text.PLg className='font-bold'>body large bold</Text.PLg>
<Text.P>paragraph regular</Text.P>
{/* <Text variant='body'>paragraph regular</Text> */}
<Text.P className='font-medium'>paragraph medium</Text.P>
<Text.P className='font-bold'>paragraph bold</Text.P>
<Text.PSm>paragraph small</Text.PSm>
{/* <Text variant='body-sm'>paragraph small</Text> */}
<Text.PSm className='font-medium'>paragraph small medium</Text.PSm>
<Text.PSm className='font-bold'>paragraph small bold</Text.PSm>
<Text.PMini>paragraph mini</Text.PMini>
{/* <Text variant='mini'>paragraph mini</Text> */}
<Text.Caption>Caption</Text.Caption>
{/* <Text variant='caption'>Caption</Text> */}
</div>
);
}
API
constHeading: (props) =>Element&object
Defined in: components/typography/typography.tsx:141
Compound heading API with base primitive and convenience heading levels.
Includes Heading.H1 through Heading.H6 shortcuts.
Type Declaration
H1()
H1: (
props) =>Element
Parameters
props
DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>>
Returns
Element
H2()
H2: (
props) =>Element
Parameters
props
DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>>
Returns
Element
H3()
H3: (
props) =>Element
Parameters
props
DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>>
Returns
Element
H4()
H4: (
props) =>Element
Parameters
props
DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>>
Returns
Element
H5()
H5: (
props) =>Element
Parameters
props
DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>>
Returns
Element
H6()
H6: (
props) =>Element
Parameters
props
DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>>
Returns
Element
Source
import type { ComponentProps, HTMLAttributes } from 'react';
import { cn } from '@branditdev/ui';
type HeadingTag = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
type TextTag =
| 'p'
| 'span'
| 'pre'
| 'code'
| 'ul'
| 'ol'
| 'li'
| 'blockquote';
type TextVariant = 'body' | 'body-lg' | 'body-sm' | 'mini' | 'caption' | 'mono';
const headingClassMap: Record<HeadingTag, string> = {
h1: 'text-h1',
h2: 'text-h2',
h3: 'text-h3',
h4: 'text-h4',
h5: 'text-h5',
h6: 'text-h6',
};
const textClassMap: Record<TextVariant, string> = {
body: 'text-p-base',
'body-lg': 'text-p-lg',
'body-sm': 'text-p-sm',
mini: 'text-p-mini',
caption: 'text-caption uppercase',
mono: 'text-mono font-mono',
};
export type HeadingProps = ComponentProps<'h1'> & {
as?: HeadingTag;
};
export type TextProps = HTMLAttributes<HTMLElement> & {
as?: TextTag;
variant?: TextVariant;
};
function HeadingComponent({
as = 'h1',
children,
className,
...props
}: HeadingProps) {
const Tag = as;
return (
<Tag
className={cn(
'scroll-m-20 font-heading text-balance',
headingClassMap[as],
className
)}
{...props}
>
{children}
</Tag>
);
}
function TextComponent({
as,
variant = 'body',
children,
className,
...props
}: TextProps) {
const Tag =
as || (variant === 'caption' || variant === 'mono' ? 'span' : 'p');
return (
<Tag
className={cn('text-balance', textClassMap[variant], className)}
{...props}
>
{children}
</Tag>
);
}
const H1 = (props: ComponentProps<'h1'>) => (
<HeadingComponent as='h1' {...props} />
);
const H2 = (props: ComponentProps<'h2'>) => (
<HeadingComponent as='h2' {...props} />
);
const H3 = (props: ComponentProps<'h3'>) => (
<HeadingComponent as='h3' {...props} />
);
const H4 = (props: ComponentProps<'h4'>) => (
<HeadingComponent as='h4' {...props} />
);
const H5 = (props: ComponentProps<'h5'>) => (
<HeadingComponent as='h5' {...props} />
);
const H6 = (props: ComponentProps<'h6'>) => (
<HeadingComponent as='h6' {...props} />
);
const P = (props: ComponentProps<'p'>) => (
<TextComponent variant='body' {...props} />
);
const PLg = (props: ComponentProps<'p'>) => (
<TextComponent variant='body-lg' {...props} />
);
const PSm = (props: ComponentProps<'p'>) => (
<TextComponent variant='body-sm' {...props} />
);
const PMini = (props: ComponentProps<'p'>) => (
<TextComponent variant='mini' {...props} />
);
const Caption = (props: ComponentProps<'span'>) => (
<TextComponent as='span' variant='caption' {...props} />
);
const Mono = (props: ComponentProps<'code'>) => (
<TextComponent as='code' variant='mono' {...props} />
);
export const Heading = Object.assign(HeadingComponent, {
H1,
H2,
H3,
H4,
H5,
H6,
});
export const Text = Object.assign(TextComponent, {
P,
PLg,
PSm,
PMini,
Caption,
Mono,
});