mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2026-07-30 18:40:19 +00:00
- Introduced new styles for the CardsTwoColumn pattern, including responsive layouts and various card designs. - Updated the xrpl.scss file to import the new CardsTwoColumn styles, ensuring they are included in the overall styling framework.
118 lines
4.2 KiB
TypeScript
118 lines
4.2 KiB
TypeScript
import React from 'react';
|
|
import clsx from 'clsx';
|
|
import { TextCard, TextCardProps } from './TextCard';
|
|
|
|
/**
|
|
* Configuration for a card in the CardsTwoColumn pattern
|
|
*/
|
|
export type CardsTwoColumnCardConfig = TextCardProps;
|
|
|
|
/**
|
|
* Props for the CardsTwoColumn pattern component
|
|
*/
|
|
export interface CardsTwoColumnProps extends Omit<React.ComponentPropsWithoutRef<'section'>, 'title'> {
|
|
/** Section title (heading-md typography) */
|
|
title: React.ReactNode;
|
|
/** Section description text (body-l typography, muted color) */
|
|
description?: React.ReactNode;
|
|
/** Secondary description paragraph (body-l typography, muted color) */
|
|
secondaryDescription?: React.ReactNode;
|
|
/** Array of 4 card configurations for the 2x2 grid */
|
|
cards: readonly [CardsTwoColumnCardConfig, CardsTwoColumnCardConfig, CardsTwoColumnCardConfig, CardsTwoColumnCardConfig];
|
|
}
|
|
|
|
/**
|
|
* CardsTwoColumn Pattern Component
|
|
*
|
|
* A section pattern that displays a header with title/description and a 2x2 grid
|
|
* of TextCard components. Follows the "Section Cards - Two Column" design from Figma.
|
|
*
|
|
* Structure:
|
|
* - Header: Title (left) + Description (right) on desktop, stacked on tablet/mobile
|
|
* - Cards: 2x2 grid on desktop, single column stacked on tablet/mobile
|
|
*
|
|
* Responsive behavior:
|
|
* - Desktop (≥992px):
|
|
* - Header: Title left, description right (flex row)
|
|
* - Cards: 2x2 grid (2 columns, 2 rows)
|
|
* - Section padding: 40px vertical, 32px horizontal
|
|
* - Gap between header and cards: 40px
|
|
* - Gap between cards: 8px
|
|
*
|
|
* - Tablet (576-991px):
|
|
* - Header: Stacked (title above description)
|
|
* - Cards: Single column, stacked vertically
|
|
* - Section padding: 32px vertical, 24px horizontal
|
|
* - Gap between header and cards: 32px
|
|
* - Gap between cards: 8px
|
|
*
|
|
* - Mobile (<576px):
|
|
* - Header: Stacked (title above description)
|
|
* - Cards: Single column, stacked vertically
|
|
* - Section padding: 24px vertical, 16px horizontal
|
|
* - Gap between header and cards: 24px
|
|
* - Gap between cards: 8px
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* <CardsTwoColumn
|
|
* title="The Future of Finance is Already Onchain"
|
|
* description="XRP Ledger isn't about bold predictions. It's about delivering value now."
|
|
* secondaryDescription="On XRPL, you're not waiting for the future. You're building it."
|
|
* cards={[
|
|
* { title: "Institutions", description: "Banks, asset managers...", color: "lilac" },
|
|
* { title: "Developers", description: "Build decentralized...", color: "neutral-light" },
|
|
* { title: "Enterprise", description: "Scale your business...", color: "neutral-dark" },
|
|
* { title: "Community", description: "Join the global...", color: "green" }
|
|
* ]}
|
|
* />
|
|
* ```
|
|
*/
|
|
export const CardsTwoColumn = React.forwardRef<HTMLElement, CardsTwoColumnProps>(
|
|
(props, ref) => {
|
|
const { title, description, secondaryDescription, cards, className, ...rest } = props;
|
|
|
|
if (cards.length !== 4) {
|
|
console.warn('CardsTwoColumn: Exactly 4 cards are required');
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<section
|
|
ref={ref}
|
|
className={clsx('bds-cards-two-column', className)}
|
|
{...rest}
|
|
>
|
|
<div className="bds-cards-two-column__container">
|
|
{/* Header Section */}
|
|
<div className="bds-cards-two-column__header">
|
|
<div className="bds-cards-two-column__header-left">
|
|
<h2 className="bds-cards-two-column__title h-md">{title}</h2>
|
|
</div>
|
|
{(description || secondaryDescription) && (
|
|
<div className="bds-cards-two-column__header-right">
|
|
<div className="bds-cards-two-column__description body-l">
|
|
{description && <p>{description}</p>}
|
|
{secondaryDescription && <p>{secondaryDescription}</p>}
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
{/* Cards Grid - 2x2 on desktop, stacked on tablet/mobile */}
|
|
<div className="bds-cards-two-column__cards">
|
|
{cards.map((card, index) => (
|
|
<TextCard key={index} {...card} />
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
);
|
|
|
|
CardsTwoColumn.displayName = 'CardsTwoColumn';
|
|
|
|
export default CardsTwoColumn;
|
|
|