Shared/SectionHeading
As H3
As H4
Default
Long Title
Multiple Headings
With Subtitle
section-heading.tsx
import { Link } from '@/components/shared/link';
import { ArrowRight } from '@/components/svg';
type HeadingLevel = 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
interface SectionHeadingProps {
title: string;
titleSub?: string;
as?: HeadingLevel;
className?: string;
linkHref?: string;
linkText?: string;
}
export const SectionHeading = ({
title,
titleSub,
as: Tag = 'h2',
className,
linkHref,
linkText = '一覧',
}: SectionHeadingProps) => {
return (
<Tag className={`font-futura font-bold text-lg xl:text-xl pb-vgap-md ${className ?? ''}`}>
<span className={'block mb-vgap-sm h-1px bg-linear-to-r from-zd-white to-zd-black'}></span>
<span className="flex items-center">
<span className="grow">
<span lang="en">{title}</span>
{titleSub && (
<>
{' '}
/ <span className="text-[.75em]">{titleSub}</span>
</>
)}
</span>
{linkHref && (
<Link
to={linkHref}
className="flex text-sm font-futura xl:text-base zd-invert-color-link"
>
<ArrowRight aria-hidden="true" className="w-[18px] lg:w-[24px]" />
<span className="whitespace-nowrap pl-[4px] md:pl-[7px]">{linkText}</span>
</Link>
)}
</span>
</Tag>
);
};
section-heading.stories.tsx
import { SectionHeading } from './section-heading';
import type { ControlsMap } from '../../sub-packages/styleguide-v2/src/data/control-types';
/**
* SectionHeading Component
*
* A heading with a gradient border line above the text.
* Used for section titles across the site.
*
* Features:
* - Gradient border from white to black above the heading
* - Configurable heading level via `as` prop (h2–h6)
* - Optional subtitle separated by " / "
* - Futura font with bold weight
*/
export const meta = {
title: 'Shared/SectionHeading',
};
export const controls: ControlsMap = {
title: { type: 'text', default: 'PRODUCTS' },
titleSub: { type: 'text', default: '' },
as: { type: 'select', default: 'h2', options: ['h2', 'h3', 'h4', 'h5', 'h6'] },
};
/**
* Default - h2 heading with title only
*/
export const Default = {
args: { title: 'PRODUCTS', titleSub: '', as: 'h2' },
render: ({ title, titleSub, as: headingAs }: { title: string; titleSub: string; as: string }) => (
<SectionHeading
title={title}
titleSub={titleSub || undefined}
as={headingAs as 'h2' | 'h3' | 'h4' | 'h5' | 'h6'}
/>
),
};
/**
* With subtitle text
*/
export const WithSubtitle = () => <SectionHeading title="GUIDES" titleSub="ガイド" />;
/**
* Rendered as h3
*/
export const AsH3 = () => <SectionHeading title="LATEST ARTICLES" titleSub="最新記事" as="h3" />;
/**
* Rendered as h4
*/
export const AsH4 = () => <SectionHeading title="RELATED" titleSub="関連情報" as="h4" />;
/**
* Long title text
*/
export const LongTitle = () => (
<SectionHeading
title="MODULAR SYNTHESIZER BEGINNERS GUIDE"
titleSub="モジュラーシンセサイザー入門ガイド"
/>
);
/**
* Multiple headings stacked to show visual hierarchy
*/
export const MultipleHeadings = () => (
<div className="flex flex-col gap-vgap-lg">
<SectionHeading title="SECTION ONE" titleSub="セクション1" as="h2" />
<SectionHeading title="SECTION TWO" titleSub="セクション2" as="h3" />
<SectionHeading title="SECTION THREE" titleSub="セクション3" as="h4" />
</div>
);