FoundationsTypography
Heading component
Installation
npx shadcn@latest add @caprice/headingpnpm dlx shadcn@latest add @caprice/headingyarn dlx shadcn@latest add @caprice/headingbunx shadcn@latest add @caprice/headingnpm install @caprice-ui/reactpnpm add @caprice-ui/reactyarn add @caprice-ui/reactbun add @caprice-ui/reactInstall the following dependencies:
npm install @base-ui/react lucide-reactpnpm add @base-ui/react lucide-reactyarn add @base-ui/react lucide-reactbun add @base-ui/react lucide-reactAdd a cn helper
import { defineConfig, getSchema, type VariantProps } from 'cva';
import { twMerge } from 'tailwind-merge';
export const { cva, cx: cn } = defineConfig({
hooks: {
onComplete: (className: string) => twMerge(className),
},
});
export type { VariantProps };
export { getSchema };
Copy and paste the following code into your project.
import { mergeProps } from '@base-ui/react/merge-props';
import { useRender } from '@base-ui/react/use-render';
import { createElement } from 'react';
import { cva, type VariantProps } from '@/lib/utils';
// TODO: Use fluid typography
export const headingVariants = cva({
base: 'wrap-break-word scroll-m-20 text-balance',
variants: {
/**
* Size
* @default 'xs'
*/
size: {
xs: 'text-xl/7',
sm: 'text-2xl',
md: 'text-[32px]/10 tracking-[-0.005em]',
lg: 'text-[40px]/12 tracking-[-0.005em]',
xl: 'text-5xl/[56px] tracking-[-0.012em]',
'2xl': 'text-[56px]/[64px] tracking-[-0.016em]',
},
/**
* Weight
* @default 'semibold'
*/
weight: {
regular: 'font-normal',
medium: 'font-medium',
semibold: 'font-semibold',
bold: 'font-bold',
},
},
defaultVariants: {
size: 'xs',
weight: 'semibold',
},
});
export interface HeadingVariants extends VariantProps<typeof headingVariants> {}
type HeadingTag = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
/**
* A heading element.
* Renders a `<h1>` to `<h6>` element.
*
* Documentation: [Caprice UI Heading](https://caprice-ui.com/docs/foundations/typography/heading)
*/
export namespace Heading {
export type Props = useRender.ComponentProps<HeadingTag> &
HeadingVariants & {
/**
* Shorthand for changing the level of the heading.
*
* Cannot be used in combination with `render`.
* @default 1 // => <h1>
*/
level?: 1 | 2 | 3 | 4 | 5 | 6;
};
}
export function Heading({
render,
size = 'md',
level = 1,
weight = 'regular',
className,
...props
}: Heading.Props) {
const Tag = render ?? createElement(`h${level}`);
const defaultProps: useRender.ElementProps<HeadingTag> & { 'data-slot'?: string } = {
'data-slot': 'heading',
className: headingVariants({
size,
weight,
className,
}),
};
return useRender({
defaultTagName: 'h1',
render: Tag,
props: mergeProps<HeadingTag>(defaultProps, props),
});
}
Update the import paths to match your project setup.
Usage
Examples
API Reference
Last updated on