Add OrganizedContent with basic functionality

This commit is contained in:
William Tran 2021-05-13 18:47:40 -04:00
parent efd9eecdca
commit edbae617c3
4 changed files with 132 additions and 4 deletions

View File

@ -0,0 +1,6 @@
.organizedcontent {
background-color: rgb(78, 212, 178, 0.2);
color: var(--purple-2);
display:flex;
flex-direction:row;
}

View File

@ -0,0 +1,62 @@
import React, { ReactNode, ComponentType } from "react";
import styles from "./OrganizedContent.module.css";
export interface LinkProps {
children: string | ReactNode | (string | ReactNode)[]
url: string
}
type Link = ComponentType<LinkProps>
interface Heading {
name: string;
url: string;
}
interface Props {
headings: Heading[];
currentIndex: number;
link: Link
children: ReactNode;
}
export const OrganizedContent: React.FC<Props> = ({
headings,
currentIndex,
children,
link: Link,
}) => {
const prevHeading = currentIndex > 0 ? headings[currentIndex - 1] : undefined;
const nextHeading =
currentIndex < headings.length - 1 ? headings[currentIndex + 1] : undefined;
return (
<div className={styles.organizedcontent}>
<div>
{headings.map((heading, index) => (
<h3>
<Link url={heading.url}>{heading.name}</Link>
</h3>
))}
</div>
<div>
<h3>{headings[currentIndex].name}</h3>
{children}
{prevHeading && (
<Link url={prevHeading.url}>
Previous
{prevHeading.name}
</Link>
)}
{nextHeading && (
<Link url={nextHeading.url}>
Next
{nextHeading.name}
</Link>
)}
</div>
</div>
);
};

View File

@ -1,5 +1,4 @@
import React from "react";
import React, { useState } from "react";
import styles from "./playground.module.css";
import AfterHoursContent, {
@ -7,6 +6,7 @@ import AfterHoursContent, {
} from "../content/playground/after-hours.event.mdx";
import { MiniEventCard } from "./MiniEventCard";
import { OrganizedContent, LinkProps } from "./OrganizedContent";
export function MiniEventCardDemo() {
const { name, location, short, date } = afterHoursMetadata;
@ -48,5 +48,59 @@ export function MiniEventCardDemo() {
description={<AfterHoursContent />}
/>
</div>
)
}
export function OrganizedContentDemo() {
let sections = [
{
name: "Heading1",
url: "a",
content: <div> Hello World! 1</div>,
},
{
name: "Heading2",
url: "b",
content: <div> Hello World! 2</div>,
},
{
name: "Heading3",
url: "c",
content: <div> Hello World! 3</div>,
},
];
const readAllSection = {
name: "Read all",
url: "readall",
content: <>{sections.map((section => section.content))}</>
}
sections = [readAllSection, ...sections];
const [index, setIndex] = useState(0);
function FakeLink({ url, children }: LinkProps) {
return (
<div
onClick={() => {
const target = sections.findIndex((section) => section.url === url);
if (target >= 0) {
setIndex(target);
}
}}
>
{children}
</div>
);
}
const { content } = sections[index];
return (
<OrganizedContent headings={sections} currentIndex={index} link={FakeLink}>
{content}
</OrganizedContent>
);
}

View File

@ -1,4 +1,4 @@
import {MiniEventCardDemo} from '../components/playground'
import { MiniEventCardDemo, OrganizedContentDemo } from '../components/playground'
# Playground
@ -7,4 +7,10 @@ import {MiniEventCardDemo} from '../components/playground'
The `<MiniEventCard />` component has a collapsible description, and it used on
the events page. It uses the `<details>` tag and works without JS!
<MiniEventCardDemo />
<MiniEventCardDemo />
## `<OrganizedContent />`
Works without JS!
<OrganizedContentDemo />