FoundationsTypography
Heading component
Installation
npx shadcn@latest add @caprice/headingnpm install @caprice-ui/reactInstall the following dependencies:
npm install @base-ui/react lucide-reactAdd a cn helper
import { defineConfig, type VariantProps } from 'cva';import { twMerge } from 'tailwind-merge';export const { compose, cva, cx: cn,} = defineConfig({ hooks: { onComplete: (className: string) => twMerge(className), },});export type { VariantProps };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 typographyexport const headingVariants = cva({ base: 'scroll-m-20', 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), });}