Brand
Section heading
Eyebrow, framed display title and a line of lead.
stablev0.1.0 Chromium 103 ui-scale safe
Install
Copies the file into
components/ds/, with its registry dependencies and npm packages. See Installation for the one-time setup.bunx shadcn@3 add @fastrp/section-headingExamples
Default
Sezon 3
Kendi hikâyeni yaz
Bir meslek seç, bir çeteye katıl ya da kendi işini kur. Şehir senin yaptıklarınla şekillenir.
Fast Roleplay
API
<SectionHeading />The heading a section opens with: a small eyebrow, the title in the display voice framed by corner ticks, and an optional line of description. Wrap a word of the title in `<em>` to set it in the accent.
| Prop | Type | Default | Notes |
|---|---|---|---|
| title* | ReactNode | — | |
| align | "center" | "start" | start | |
| as | "h1" | "h2" | "h3" | h2 | |
| className | string | — | |
| description | ReactNode | — | |
| eyebrow | ReactNode | — | |
| framed | boolean | true | Frame the title in corner ticks. On by default — the brand's heading. |
| size | "sm" | "md" | "lg" | "xl" | — | |
| variant | "outline" | "solid" | — |
Dependencies
npm
- class-variance-authority@^0.7.1
Registry
- @fastrp/bracketed
- @fastrp/utils
Source
components/ds/section-heading.tsxShowHide
import { cva, type VariantProps } from 'class-variance-authority';
import type { ReactNode } from 'react';
import { Bracketed } from '@/components/ds/bracketed';
import { cn } from '@/lib/utils';
// @fast-ds [email protected]
const titleVariants = cva(
// `em` inside a title is the brand emphasis: upright, in the accent — never italic.
'font-display text-foreground [&_em]:not-italic [&_em]:text-brand',
{
variants: {
size: {
sm: 'text-3xl md:text-4xl',
md: 'text-4xl md:text-6xl',
lg: 'text-5xl md:text-display-2',
xl: 'text-5xl md:text-7xl lg:text-display-1',
},
variant: {
solid: '',
/** The web site's outlined twin: a stroke and no fill. */
outline: 'text-outline',
},
},
defaultVariants: { size: 'md', variant: 'solid' },
},
);
export type SectionHeadingProps = VariantProps<typeof titleVariants> & {
title: ReactNode;
eyebrow?: ReactNode;
description?: ReactNode;
/** Frame the title in corner ticks. On by default — the brand's heading. */
framed?: boolean;
align?: 'start' | 'center';
as?: 'h1' | 'h2' | 'h3';
className?: string;
};
/**
* The heading a section opens with: a small eyebrow, the title in the display voice framed by
* corner ticks, and an optional line of description. Wrap a word of the title in `<em>` to set it
* in the accent.
*/
export function SectionHeading({
title,
eyebrow,
description,
framed = true,
align = 'start',
as: Heading = 'h2',
size,
variant,
className,
}: SectionHeadingProps) {
const heading = (
<Heading className={cn(titleVariants({ size, variant }), 'leading-[0.95]')}>{title}</Heading>
);
return (
<div
className={cn(
'flex flex-col gap-4',
align === 'center' && 'items-center text-center',
className,
)}
>
{eyebrow && <span className="text-eyebrow uppercase text-muted-foreground">{eyebrow}</span>}
{framed ? <Bracketed>{heading}</Bracketed> : heading}
{description && (
<p className="max-w-2xl text-base leading-relaxed text-muted-foreground md:text-lg">
{description}
</p>
)}
</div>
);
}