OrganizedContent requires only the current section's Content

This commit is contained in:
Aditya Thakral 2021-08-22 01:23:24 -04:00
parent d6adf8e526
commit f350403ed1
2 changed files with 53 additions and 29 deletions

View File

@ -13,7 +13,6 @@ type Link = ComponentType<LinkProps>;
interface Section {
id: string;
title: string;
Content: ComponentType;
}
const READ_ALL_TITLE = "Read All";
@ -21,16 +20,23 @@ export const READ_ALL_ID = "read-all";
interface Props {
sections: Section[];
currentId: string;
id: string;
children: ReactNode;
link: Link;
}
export function OrganizedContent(props: Props) {
const sections = createSections(props.sections);
const currentIndex = sections.findIndex(({ id }) => id === props.currentId);
export function OrganizedContent({
sections,
id,
children,
link: Link,
}: Props) {
const currentIndex = sections.findIndex(
({ id: sectionId }) => sectionId === id
);
if (currentIndex < 0) {
throw new Error(`Section with ID ${props.currentId} was not found`);
throw new Error(`Section with ID ${id} was not found`);
}
const section = sections[currentIndex];
@ -38,20 +44,20 @@ export function OrganizedContent(props: Props) {
return (
<div className={styles.wrapper}>
<Nav sections={sections} currentIndex={currentIndex} link={props.link} />
<Nav sections={sections} currentIndex={currentIndex} link={Link} />
<div className={styles.content}>
{isReadAll ? (
<section.Content />
children
) : (
<>
<div>
<h1>{section.title}</h1>
<section.Content />
{children}
</div>
<Footer
sections={sections}
currentIndex={currentIndex}
link={props.link}
link={Link}
/>
</>
)}
@ -136,26 +142,32 @@ function Footer({ sections, currentIndex, link: Link }: FooterProps) {
);
}
function createSections(sections: Section[]) {
return [
{
export interface SectionWithContent {
section: Section;
Content: ComponentType;
}
export function createReadAllSection(
sections: SectionWithContent[]
): SectionWithContent {
return {
section: {
id: READ_ALL_ID,
title: READ_ALL_TITLE,
Content() {
return (
<>
{sections.map(({ id, title, Content: SectionContent }) => (
<div key={id}>
<h1>{title}</h1>
<SectionContent />
</div>
))}
</>
);
},
},
...sections,
];
Content: function ReadAllContent() {
return (
<>
{sections.map(({ section: { id, title }, Content }) => (
<div key={id}>
<h1>{title}</h1>
<Content />
</div>
))}
</>
);
},
};
}
function Arrow({ direction }: { direction: "left" | "right" }) {

View File

@ -45,7 +45,11 @@ import { Link } from "./Link";
import { MiniEventCard } from "./MiniEventCard";
import { MiniTechTalkCard } from "./MiniTechTalkCard";
import { NewsCard } from "./NewsCard";
import { OrganizedContent, LinkProps } from "./OrganizedContent";
import {
OrganizedContent,
LinkProps,
createReadAllSection,
} from "./OrganizedContent";
import { TeamMember } from "./TeamMember";
import { TeamMemberCard } from "./TeamMemberCard";
import { TechTalkCard } from "./TechTalkCard";
@ -217,8 +221,16 @@ export function OrganizedContentDemo() {
);
}
const Content =
sections.find(({ id: sectionId }) => sectionId === id)?.Content ??
createReadAllSection(
sections.map((section) => ({ section, Content: section.Content }))
).Content;
return (
<OrganizedContent sections={sections} currentId={id} link={FakeLink} />
<OrganizedContent sections={sections} id={id} link={FakeLink}>
<Content />
</OrganizedContent>
);
}