Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { AccordionDetails, AccordionSummary, Accordion as MuiAccordion, Stack, T
import * as React from "react";
import Marquee from "react-fast-marquee";

import { useAppContext } from "../../../../../apps/pyconkr/src/contexts/app_context";
import { useAppContext } from "../../contexts/app_context";
import PyCon2025HostLogoBig from "../../assets/pyconkr2025_hostlogo_big.png";
import PyCon2025HostLogoSmall from "../../assets/pyconkr2025_hostlogo_small.png";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import ArrowForwardIcon from "@mui/icons-material/ArrowForward";
import { ButtonBase, Stack, Typography } from "@mui/material";
import * as React from "react";
import { useAppContext } from "../../../../../apps/pyconkr/src/contexts/app_context";
import { useAppContext } from "../../contexts/app_context";
import PyCon2025MobileLogoImage from "../../assets/pyconkr2025_main_cover_image.png";
import PyCon2025MobileLogoTitle from "../../assets/pyconkr2025_main_cover_title.png";

Expand Down
67 changes: 62 additions & 5 deletions apps/pyconkr/src/consts/mdx_components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import * as Common from "@frontend/common";
import * as Shop from "@frontend/shop";
import * as mui from "@mui/material";
import type { MDXComponents } from "mdx/types.js";
import * as React from "react";

import PyCon2025Logo from "../assets/pyconkr2025_logo.png";

const MUIMDXComponents: MDXComponents = {
Mui__material__Accordion: mui.Accordion,
Expand Down Expand Up @@ -130,17 +133,71 @@ const MUIMDXComponents: MDXComponents = {
Mui__material__Zoom: mui.Zoom,
};

const PyConKR2025SecondaryStyledDetails: React.FC<React.ComponentProps<typeof Common.Components.MDX.SecondaryStyledDetails>> = (props) => {
const theme = mui.useTheme();
return React.createElement(Common.Components.MDX.SecondaryStyledDetails, { ...props, paletteColor: theme.palette.highlight });
};

const PyConKR2025SessionListFallbackImage = React.createElement("img", {
src: PyCon2025Logo,
alt: "PyCon 2025 Logo",
style: { width: "100%", height: "100%", objectFit: "cover", borderRadius: "50%" },
});

const pyConKR2025SessionListStyles: Common.Components.MDX.SessionListStyles = {
categoryButton: { flexBasis: "14rem" },
itemContainer: { padding: "0.5rem 1.5rem", gap: "1.5rem", minHeight: "9rem", mobilePadding: "0.5rem", mobileGap: "1rem" },
imageContainer: { size: "6rem" },
title: { fontSize: "1.5em", fontWeight: 600, lineHeight: 1.25 },
};

const PyConKR2025SessionList: React.FC<React.ComponentProps<typeof Common.Components.MDX.SessionList>> = (props) =>
React.createElement(Common.Components.MDX.SessionList, { ...props, fallbackImage: PyConKR2025SessionListFallbackImage, styles: pyConKR2025SessionListStyles });

const pyConKR2025SessionTimeTableStyles: Common.Components.MDX.SessionTimeTableStyles = {
layout: { tdHeight: 4, tdWidth: 15, tdWidthMobile: 20 },
dateItemContainer: { padding: "1rem 3rem" },
dateTitle: { fontSize: "2.25em", fontWeight: 600, lineHeight: 1.25 },
dateSubTitle: { fontSize: "1em", fontWeight: 600, lineHeight: 1.25 },
sessionTitle: { fontSize: "1.125em", fontWeight: 600, lineHeight: 1.25 },
sessionBox: { padding: "0.25rem", borderRadius: "0.5rem", gap: "0.5rem" },
tableCell: { padding: "0 0.5rem" },
tableContainer: { gap: "1rem" },
};

const PyConKR2025SessionTimeTable: React.FC<React.ComponentProps<typeof Common.Components.MDX.SessionTimeTable>> = (props) =>
React.createElement(Common.Components.MDX.SessionTimeTable, { ...props, styles: pyConKR2025SessionTimeTableStyles });

const pyConKR2025FAQAccordionStyles: Common.Components.MDX.FAQAccordionStyles = {
summary: { padding: "10px 35px", minHeight: "60px", maxHeight: "60px" },
number: { fontSize: "18px", fontWeight: 400 },
question: { fontSize: "18px", fontWeight: 400, marginLeft: "60px" },
details: { fontSize: "14px", fontWeight: 400, padding: "20px 0 20px calc(35px + 18px + 60px)" },
};

const PyConKR2025FAQAccordion: React.FC<React.ComponentProps<typeof Common.Components.MDX.FAQAccordion>> = (props) =>
React.createElement(Common.Components.MDX.FAQAccordion, { ...props, styles: pyConKR2025FAQAccordionStyles });

const pyConKR2025StyledFullWidthButtonStyles: Common.Components.MDX.StyledFullWidthButtonStyles = {
borderRadius: "0.5rem",
textTransform: "none",
largeHeight: "3.5rem",
};

const PyConKR2025StyledFullWidthButton: React.FC<React.ComponentProps<typeof Common.Components.MDX.StyledFullWidthButton>> = (props) =>
React.createElement(Common.Components.MDX.StyledFullWidthButton, { ...props, styles: pyConKR2025StyledFullWidthButtonStyles });

const PyConKRCommonMDXComponents: MDXComponents = {
Common__Components__Lottie: Common.Components.LottiePlayer,
Common__Components__NetworkLottie: Common.Components.NetworkLottiePlayer,
Common__Components__MDX__Confetti: Common.Components.MDX.Confetti,
Common__Components__MDX__PrimaryStyledDetails: Common.Components.MDX.PrimaryStyledDetails,
Common__Components__MDX__SecondaryStyledDetails: Common.Components.MDX.SecondaryStyledDetails,
Common__Components__MDX__SecondaryStyledDetails: PyConKR2025SecondaryStyledDetails,
Common__Components__MDX__Map: Common.Components.MDX.Map,
Common__Components__MDX__FAQAccordion: Common.Components.MDX.FAQAccordion,
Common__Components__MDX__FullWidthStyledButton: Common.Components.MDX.StyledFullWidthButton,
Common__Components__Session__List: Common.Components.MDX.SessionList,
Common__Components__Session__TimeTable: Common.Components.MDX.SessionTimeTable,
Common__Components__MDX__FAQAccordion: PyConKR2025FAQAccordion,
Common__Components__MDX__FullWidthStyledButton: PyConKR2025StyledFullWidthButton,
Common__Components__Session__List: PyConKR2025SessionList,
Common__Components__Session__TimeTable: PyConKR2025SessionTimeTable,
};

const PythonKRShopMDXComponents: MDXComponents = {
Expand Down
Binary file removed packages/common/src/assets/pyconkr2025_logo.png
Binary file not shown.
14 changes: 11 additions & 3 deletions packages/common/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,22 @@ import { Confetti as ConfettiComponent } from "./mdx_components/confetti";
import {
FAQAccordion as FAQAccordionComponent,
type FAQAccordionProps as FAQAccordionPropsType,
type FAQAccordionStyles as FAQAccordionStylesType,
type FAQItem as FAQItemType,
} from "./mdx_components/faq_accordion";
import type { MapPropType as MapComponentPropType } from "./mdx_components/map";
import { Map as MapComponent } from "./mdx_components/map";
import { OneDetailsOpener as OneDetailsOpenerComponent } from "./mdx_components/one_details_opener";
import { SessionList as SessionListComponent } from "./mdx_components/session_list";
import { SessionTimeTable as SessionTimeTableComponent } from "./mdx_components/session_timetable";
import { SessionList as SessionListComponent, type SessionListStyles as SessionListStylesType } from "./mdx_components/session_list";
import { SessionTimeTable as SessionTimeTableComponent, type SessionTimeTableStyles as SessionTimeTableStylesType } from "./mdx_components/session_timetable";
import {
PrimaryStyledDetails as PrimaryStyledDetailsComponent,
HighlightedStyledDetails as SecondaryStyledDetailsComponent,
} from "./mdx_components/styled_details";
import { StyledFullWidthButton as StyledFullWidthButtonComponent } from "./mdx_components/styled_full_width_button";
import {
StyledFullWidthButton as StyledFullWidthButtonComponent,
type StyledFullWidthButtonStyles as StyledFullWidthButtonStylesType,
} from "./mdx_components/styled_full_width_button";
import { MDXEditor as MDXEditorComponent } from "./mdx_editor";
import { PythonKorea as PythonKoreaComponent } from "./pythonkorea";

Expand Down Expand Up @@ -61,7 +65,11 @@ namespace Components {
export const SessionTimeTable = SessionTimeTableComponent;
export type MapPropType = MapComponentPropType;
export type FAQAccordionProps = FAQAccordionPropsType;
export type FAQAccordionStyles = FAQAccordionStylesType;
export type FAQItem = FAQItemType;
export type SessionListStyles = SessionListStylesType;
export type SessionTimeTableStyles = SessionTimeTableStylesType;
export type StyledFullWidthButtonStyles = StyledFullWidthButtonStylesType;
}
}

Expand Down
140 changes: 79 additions & 61 deletions packages/common/src/components/mdx_components/faq_accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,44 @@ export interface FAQItem {
answer: string;
}

export type FAQAccordionStyles = {
summary?: {
padding?: string;
minHeight?: string;
maxHeight?: string;
};
number?: {
fontSize?: string;
fontWeight?: number | string;
};
question?: {
fontSize?: string;
fontWeight?: number | string;
marginLeft?: string;
};
details?: {
fontSize?: string;
fontWeight?: number | string;
padding?: string;
};
};

export interface FAQAccordionProps {
items: FAQItem[];
styles?: FAQAccordionStyles;
}

export const FAQAccordion: React.FC<FAQAccordionProps> = ({ items }) => {
export const FAQAccordion: React.FC<FAQAccordionProps> = ({ items, styles }) => {
return (
<AccordionWrapper>
{items.map((faq, index) => (
<React.Fragment key={faq.id}>
<StyledAccordion>
<StyledAccordion faqStyles={styles}>
<AccordionSummary expandIcon={<ExpandMoreIcon />} aria-controls={`panel${faq.id}-content`} id={`panel${faq.id}-header`}>
<Number>{faq.id}</Number>
<Question>{faq.question}</Question>
<Number faqStyles={styles}>{faq.id}</Number>
<Question faqStyles={styles}>{faq.question}</Question>
</AccordionSummary>
<StyledAccordionDetails>{faq.answer}</StyledAccordionDetails>
<StyledAccordionDetails faqStyles={styles}>{faq.answer}</StyledAccordionDetails>
</StyledAccordion>
{index !== items.length - 1 && <Divider />}
</React.Fragment>
Expand All @@ -45,59 +68,54 @@ const Divider = styled.div`
margin: 0;
`;

const StyledAccordion = styled(MuiAccordion)`
box-shadow: none;
border-radius: 0;

&:before {
display: none;
}

&.MuiAccordion-root {
margin: 0;

&:first-of-type {
border-top: none;
}

&:last-of-type {
border-bottom: none;
}
}

.MuiAccordionSummary-root {
padding: 10px 35px;
min-height: 60px;
max-height: 60px;

.MuiAccordionSummary-content {
display: flex;
align-items: center;
margin: 0;
}

&.Mui-expanded {
min-height: 60px;
max-height: 60px;
}
}
`;

const Number = styled.span`
font-size: 18px;
font-weight: 400;
`;

const Question = styled.span`
font-size: 18px;
font-weight: 400;
margin-left: 60px;
`;

const StyledAccordionDetails = styled(AccordionDetails)`
background-color: ${({ theme }) => `${theme.palette.primary.light}26`}; // 15% opacity (26 in hex)
color: ${({ theme }) => theme.palette.primary.dark};
font-size: 14px;
font-weight: 400;
padding: 20px 0 20px calc(35px + 18px + 60px); // top right bottom left
`;
const StyledAccordion = styled(MuiAccordion, {
shouldForwardProp: (prop) => prop !== "faqStyles",
})<{ faqStyles?: FAQAccordionStyles }>(({ faqStyles }) => ({
boxShadow: "none",
borderRadius: 0,
"&:before": { display: "none" },
"&.MuiAccordion-root": {
margin: 0,
"&:first-of-type": { borderTop: "none" },
"&:last-of-type": { borderBottom: "none" },
},
".MuiAccordionSummary-root": {
padding: faqStyles?.summary?.padding ?? "10px 35px",
minHeight: faqStyles?.summary?.minHeight ?? "60px",
maxHeight: faqStyles?.summary?.maxHeight ?? "60px",
".MuiAccordionSummary-content": {
display: "flex",
alignItems: "center",
margin: 0,
},
"&.Mui-expanded": {
minHeight: faqStyles?.summary?.minHeight ?? "60px",
maxHeight: faqStyles?.summary?.maxHeight ?? "60px",
},
},
}));

const Number = styled("span", {
shouldForwardProp: (prop) => prop !== "faqStyles",
})<{ faqStyles?: FAQAccordionStyles }>(({ faqStyles }) => ({
fontSize: faqStyles?.number?.fontSize ?? "18px",
fontWeight: faqStyles?.number?.fontWeight ?? 400,
}));

const Question = styled("span", {
shouldForwardProp: (prop) => prop !== "faqStyles",
})<{ faqStyles?: FAQAccordionStyles }>(({ faqStyles }) => ({
fontSize: faqStyles?.question?.fontSize ?? "18px",
fontWeight: faqStyles?.question?.fontWeight ?? 400,
marginLeft: faqStyles?.question?.marginLeft ?? "60px",
}));

const StyledAccordionDetails = styled(AccordionDetails, {
shouldForwardProp: (prop) => prop !== "faqStyles",
})<{ faqStyles?: FAQAccordionStyles }>(({ theme, faqStyles }) => ({
backgroundColor: `${theme.palette.primary.light}26`,
color: theme.palette.primary.dark,
fontSize: faqStyles?.details?.fontSize ?? "14px",
fontWeight: faqStyles?.details?.fontWeight ?? 400,
padding: faqStyles?.details?.padding ?? "20px 0 20px calc(35px + 18px + 60px)",
}));
Loading