Files
portfolio/src/entities/Section/ui/SectionPanel/SectionPanel.tsx
T

67 lines
1.7 KiB
TypeScript

import Link from 'next/link';
import type { ReactNode } from 'react';
import { ViewTransitionWrapper } from '$shared/ui';
interface SectionPanelProps {
/**
* Display number prefix (e.g. "01")
*/
number: string;
/**
* Section title
*/
title: string;
/**
* HTML id for anchor navigation
*/
id: string;
/**
* Whether this section is expanded
*/
isActive: boolean;
/**
* Navigation URL for the collapsed heading link
*/
href: string;
/**
* Section content, shown when active
*/
children: ReactNode;
}
/**
* Accordion-style section that collapses to a navigation link when inactive.
*/
export function SectionPanel({ number, title, id, isActive, href, children }: SectionPanelProps) {
const heading = `${number}. ${title}`;
return (
<section id={id} className="scroll-mt-8">
{isActive ? (
<div className="mb-section-gap">
<ViewTransitionWrapper name="section-title">
<div className="mb-section-gap">
<h1 className="font-heading font-black text-xl sm:text-section-title leading-[1.2] mb-0 py-0.5">
{heading}
</h1>
</div>
</ViewTransitionWrapper>
<ViewTransitionWrapper name="section-body">
<div>{children}</div>
</ViewTransitionWrapper>
</div>
) : (
<Link
href={href}
aria-label={heading}
className="block w-full text-left text-xl sm:text-nav-title py-0.5 group border-b-0 hover:border-b-0"
>
<span className="block font-heading font-wonk font-black opacity-30 group-hover:opacity-60 transition-opacity duration-200">
{heading}
</span>
</Link>
)}
</section>
);
}