mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2026-07-31 19:10:17 +00:00
Component Library Refactor & New Components (#3510)
* 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
This commit is contained in:
committed by
Calvin Jhunjhuwala
parent
fe1aa0ecb1
commit
176fb3cbc7
50
shared/patterns/SectionHeader/SectionHeader.scss
Normal file
50
shared/patterns/SectionHeader/SectionHeader.scss
Normal file
@@ -0,0 +1,50 @@
|
||||
// BDS SectionHeader Pattern Styles
|
||||
// Brand Design System - Consolidated section header (heading + description)
|
||||
//
|
||||
// Naming Convention: BEM with 'bds' namespace
|
||||
// .bds-section-header - Header wrapper for heading and description
|
||||
// .bds-section-header__heading - Section heading (uses .h-md)
|
||||
// .bds-section-header__description - Section description (uses .body-l)
|
||||
//
|
||||
// Design tokens from _spacing.scss:
|
||||
// - Gap between heading and description: $bds-gap-header-*
|
||||
// - Light/Dark mode colors: $black / $white
|
||||
|
||||
// =============================================================================
|
||||
// Header Section
|
||||
// =============================================================================
|
||||
|
||||
.bds-section-header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $bds-gap-header-sm;
|
||||
margin-bottom: $bds-gap-section-sm;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
gap: $bds-gap-header-md;
|
||||
margin-bottom: $bds-gap-section-md;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
gap: $bds-gap-header-lg;
|
||||
margin-bottom: $bds-gap-section-lg;
|
||||
}
|
||||
|
||||
@include bds-theme-mode(light) {
|
||||
color: $black;
|
||||
}
|
||||
|
||||
@include bds-theme-mode(dark) {
|
||||
color: $white;
|
||||
}
|
||||
}
|
||||
|
||||
.bds-section-header__heading {
|
||||
margin: 0;
|
||||
// Typography handled by .h-md class from _font.scss
|
||||
}
|
||||
|
||||
.bds-section-header__description {
|
||||
margin: 0;
|
||||
// Typography handled by .body-l class from _font.scss
|
||||
}
|
||||
111
shared/patterns/SectionHeader/SectionHeader.tsx
Normal file
111
shared/patterns/SectionHeader/SectionHeader.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
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;
|
||||
1
shared/patterns/SectionHeader/index.ts
Normal file
1
shared/patterns/SectionHeader/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { SectionHeader, type SectionHeaderProps } from './SectionHeader';
|
||||
Reference in New Issue
Block a user