Skip to content

Commit

Permalink
scaffold alt new timeline pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
rebeccahongsf committed Oct 31, 2024
1 parent 8a07c83 commit 2987e12
Show file tree
Hide file tree
Showing 8 changed files with 258 additions and 0 deletions.
11 changes: 11 additions & 0 deletions app/components/TimelineEven/TimelineDetails.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const root = "overflow-hidden";
export const wrapper = "mr-0 au-ml-auto flex-col lg:flex-row";
export const contentWrapper = "lg:rs-pr-9 ml-0 flex flex-col *:font-dm-sans";
export const heading = "2xl:whitespace-pre-line -mt-01em rs-mb-2 xl:max-w-1200";
export const superhead = "order-first mb-38";
export const dek = "max-w-[50ch] type-3 rs-mb-3 *:*:leading-snug";
export const body = "max-w-[50ch] rs-mb-3 *:*:leading-snug";
export const imageWrapper =
"aspect-[1/1] group relative w-500 h-500 perspective-600";
export const image =
"inset-0 w-full h-full object-cover rounded-lg transform ease-in-out duration-500";
117 changes: 117 additions & 0 deletions app/components/TimelineEven/TimelineDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { HTMLAttributes } from "react";
import { Container } from "../Container";
import { Heading, Text } from "../Typography";
import { FlexBox } from "../FlexBox";
import * as styles from "./TimelineDetails.styles";
import { cnb } from "cnbuilder";
import { XCircleIcon } from "@heroicons/react/24/outline";

type TimelineDetailsProps = HTMLAttributes<HTMLDivElement> & {
heading: string;
year: string;
dek?: string;
body: string;
cta?: React.ReactNode;
image: string;
bgColor?: "fog-light" | "red-gradient";
align?: "right" | "left";
width?: "full" | "narrow";
isSelected?: boolean;
onClose: () => void;
};

export const TimelineDetails = ({
heading,
year,
dek,
body,
cta,
image,
bgColor = "fog-light",
align = "left",
isSelected,
onClose,
...props
}: TimelineDetailsProps) => (
<Container
{...props}
as="section"
bgColor={bgColor}
width="site"
py={9}
className={styles.root}
>
<FlexBox
alignItems="start"
justifyContent="between"
gap
className={styles.wrapper}
>
<Container className={cnb(styles.contentWrapper)}>
{heading && (
<Heading leading="none" className={styles.heading}>
{heading}
</Heading>
)}
{year && (
<Text
font="serif"
variant="overview"
weight="normal"
className={styles.superhead}
>
{year}
</Text>
)}
{dek && (
<Text
font="serif"
variant="overview"
weight="normal"
className={styles.dek}
>
{dek}
</Text>
)}
{body && (
<Text
font="serif"
variant="overview"
weight="normal"
className={styles.body}
>
{body}
</Text>
)}
{cta}
</Container>
{image && (
<div
className={cnb(styles.imageWrapper, {
"order-first": align === "left",
})}
>
<img
alt=""
src={image}
className={cnb(styles.image, {
"rotate-y-[25deg] group-hocus:rotate-y-[-25deg]":
align === "left",
"rotate-y-[-25deg] group-hocus:rotate-y-[25deg]":
align === "right",
})}
width={500}
height={500}
/>
</div>
)}
<button className="group" onClick={onClose}>
<span className="sr-only">Close {heading} details</span>
<XCircleIcon
width={50}
className="text-black group-hocus:text-digital-red"
/>
</button>
</FlexBox>
</Container>
);
10 changes: 10 additions & 0 deletions app/components/TimelineEven/TimelineItem.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const size = {
small: "w-150 h-150",
medium: "w-200 h-200",
large: "w-300 h-300",
};

export const trapezoid = {
left: "rotate-y-[25deg] group-hocus:rotate-y-[-25deg]",
right: "rotate-y-[-25deg] group-hocus:rotate-y-[25deg]",
};
64 changes: 64 additions & 0 deletions app/components/TimelineEven/TimelineItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { cnb } from 'cnbuilder';
import * as styles from './TimelineItem.styles';
import * as types from './TimelineItem.types';
import { Heading, Text } from '../Typography';

interface TimelineItemProps {
heading: string;
year: string;
image: string;
size?: types.SizeType;
trapezoid?: types.TrapezoidType;
className?: string;
}

const TimelineItem = ({
heading,
year,
image,
size = 'medium',
trapezoid = 'left',
className,
...props
}: TimelineItemProps) => {
const imageSize = styles.size[size];
const trapezoidType = styles.trapezoid[trapezoid];

return (
<div {...props} className="flex flex-col">
<button
className={cnb(
'group relative hocus:transform-none',
trapezoidType,
className
)}
>
<div
className={cnb(
'aspect-[1/1] group relative perspective-600',
imageSize
)}
>
<img
alt=""
src={image}
className="inset-0 w-full h-full object-cover rounded-lg transform ease-in-out duration-500"
/>
</div>
</button>
<div className="flex flex-col *:font-dm-sans">
<Heading className="type-0" weight="normal">{heading}</Heading>
<Text
font="serif"
variant="overview"
weight="normal"
className="order-first mt-28"
>
{year}
</Text>
</div>
</div>
);
};

export default TimelineItem;
4 changes: 4 additions & 0 deletions app/components/TimelineEven/TimelineItem.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import * as styles from "./TimelineItem.styles";

export type SizeType = keyof typeof styles.size;
export type TrapezoidType = keyof typeof styles.trapezoid;
49 changes: 49 additions & 0 deletions app/components/TimelineEven/TimelineOverview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
'use client';

import { Container } from '@/components/Container';
import TimelineItem from './TimelineItem';
import { useState } from 'react';
import { TimelineDetails } from './TimelineDetails';
import { motion, AnimatePresence } from 'framer-motion';
import { SizeType, TrapezoidType } from './TimelineItem.types';

type TimelineItemData = {
year: string;
heading: string;
dek: string;
body: string;
href?: string;
image: string;
};

type TimelineProps = {
timelineData: TimelineItemData[];
};


const TimelineEven = ({ timelineData }: TimelineProps) => {
const sizePattern:SizeType[] = ['large', 'medium', 'small'];

return (
<Container width="site" py={5} bgColor="fog-light" className="mb-50">
<div className="grid gap-50 grid-cols-4">
{timelineData.map((item, idx) => {
const trapezoid = idx % 2 === 0 ? 'right' : 'left';
const size = sizePattern[idx % sizePattern.length];

return (
<TimelineItem
key={idx}
{...item}
size={size}
trapezoid={trapezoid}
className="rounded-lg flex items-center justify-center"
/>
);
})}
</div>
</Container>
);
};

export default TimelineEven;
1 change: 1 addition & 0 deletions app/components/TimelineEven/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./TimelineOverview";
2 changes: 2 additions & 0 deletions app/example/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { PageTitle } from "@/components/PageTitle";
import TimelineOverview from "@/components/Timeline/TimelineOverview";
import { loadTimelineData } from "@/utilities/loadTimelineData";
import { GradientBanner } from "@/components/GradientBanner/GradientBanner";
import TimelineEven from '@/components/TimelineEven/TimelineOverview';

const ExamplePage = async () => {
const timelineData = await loadTimelineData();
Expand Down Expand Up @@ -74,6 +75,7 @@ const ExamplePage = async () => {
</div>
</GradientBanner>
<TimelineOverview timelineData={timelineData} />
<TimelineEven timelineData={timelineData} />
</div>
);
};
Expand Down

0 comments on commit 2987e12

Please sign in to comment.