mirror of
https://github.com/XRPLF/xrpl-dev-portal.git
synced 2026-09-27 15:37:57 +00:00
add new PanelStack component to replace CarouselFeatured component
This commit is contained in:
@@ -3,9 +3,9 @@ import { useThemeHooks } from "@redocly/theme/core/hooks";
|
||||
import { PageWrapper } from "shared/components/PageWrapper";
|
||||
import { HeaderHeroSplitMedia } from "shared/sections/HeaderHeroSplitMedia/HeaderHeroSplitMedia";
|
||||
import {
|
||||
CarouselFeatured,
|
||||
type CarouselSlide,
|
||||
} from "shared/patterns/CarouselFeatured/CarouselFeatured";
|
||||
PanelStack,
|
||||
type PanelStackPanel,
|
||||
} from "shared/patterns/PanelStack";
|
||||
import { LogoSquareGrid } from "shared/sections/LogoSquareGrid";
|
||||
import { LinkTextDirectory } from "shared/sections/LinkTextDirectory/LinkTextDirectory";
|
||||
import { FeatureSingleTopic } from "shared/sections/FeatureSingleTopic/FeatureSingleTopic";
|
||||
@@ -22,7 +22,7 @@ export default function Funding() {
|
||||
const { useTranslate } = useThemeHooks();
|
||||
const { translate } = useTranslate();
|
||||
|
||||
const carouselSlides: CarouselSlide[] = [
|
||||
const carouselSlides: PanelStackPanel[] = [
|
||||
{
|
||||
id: "xrpl-grants-accelerator",
|
||||
heading: translate("Explore XRPL Funding and Builders Programs"),
|
||||
@@ -156,7 +156,7 @@ export default function Funding() {
|
||||
}}
|
||||
/>
|
||||
|
||||
<CarouselFeatured slides={carouselSlides} background="yellow" />
|
||||
<PanelStack slides={carouselSlides} background="yellow" />
|
||||
|
||||
<LogoSquareGrid
|
||||
variant="gray"
|
||||
|
||||
@@ -4,7 +4,7 @@ import { PageWrapper } from 'shared/components/PageWrapper';
|
||||
import { HeaderHeroSplitMedia } from 'shared/sections/HeaderHeroSplitMedia/HeaderHeroSplitMedia';
|
||||
import { CarouselCardList } from 'shared/sections/CarouselCardList/CarouselCardList';
|
||||
import { LogoRectangleGrid } from 'shared/sections/LogoRectangleGrid/LogoRectangleGrid';
|
||||
import { CarouselFeatured } from 'shared/patterns/CarouselFeatured/CarouselFeatured';
|
||||
import { PanelStack } from 'shared/patterns/PanelStack';
|
||||
import { SmallTilesSection } from 'shared/sections/SmallTilesSection/SmallTilesSection';
|
||||
import { LinkTextDirectory } from 'shared/sections/LinkTextDirectory/LinkTextDirectory';
|
||||
import { FeatureTwoColumn } from 'shared/sections/FeatureTwoColumn/FeatureTwoColumn';
|
||||
@@ -116,7 +116,7 @@ export default function Tokenization() {
|
||||
/>
|
||||
|
||||
{/* 5. Token Utility and Market Integration — Carousel Featured (4 slides from Assets frame) */}
|
||||
<CarouselFeatured
|
||||
<PanelStack
|
||||
background="neutral"
|
||||
slides={[
|
||||
{
|
||||
|
||||
@@ -13,7 +13,7 @@ import { FeatureSingleTopic } from "shared/sections/FeatureSingleTopic";
|
||||
import type { StandardCardPropsWithoutVariant } from "shared/components/StandardCard";
|
||||
import { BdsLink } from "shared/components/Link";
|
||||
import { HomeHero } from "shared/sections/HomeHero/HomeHero";
|
||||
import { CarouselFeatured } from "shared/patterns/CarouselFeatured";
|
||||
import { PanelStack } from "shared/patterns/PanelStack";
|
||||
|
||||
export const frontmatter = {
|
||||
seo: {
|
||||
@@ -231,7 +231,7 @@ export default function Index() {
|
||||
cards={blockchainCardStats}
|
||||
/>
|
||||
|
||||
<CarouselFeatured
|
||||
<PanelStack
|
||||
slides={[
|
||||
{
|
||||
id: 0,
|
||||
|
||||
28
shared/patterns/PanelStack/PanelStack.scss
Normal file
28
shared/patterns/PanelStack/PanelStack.scss
Normal file
@@ -0,0 +1,28 @@
|
||||
// BDS PanelStack Pattern Styles
|
||||
// Brand Design System - Vertically stacked featured panels
|
||||
//
|
||||
// Reuses CarouselFeatured slide styles (`.bds-carousel-featured*`) so each
|
||||
// panel matches a carousel slide. This file only handles the vertical stack.
|
||||
//
|
||||
// Naming Convention: BEM with 'bds' namespace
|
||||
// .bds-panel-stack - Outer stack (document flow, no carousel track)
|
||||
// .bds-panel-stack__panel - Individual panel (also has carousel-featured classes)
|
||||
|
||||
.bds-panel-stack {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
gap: $bds-space-2xl;
|
||||
|
||||
@include media-breakpoint-up(md) {
|
||||
gap: $bds-space-3xl;
|
||||
}
|
||||
|
||||
@include media-breakpoint-up(lg) {
|
||||
gap: $bds-space-4xl;
|
||||
}
|
||||
}
|
||||
|
||||
.bds-panel-stack__panel {
|
||||
overflow: hidden;
|
||||
}
|
||||
158
shared/patterns/PanelStack/PanelStack.tsx
Normal file
158
shared/patterns/PanelStack/PanelStack.tsx
Normal file
@@ -0,0 +1,158 @@
|
||||
import React from "react";
|
||||
import clsx from "clsx";
|
||||
import { Divider } from "../../components/Divider";
|
||||
import { PageGrid, PageGridRow, PageGridCol } from "../../components/PageGrid";
|
||||
import { ButtonGroup } from "../ButtonGroup/ButtonGroup";
|
||||
import type {
|
||||
CarouselFeaturedBackground,
|
||||
CarouselFeaturedProps,
|
||||
CarouselSlide,
|
||||
} from "../CarouselFeatured/CarouselFeatured";
|
||||
|
||||
/**
|
||||
* Props for a single panel in the PanelStack component.
|
||||
* Same shape as a CarouselFeatured slide.
|
||||
*/
|
||||
export type PanelStackPanel = CarouselSlide;
|
||||
|
||||
/**
|
||||
* Background color options for PanelStack.
|
||||
* Same variants as CarouselFeatured; each adapts to light/dark mode.
|
||||
*/
|
||||
export type PanelStackBackground = CarouselFeaturedBackground;
|
||||
|
||||
/**
|
||||
* Props for the PanelStack pattern component.
|
||||
* Matches CarouselFeatured, minus carousel-only behavior.
|
||||
*/
|
||||
export interface PanelStackProps extends CarouselFeaturedProps {
|
||||
/** Array of panels to display. Same shape as CarouselFeatured slides. */
|
||||
slides: readonly CarouselSlide[];
|
||||
/** Background color variant. Defaults to 'grey'. */
|
||||
background?: PanelStackBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* PanelStack Pattern Component
|
||||
*
|
||||
* Statically stacks featured panels vertically using the same two-column
|
||||
* slide layout as CarouselFeatured (image left / content right on desktop;
|
||||
* content top / image bottom on tablet and mobile). There is no carousel
|
||||
* track, navigation, or other interaction.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* <PanelStack
|
||||
* slides={[
|
||||
* {
|
||||
* id: 1,
|
||||
* heading: "Powered by Developers",
|
||||
* features: [
|
||||
* { title: "Easy-to-Integrate APIs", description: "Build with common languages..." },
|
||||
* { title: "Full Lifecycle Support", description: "From dev tools to deployment..." },
|
||||
* ],
|
||||
* buttons: [
|
||||
* { label: "Get Started", href: "/docs" },
|
||||
* { label: "Learn More", href: "/about" }
|
||||
* ],
|
||||
* imageSrc: '/image1.jpg',
|
||||
* imageAlt: 'Panel 1'
|
||||
* },
|
||||
* ]}
|
||||
* />
|
||||
* ```
|
||||
*/
|
||||
export const PanelStack = React.forwardRef<HTMLElement, PanelStackProps>(
|
||||
(props, ref) => {
|
||||
const { slides, background = "grey", className, children, ...rest } = props;
|
||||
|
||||
if (slides.length === 0) {
|
||||
console.warn("PanelStack: No slides provided");
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<section
|
||||
ref={ref}
|
||||
className={clsx("bds-panel-stack", className)}
|
||||
{...rest}
|
||||
>
|
||||
{slides.map((slide, index) => (
|
||||
<PageGrid
|
||||
key={slide.id}
|
||||
className={clsx(
|
||||
"bds-carousel-featured",
|
||||
`bds-carousel-featured--bg-${background}`,
|
||||
"bds-panel-stack__panel",
|
||||
)}
|
||||
>
|
||||
<PageGridRow>
|
||||
<PageGridCol
|
||||
span={{ base: 4, md: 8, lg: 6 }}
|
||||
className="bds-carousel-featured__content-col order-1 order-lg-2"
|
||||
>
|
||||
<div className="bds-carousel-featured__content">
|
||||
<div className="bds-carousel-featured__header">
|
||||
<h2 className="bds-carousel-featured__heading h-md">
|
||||
{slide.heading}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className="bds-carousel-featured__bottom">
|
||||
<ul className="bds-carousel-featured__features">
|
||||
{slide.features.map((feature, featureIndex) => (
|
||||
<li
|
||||
key={featureIndex}
|
||||
className="bds-carousel-featured__feature"
|
||||
>
|
||||
<Divider color="base" weight="regular" />
|
||||
<div className="bds-carousel-featured__feature-title body-r">
|
||||
{feature.title}
|
||||
</div>
|
||||
<div className="bds-carousel-featured__feature-description label-l">
|
||||
{feature.description}
|
||||
</div>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="bds-carousel-featured__cta">
|
||||
{slide.buttons && slide.buttons.length > 0 && (
|
||||
<ButtonGroup
|
||||
buttons={slide.buttons}
|
||||
maxButtons={2}
|
||||
color="black"
|
||||
forceColor={background !== "neutral"}
|
||||
className="bds-carousel-featured__buttons"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
|
||||
<PageGridCol
|
||||
span={{ base: 4, md: 8, lg: 6 }}
|
||||
className="bds-carousel-featured__media-col order-2 order-lg-1"
|
||||
>
|
||||
<div className="bds-carousel-featured__media">
|
||||
<img
|
||||
src={slide.imageSrc}
|
||||
alt={slide.imageAlt}
|
||||
className="bds-carousel-featured__image"
|
||||
loading={index === 0 ? "eager" : "lazy"}
|
||||
/>
|
||||
</div>
|
||||
</PageGridCol>
|
||||
</PageGridRow>
|
||||
</PageGrid>
|
||||
))}
|
||||
{children}
|
||||
</section>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
PanelStack.displayName = "PanelStack";
|
||||
|
||||
export default PanelStack;
|
||||
7
shared/patterns/PanelStack/index.ts
Normal file
7
shared/patterns/PanelStack/index.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export {
|
||||
PanelStack,
|
||||
type PanelStackProps,
|
||||
type PanelStackBackground,
|
||||
type PanelStackPanel,
|
||||
} from "./PanelStack";
|
||||
export { default } from "./PanelStack";
|
||||
@@ -113,6 +113,7 @@ $line-height-base: 1.5;
|
||||
@import "../shared/sections/CardStatsList/CardStatsList.scss";
|
||||
@import "../shared/sections/CarouselCardList/CarouselCardList.scss";
|
||||
@import "../shared/patterns/CarouselFeatured/CarouselFeatured.scss";
|
||||
@import "../shared/patterns/PanelStack/PanelStack.scss";
|
||||
@import "../shared/sections/LogoSquareGrid/LogoSquareGrid.scss";
|
||||
@import "../shared/patterns/SectionHeader/SectionHeader.scss";
|
||||
@import "../shared/sections/CardsFeatured/CardsFeatured.scss";
|
||||
|
||||
Reference in New Issue
Block a user