125 lines
3.6 KiB
TypeScript
125 lines
3.6 KiB
TypeScript
import { cn } from "@/lib/utils";
|
|
import {
|
|
BgColorName,
|
|
bgColors,
|
|
sidePlacements,
|
|
VerticalPlacementName,
|
|
verticalPlacements,
|
|
} from "@/front/lib/constants";
|
|
import { ButtonProps, IconConfig, TextProps } from "@/types/front";
|
|
import { forwardRef, ReactNode } from "react";
|
|
import Container from "./Container";
|
|
import Button from "./Button";
|
|
import { Link } from "@inertiajs/react";
|
|
|
|
export type ButtonSectionProps = ButtonProps & {
|
|
/** Button vertical placement (top or bottom). Default: bottom */
|
|
placement?: VerticalPlacementName;
|
|
icon?: IconConfig;
|
|
};
|
|
|
|
type Props = {
|
|
variant?: BgColorName;
|
|
title?: TextProps;
|
|
subtitle?: TextProps;
|
|
description?: TextProps;
|
|
children: ReactNode;
|
|
className?: string;
|
|
containerClassName?: string;
|
|
button?: ButtonSectionProps;
|
|
};
|
|
const Section = forwardRef<HTMLDivElement, Props>((props, ref) => {
|
|
const {
|
|
variant = bgColors.BACKGROUND,
|
|
title,
|
|
subtitle,
|
|
description,
|
|
children,
|
|
className,
|
|
button,
|
|
containerClassName,
|
|
} = props;
|
|
const btnVariant = variant === bgColors.BACKGROUND ? "default" : "inverted";
|
|
const btnPlacement =
|
|
(button && button.placement) ?? verticalPlacements.BOTTOM;
|
|
return (
|
|
<section ref={ref} className={cn(variant, "text-center py-20", className)}>
|
|
<Container className={cn(containerClassName)}>
|
|
{btnPlacement === verticalPlacements.TOP && button && (
|
|
<div className="mb-10">
|
|
<Button
|
|
variant={btnVariant}
|
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
{...(button.icon && {
|
|
icon: {
|
|
icon: button.icon.icon,
|
|
placement: button.icon.placement ?? sidePlacements.RIGHT,
|
|
},
|
|
})}
|
|
asChild
|
|
>
|
|
<Link href={button.href}>{button.label}</Link>
|
|
</Button>
|
|
</div>
|
|
)}
|
|
{(title || subtitle || description) && (
|
|
<Container className={cn("space-y-5 mb-16")}>
|
|
{title && (
|
|
<h2
|
|
className={cn(
|
|
"text-3xl md:text-5xl max-w-5xl mx-auto uppercase",
|
|
title.font,
|
|
title.weight ?? "font-bold",
|
|
)}
|
|
>
|
|
{title.text}
|
|
</h2>
|
|
)}
|
|
{subtitle && (
|
|
<h3
|
|
className={cn(
|
|
"text-2xl md:text-3xl mx-auto max-w-2xl uppercase",
|
|
subtitle.font,
|
|
subtitle.weight ?? "font-bold",
|
|
)}
|
|
>
|
|
{subtitle.text}
|
|
</h3>
|
|
)}
|
|
{description && (
|
|
<p
|
|
className={cn(
|
|
"mx-auto max-w-3xl",
|
|
description.font,
|
|
description.weight ?? "font-normal",
|
|
)}
|
|
>
|
|
{description.text}
|
|
</p>
|
|
)}
|
|
</Container>
|
|
)}
|
|
<div>{children}</div>
|
|
{btnPlacement === verticalPlacements.BOTTOM && button && (
|
|
<div className="mt-16">
|
|
<Button
|
|
variant={btnVariant}
|
|
link={{
|
|
href: button.href,
|
|
label: button.label,
|
|
}}
|
|
// eslint-disable-next-line react/jsx-props-no-spreading
|
|
{...(button.icon && {
|
|
icon: {
|
|
icon: button.icon.icon,
|
|
placement: button.icon.placement ?? sidePlacements.RIGHT,
|
|
},
|
|
})}
|
|
/>
|
|
</div>
|
|
)}
|
|
</Container>
|
|
</section>
|
|
);
|
|
});
|
|
export default Section;
|