Merge main
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
commit
34e05db3fc
|
@ -0,0 +1,75 @@
|
|||
.wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.line {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
border-radius: calc(10rem / 16);
|
||||
background-color: var(--secondary-accent);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.timelineSections {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-around;
|
||||
gap: calc(20rem / 16);
|
||||
}
|
||||
|
||||
.timelineSection {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.time {
|
||||
margin: 0;
|
||||
text-align: right;
|
||||
font-size: calc(30rem / 16);
|
||||
font-weight: 700;
|
||||
color: var(--secondary-accent);
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.circle {
|
||||
background-color: var(--secondary-accent);
|
||||
box-shadow: calc(0rem / 16) calc(0rem / 16) calc(30rem / 16) var(--secondary-accent);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.innerCircle {
|
||||
background-color: var(--label);
|
||||
display: none;
|
||||
}
|
||||
|
||||
.text {
|
||||
height: fit-content;
|
||||
margin: 0;
|
||||
padding: calc(15rem / 16);
|
||||
border-radius: calc(10rem / 16);
|
||||
font-size: calc(20rem / 16);
|
||||
font-weight: 700;
|
||||
color: var(--label);
|
||||
border: calc(2rem / 16) solid var(--card-background);
|
||||
background-color: var(--card-background);
|
||||
word-wrap: break-word;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.timelineSection:hover .time {
|
||||
color: var(--secondary-accent-light);
|
||||
}
|
||||
|
||||
.timelineSection:hover .innerCircle {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.timelineSection:hover .text {
|
||||
border: calc(2rem / 16) solid var(--secondary-accent-light);
|
||||
box-shadow: calc(0rem / 16) calc(0rem / 16) calc(20rem / 16) var(--secondary-accent);
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
import React from "react";
|
||||
|
||||
import styles from "./Timeline.module.css";
|
||||
|
||||
interface TimelineData {
|
||||
time: string;
|
||||
text: string;
|
||||
}
|
||||
|
||||
interface TimelineProps {
|
||||
data: TimelineData[];
|
||||
/** Whether the time is transformed to uppercase. */
|
||||
isTimeUppercase?: boolean;
|
||||
/** Width of the middle timeline line, in pixels */
|
||||
lineWidth?: number;
|
||||
/** Width of the outer circles on the timeline, in pixels. */
|
||||
outerCircleWidth?: number;
|
||||
/** Width of the inner circles on the timeline, in pixels. */
|
||||
innerCircleWidth?: number;
|
||||
/** Width of time label, in pixels. */
|
||||
timeWidth?: number;
|
||||
/** Width of text label, in pixels. */
|
||||
textWidth?: number;
|
||||
/** Distance between the time label AND the text label to middle line, in pixels. */
|
||||
gap?: number;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
export function Timeline({
|
||||
data,
|
||||
isTimeUppercase = true,
|
||||
lineWidth = 5,
|
||||
outerCircleWidth = 30,
|
||||
innerCircleWidth = 15,
|
||||
timeWidth = 200,
|
||||
textWidth = 300,
|
||||
gap = 50,
|
||||
className,
|
||||
}: TimelineProps) {
|
||||
const largerMiddleElement =
|
||||
outerCircleWidth > lineWidth ? outerCircleWidth : lineWidth;
|
||||
const width = timeWidth + gap + largerMiddleElement + gap + textWidth;
|
||||
if (innerCircleWidth > outerCircleWidth) {
|
||||
throw new Error(
|
||||
`<Timeline /> - innerCircleWidth (${innerCircleWidth}) is larger than outerCircleWidth (${outerCircleWidth})`
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
className ? `${className} ${styles.wrapper}` : `${styles.wrapper}`
|
||||
}
|
||||
style={{ width: width }}
|
||||
>
|
||||
<div
|
||||
className={styles.line}
|
||||
style={{
|
||||
width: lineWidth,
|
||||
left: width / 2 - lineWidth / 2,
|
||||
}}
|
||||
/>
|
||||
<div className={styles.timelineSections}>
|
||||
{data.map((datum) => (
|
||||
<TimelineSection
|
||||
key={datum.time}
|
||||
datum={datum}
|
||||
width={width}
|
||||
isTimeUppercase={isTimeUppercase}
|
||||
outerCircleWidth={outerCircleWidth}
|
||||
innerCircleWidth={innerCircleWidth}
|
||||
timeWidth={timeWidth}
|
||||
textWidth={textWidth}
|
||||
gap={gap}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface TimelineSectionProps {
|
||||
datum: TimelineData;
|
||||
width: number;
|
||||
isTimeUppercase: boolean;
|
||||
outerCircleWidth: number;
|
||||
innerCircleWidth: number;
|
||||
timeWidth: number;
|
||||
textWidth: number;
|
||||
gap: number;
|
||||
}
|
||||
|
||||
function TimelineSection({
|
||||
datum,
|
||||
width,
|
||||
isTimeUppercase,
|
||||
outerCircleWidth,
|
||||
innerCircleWidth,
|
||||
timeWidth,
|
||||
textWidth,
|
||||
gap,
|
||||
}: TimelineSectionProps) {
|
||||
return (
|
||||
<div className={styles.timelineSection} style={{ gap: gap }}>
|
||||
<div
|
||||
className={styles.time}
|
||||
style={{
|
||||
width: timeWidth,
|
||||
marginLeft: (width - 2 * gap - outerCircleWidth) / 2 - timeWidth,
|
||||
}}
|
||||
>
|
||||
{isTimeUppercase ? datum.time.toUpperCase() : datum.time}
|
||||
</div>
|
||||
<div
|
||||
className={styles.circle}
|
||||
style={{
|
||||
width: outerCircleWidth,
|
||||
height: outerCircleWidth,
|
||||
borderRadius: outerCircleWidth,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={styles.innerCircle}
|
||||
style={{
|
||||
width: innerCircleWidth,
|
||||
height: innerCircleWidth,
|
||||
borderRadius: innerCircleWidth,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
className={styles.text}
|
||||
style={{
|
||||
width: textWidth,
|
||||
marginRight: (width - 2 * gap - outerCircleWidth) / 2 - textWidth,
|
||||
}}
|
||||
>
|
||||
{datum.text}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -80,6 +80,33 @@ export const moreMockCategoricalData = [
|
|||
{ key: "Dart", value: 2.21 },
|
||||
];
|
||||
|
||||
export const mockTimelineData = [
|
||||
{
|
||||
time: "Fall 2020",
|
||||
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
|
||||
},
|
||||
{
|
||||
time: "Winter 2021",
|
||||
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad",
|
||||
},
|
||||
{
|
||||
time: "Spring 2021",
|
||||
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor i",
|
||||
},
|
||||
{
|
||||
time: "Fall 2021",
|
||||
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proid",
|
||||
},
|
||||
{
|
||||
time: "Winter 2022",
|
||||
text: "Lorem ipsum dolor sit amet, consectetur adipi",
|
||||
},
|
||||
{
|
||||
time: "Spring 2022",
|
||||
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut en",
|
||||
},
|
||||
];
|
||||
|
||||
export const mockBoxPlotData = [
|
||||
{
|
||||
category: "1A",
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
mockQuoteData,
|
||||
mockQuoteDataLong,
|
||||
mockPieData,
|
||||
mockTimelineData,
|
||||
} from "data/mocks";
|
||||
import { sectionsData } from "data/routes";
|
||||
import React from "react";
|
||||
|
@ -15,6 +16,7 @@ import { About } from "@/components/About";
|
|||
import { PieChart } from "@/components/PieChart";
|
||||
import { QuotationCarousel } from "@/components/QuotationCarousel";
|
||||
import { Sections } from "@/components/Sections";
|
||||
import { Timeline } from "@/components/Timeline";
|
||||
|
||||
import { CenterWrapper } from "../components/CenterWrapper";
|
||||
import { ColorPalette } from "../components/ColorPalette";
|
||||
|
@ -29,6 +31,7 @@ export default function Home() {
|
|||
<p>Show off your components here!</p>
|
||||
|
||||
<ColorPalette />
|
||||
|
||||
<h2>
|
||||
<code>Text Styles</code>
|
||||
</h2>
|
||||
|
@ -92,6 +95,11 @@ export default function Home() {
|
|||
}))}
|
||||
/>
|
||||
|
||||
<h2>
|
||||
<code>{"<Timeline />"}</code>
|
||||
</h2>
|
||||
<Timeline data={mockTimelineData} />
|
||||
|
||||
<h2>
|
||||
<code>{"<Textbox />"}</code>
|
||||
</h2>
|
||||
|
|
Loading…
Reference in New Issue