Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
115 changes: 114 additions & 1 deletion apps/website/screens/theme-generator/ThemeGeneratorPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,55 @@
import { DxcLink, DxcContainer, DxcFlex, DxcHeading, DxcTypography } from "@dxc-technology/halstack-react";
import {
DxcLink,
DxcContainer,
DxcFlex,
DxcHeading,
DxcTypography,
DxcParagraph,
DxcInset,
DxcGrid,
} from "@dxc-technology/halstack-react";
import Link from "next/link";
import LandingCards from "./components/LandingCards";
import LandingSteps from "./components/LandingSteps";

const steps = [
{
title: "Define your brand",
description: "Choose your core and semantic colors to set the foundation of your theme.",
},
{
title: "Let the system do the rest",
description: "The generator creates a complete set of tokens based on your colors.",
},
{
title: "See it in real components",
description: "Preview your theme applied to real Halstack components and layouts.",
},
{
title: "Export and use it",
description: "Review your theme and export it as a ready-to-use JSON file.",
},
];

const cards = [
{
icon: "filled_palette",
title: "From brand colors to design tokens",
description: "Define your core and semantic colors and let the generator create a structured set of design tokens.",
},
{
icon: "preview",
title: "Preview your theme in real components",
description:
"Apply your generated tokens to real Halstack components and layouts to validate your color choices in context.",
},
{
icon: "accessibility",
title: "Accessible and ready to implement",
description:
"The generator adjusts color combinations to aim for strong contrast and readability. Export a ready-to-use theme file and integrate it into your development workflow.",
},
];

const ThemeGeneratorPage = () => {
return (
Expand Down Expand Up @@ -37,6 +87,69 @@ const ThemeGeneratorPage = () => {
</DxcContainer>
</DxcFlex>
</DxcContainer>
<DxcInset top="72px" bottom="var(--spacing-gap-xxl)">
<DxcFlex justifyContent="center" alignItems="center">
<DxcGrid gap="var(--spacing-gap-xl)">
<DxcContainer width="60%">
<DxcFlex direction="column" justifyContent="center" gap="var(--spacing-gap-m)">
<DxcHeading text="Everything you need to theme at scale" level={3} />
<DxcParagraph>
Theme Generator <strong>removes the complexity</strong> of brand customization so your team can move
faster, stay consistent, and ship with confidence.
</DxcParagraph>
</DxcFlex>
</DxcContainer>
<LandingCards cards={cards} />
</DxcGrid>
</DxcFlex>
</DxcInset>
<DxcInset vertical="var(--spacing-padding-xxl)">
<DxcFlex direction="column" justifyContent="center" alignItems="center" gap="var(--spacing-gap-m)">
<DxcHeading text="How it works" level={3} />
<DxcParagraph>From brand colors to a production-ready Halstack theme in just a few clear steps.</DxcParagraph>
</DxcFlex>
</DxcInset>
<LandingSteps steps={steps} />
<DxcContainer
width="100%"
boxSizing="border-box"
background={{
image: "url(/theme-generator-landing-bg-flipped.png)",
size: "cover",
}}
height="329px"
margin={{ top: "42px" }}
>
<DxcFlex direction="column" fullHeight alignItems="center" justifyContent="center" gap="var(--spacing-gap-ml)">
<DxcFlex direction="column" alignItems="center" justifyContent="center" gap="var(--spacing-gap-m)">
<DxcTypography fontWeight="var(--typography-heading-semibold)" fontSize="var(--typography-heading-xl)">
Your brand, fully expressed in Halstack
</DxcTypography>
<DxcContainer width="70%">
<DxcFlex>
<DxcTypography
fontSize="var(--typography-body-l)"
textAlign="center"
color="var(--color-fg-neutral-strongest)"
>
Turn your brand into a living part of your products. Keep every interface aligned, consistent, and
easier to evolve as your needs grow.
</DxcTypography>
</DxcFlex>
</DxcContainer>
</DxcFlex>
<DxcFlex gap="var(--spacing-gap-l)">
<Link href="" passHref legacyBehavior>
<DxcLink icon="arrow_forward" iconPosition="after">
Open Theme Generator
</DxcLink>
</Link>
<Link href="" passHref legacyBehavior>
<DxcLink>View documentation</DxcLink>
</Link>
</DxcFlex>
</DxcFlex>
</DxcContainer>
</>
);
};
Expand Down
27 changes: 27 additions & 0 deletions apps/website/screens/theme-generator/components/LandingCards.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { DxcContainer, DxcFlex, DxcTypography, DxcAvatar } from "@dxc-technology/halstack-react";

const LandingCard = ({ icon, title, description }: { icon: string; title: string; description: string }) => {
return (
<DxcContainer width="345px" padding="var(--spacing-padding-m)" boxShadow="var(--shadow-100)">
<DxcFlex direction="column" gap="var(--spacing-gap-ml)" justifyContent="center" alignItems="start">
<DxcAvatar icon={icon} color="primary" size="large" shape="square" />
<DxcFlex direction="column" gap="var(--spacing-gap-xs)">
<DxcTypography fontWeight="var(--typography-title-bold)">{title}</DxcTypography>
<DxcTypography fontSize="var(--typography-body-s)">{description}</DxcTypography>
</DxcFlex>
</DxcFlex>
</DxcContainer>
);
};

const LandingCards = ({ cards }: { cards: { icon: string; title: string; description: string }[] }) => {
return (
<DxcFlex gap="var(--spacing-gap-l)" wrap="wrap">
{cards.map((card, index) => (
<LandingCard key={index} {...card} />
))}
</DxcFlex>
);
};

export default LandingCards;
40 changes: 40 additions & 0 deletions apps/website/screens/theme-generator/components/LandingSteps.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { DxcContainer, DxcFlex, DxcTypography, DxcAvatar, DxcDivider, DxcInset } from "@dxc-technology/halstack-react";
import React from "react";

const LandingStep = ({ index, title, description }: { index: number; title: string; description: string }) => {
return (
<DxcContainer width="224px">
<DxcFlex direction="column" alignItems="center" gap="var(--spacing-gap-l)">
<DxcAvatar label={`${index}`} color="primary" size="large" />
<DxcFlex direction="column" alignItems="center" gap="var(--spacing-gap-xs)">
<DxcTypography fontWeight="var(--typography-title-bold)">{title}</DxcTypography>
<DxcTypography textAlign="center" fontSize="var(--typography-body-m)">
{description}
</DxcTypography>
</DxcFlex>
</DxcFlex>
</DxcContainer>
);
};

const LandingSteps = ({ steps }: { steps: { title: string; description: string }[] }) => {
return (
<DxcInset bottom="var(--spacing-gap-xxl)">
<DxcFlex gap="var(--spacing-gap-l)" wrap="wrap" justifyContent="center">
{steps.map((step, index) => (
<React.Fragment key={index}>
<LandingStep index={index + 1} title={step.title} description={step.description} />
{index !== steps.length - 1 && (
<DxcContainer width="48px">
<DxcFlex fullHeight alignItems="center" justifyContent="center">
<DxcDivider color="lightGrey" />
</DxcFlex>
</DxcContainer>
)}
</React.Fragment>
))}
</DxcFlex>
</DxcInset>
);
};
export default LandingSteps;