mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2026-04-29 15:37:48 +00:00
* adding showcase page * adding CardStatsList * clean up, tighter code * code review and code clean up * update import, clean up env for error message * tweak some css code * less css, rebuilt * re-adding bem, modifier for bds variants
112 lines
3.2 KiB
TypeScript
112 lines
3.2 KiB
TypeScript
import React from 'react';
|
|
import clsx from 'clsx';
|
|
import { PageGrid } from '../../components/PageGrid/page-grid';
|
|
import type { ResponsiveValue, PageGridSpanValue } from '../../components/PageGrid/page-grid';
|
|
import { isEnvironment } from '../../utils/helpers';
|
|
|
|
const DEFAULT_SPAN = {
|
|
base: 'fill' as const,
|
|
md: 6,
|
|
lg: 8,
|
|
};
|
|
|
|
export interface SectionHeaderProps {
|
|
/** Section heading text */
|
|
heading?: React.ReactNode;
|
|
/** Section description text */
|
|
description?: React.ReactNode;
|
|
/** Polymorphic heading element - h1 through h6 */
|
|
as?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
|
|
/** PageGrid.Col span - defaults to { base: 'fill', md: 6, lg: 8 } */
|
|
span?: ResponsiveValue<PageGridSpanValue>;
|
|
/** Optional slot for trailing content (e.g. ButtonGroup) */
|
|
children?: React.ReactNode;
|
|
/** Additional CSS classes for the header wrapper */
|
|
className?: string;
|
|
}
|
|
|
|
/**
|
|
* SectionHeader - Consolidated section header pattern
|
|
*
|
|
* Renders a PageGrid.Row + Col with heading (polymorphic h1-h6) and optional description.
|
|
* Used across CardsFeatured, StandardCardGroupSection, CardsIconGrid, and other sections.
|
|
*
|
|
* **Behavior:**
|
|
* - Returns `null` if no content is provided (no heading, description, or children)
|
|
* - Logs a development warning when returning null to help catch missing props
|
|
* - At least one of `heading`, `description`, or `children` should be provided
|
|
*
|
|
* @example
|
|
* // Typical usage with heading and description
|
|
* <SectionHeader
|
|
* heading="Our Features"
|
|
* description="Explore what we offer"
|
|
* />
|
|
*
|
|
* @example
|
|
* // With custom heading level
|
|
* <SectionHeader
|
|
* heading="Main Title"
|
|
* as="h1"
|
|
* description="Subtitle text"
|
|
* />
|
|
*
|
|
* @example
|
|
* // With children (e.g., ButtonGroup)
|
|
* <SectionHeader heading="Products">
|
|
* <ButtonGroup buttons={[...]} />
|
|
* </SectionHeader>
|
|
*/
|
|
export const SectionHeader = React.forwardRef<HTMLDivElement, SectionHeaderProps>(
|
|
(props, ref) => {
|
|
const {
|
|
heading,
|
|
description,
|
|
as = 'h2',
|
|
span = DEFAULT_SPAN,
|
|
children,
|
|
className,
|
|
} = props;
|
|
|
|
const hasContent = heading || description || children;
|
|
if (!hasContent) {
|
|
if (isEnvironment(["development", "test"])) {
|
|
console.warn(
|
|
'SectionHeader: No content provided. Component requires at least one of: heading, description, or children. ' +
|
|
'Returning null - this may indicate a missing prop or data issue.'
|
|
);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
const HeadingTag = as;
|
|
|
|
return (
|
|
<PageGrid.Row>
|
|
<PageGrid.Col span={span}>
|
|
<div
|
|
ref={ref}
|
|
className={clsx('bds-section-header', className)}
|
|
>
|
|
{heading != null && heading !== '' && (
|
|
<HeadingTag className="bds-section-header__heading h-md">
|
|
{heading}
|
|
</HeadingTag>
|
|
)}
|
|
{description != null && description !== '' && (
|
|
<p className="bds-section-header__description body-l">
|
|
{description}
|
|
</p>
|
|
)}
|
|
{children}
|
|
</div>
|
|
</PageGrid.Col>
|
|
</PageGrid.Row>
|
|
);
|
|
}
|
|
);
|
|
|
|
SectionHeader.displayName = 'SectionHeader';
|
|
|
|
export default SectionHeader;
|