8000 feat: 스타일링된 `Accordion` 추가 by MU-Software · Pull Request #23 · pythonkr/frontend · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: 스타일링된 Accordion 추가 #23

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 3, 2025
Merged
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
2 changes: 2 additions & 0 deletions apps/pyconkr-admin/src/consts/mdx_components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ const MUIMDXComponents: MDXComponents = {
};

const PyConKRCommonMDXComponents: MDXComponents = {
Common__Components__MDX__PrimaryStyledDetails: Common.Components.MDX.PrimaryStyledDetails,
Common__Components__MDX__SecondaryStyledDetails: Common.Components.MDX.SecondaryStyledDetails,
Common__Components__MDX__Map: Common.Components.MDX.Map,
};

Expand Down
4 changes: 3 additions & 1 deletion apps/pyconkr/src/components/pages/test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ import { Button, Stack } from "@mui/material";
import * as React from "react";

import { BackendTestPage } from "../../debug/page/backend_test";
import { ComponentTestPage } from "../../debug/page/component_test";
import { MapTestPage } from "../../debug/page/map_test";
import { MdiTestPage } from "../../debug/page/mdi_test";
import { ShopTestPage } from "../../debug/page/shop_test";

const LOCAL_STORAGE_KEY = "selectedTab";
type SelectedTabType = "shop" | "mdi" | "backend" | "map";
type SelectedTabType = "shop" | "mdi" | "backend" | "map" | "component";

const getTabFromLocalStorage = (): SelectedTabType =>
(localStorage.getItem(LOCAL_STORAGE_KEY) as SelectedTabType) || "shop";
Expand All @@ -22,6 +23,7 @@ const TabList: { [key in SelectedTabType]: React.ReactNode } = {
mdi: <MdiTestPage />,
backend: <BackendTestPage />,
map: <MapTestPage />,
component: <ComponentTestPage />,
};

export const Test: React.FC = () => {
Expand Down
2 changes: 2 additions & 0 deletions apps/pyconkr/src/consts/mdx_components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ const MUIMDXComponents: MDXComponents = {
};

const PyConKRCommonMDXComponents: MDXComponents = {
Common__Components__MDX__PrimaryStyledDetails: Common.Components.MDX.PrimaryStyledDetails,
Common__Components__MDX__SecondaryStyledDetails: 10000 Common.Components.MDX.SecondaryStyledDetails,
Common__Components__MDX__Map: Common.Components.MDX.Map,
};

Expand Down
85 changes: 85 additions & 0 deletions apps/pyconkr/src/debug/page/component_test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import * as Common from "@frontend/common";
import { Chip, Stack, Table, TableBody, TableCell, TableRow } from "@mui/material";
import * as React from "react";

const HighlightedChip: React.FC<{ label: string }> = ({ label }) => (
<Chip
label={label}
sx={(theme) => ({
borderColor: theme.palette.highlight.light,
backgroundColor: theme.palette.highlight.main,
color: "#fff",
fontWeight: 600,
})}
/>
);

export const ComponentTestPage: React.FC = () => {
return (
<Stack direction="column" spacing={2} sx={{ p: 2 }}>
<Common.Components.MDX.PrimaryStyledDetails summary="자가용 이용시">
모든 자동차의 출입은 동국대 정문으로만 가능
<Table>
<TableBody>
<TableRow>
<TableCell>
<HighlightedChip label="분당방면" />
</TableCell>
<TableCell>한남대교 → 남산국립극장 400m 전방 → 동국대 정문</TableCell>
</TableRow>
<TableRow>
<TableCell>
<HighlightedChip label="강남방면" />
</TableCell>
<TableCell>동호대교 → 장충체육관 앞 사거리에서 좌회전 300m 전방 → 동국대 정문</TableCell>
</TableRow>
<TableRow>
<TableCell>
<HighlightedChip label="용산방면" />
</TableCell>
<TableCell>남산 2호터널 통과 후 좌회전 100m 전방 → 동국대 정문</TableCell>
</TableRow>
<TableRow>
<TableCell>
<HighlightedChip label="동대문방면" />
</TableCell>
<TableCell>장충사거리 200m 전방 → 동국대 정문</TableCell>
</TableRow>
</TableBody>
</Table>
</Common.Components.MDX.PrimaryStyledDetails>

<Common.Components.MDX.SecondaryStyledDetails summary="자가용 이용시">
모든 자동차의 출입은 동국대 정문으로만 가능
<Table>
<TableBody>
<TableRow>
<TableCell>
<HighlightedChip label="분당방면" />
</TableCell>
<TableCell>한남대교 → 남산국립극장 400m 전방 → 동국대 정문</TableCell>
</TableRow>
<TableRow>
<TableCell>
<HighlightedChip label="강남방면" />
</TableCell>
<TableCell>동호대교 → 장충체육관 앞 사거리에서 좌회전 300m 전방 → 동국대 정문</TableCell>
</TableRow>
<TableRow>
<TableCell>
<HighlightedChip label="용산방면" />
</TableCell>
<TableCell>남산 2호터널 통과 후 좌회전 100m 전방 → 동국대 정문</TableCell>
</TableRow>
<TableRow>
<TableCell>
<HighlightedChip label="동대문방면" />
</TableCell>
<TableCell>장충사거리 200m 전방 → 동국대 정문</TableCell>
</TableRow>
</TableBody>
</Table>
</Common.Components.MDX.SecondaryStyledDetails>
</Stack>
);
};
6 changes: 6 additions & 0 deletions apps/pyconkr/src/styles/globalStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ export const muiTheme = createTheme({
light: "#B6D8D7",
dark: "#126D7F",
},
highlight: {
main: "#E17101",
light: "#EE8D74",
dark: "#C66900",
contrastText: "#FFFFFF",
},
text: {
primary: "#000000",
secondary: "#666666",
Expand Down
6 changes: 6 additions & 0 deletions packages/common/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import { ErrorFallback as ErrorFallbackComponent } from "./error_handler";
import { MDXRenderer as MDXRendererComponent } from "./mdx";
import type { MapPropType as MapComponentPropType } from "./mdx_components/map";
import { Map as MapComponent } from "./mdx_components/map";
import {
PrimaryStyledDetails as PrimaryStyledDetailsComponent,
HighlightedStyledDetails as SecondaryStyledDetailsComponent,
} from "./mdx_components/styled_details";
import { MDXEditor as MDXEditorComponent } from "./mdx_editor";
import { PythonKorea as PythonKoreaComponent } from "./pythonkorea";

Expand All @@ -24,6 +28,8 @@ namespace Components {
export const ErrorFallback = ErrorFallbackComponent;

export namespace MDX {
export const PrimaryStyledDetails = PrimaryStyledDetailsComponent;
export const SecondaryStyledDetails = SecondaryStyledDetailsComponent;
export const Map = MapComponent;
export type MapPropType = MapComponentPropType;
}
Expand Down
82 changes: 82 additions & 0 deletions packages/common/src/components/mdx_components/styled_details.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { ExpandMore } from "@mui/icons-material";
import {
Accordion,
AccordionActions,
AccordionDetails,
AccordionSummary,
PaletteColor,
styled,
SxProps,
Typography,
useTheme,
} from "@mui/material";
import * as React from "react";

type StyledDetailsProps = React.PropsWithChildren<{
expandIcon?: React.ReactNode;
open?: boolean;
summary?: React.ReactNode;
actions?: React.ReactNode;
}>;

type BaseStyledDetailsProps = StyledDetailsProps & {
paletteColor: PaletteColor;
transparencyOnExpand?: number;
};

const BaseStyledDetails: React.FC<BaseStyledDetailsProps> = ({
expandIcon,
open,
summary,
children,
actions,
paletteColor,
transparencyOnExpand,
}) => {
const StyledAccordion = styled(Accordion)(({ theme }) => ({
width: "100%",
paddingRight: theme.spacing(1),
paddingLeft: theme.spacing(1),
border: `1px solid ${paletteColor.dark}`,
borderRadius: "0.5rem",
fontWeight: 500,
}));

const StyledAccordionSummary = styled(AccordionSummary)(() => ({
color: paletteColor.dark,
}));

const rootSx: SxProps = {
transition: "background-color 0.3s ease",
"&.Mui-expanded": {
backgroundColor: `color-mix(in srgb, ${paletteColor.light} ${transparencyOnExpand || 10}%, transparent)`,
},
};

const DefaultExpandIcon = styled(ExpandMore)(({ theme }) => ({
color: paletteColor.dark,
fontSize: theme.typography.h4.fontSize,
}));

return (
<StyledAccordion expanded={open} disableGutters square elevation={0} slotProps={{ root: { sx: rootSx } }}>
{summary && (
<StyledAccordionSummary expandIcon={expandIcon || <DefaultExpandIcon />}>
{typeof summary === "string" ? <Typography variant="h5">{summary}</Typography> : summary}
</StyledAccordionSummary>
)}
<AccordionDetails sx={{ pt: "0", pb: "1rem", px: "2rem" }}>{children}</AccordionDetails>
{actions && <AccordionActions sx={{ pt: "0", pb: "1rem", px: "2rem" }}>{actions}</AccordionActions>}
</StyledAccordion>
);
};

export const PrimaryStyledDetails: React.FC<StyledDetailsProps> = (props) => {
const { palette } = useTheme();
return <BaseStyledDetails {...props} paletteColor={palette.primary} transparencyOnExpand={20} />;
};

export const HighlightedStyledDetails: React.FC<StyledDetailsProps> = (props) => {
const { palette } = useTheme();
return <BaseStyledDetails {...props} paletteColor={palette.highlight} transparencyOnExpand={10} />;
};
2 changes: 1 addition & 1 deletion packages/common/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@
"strict": true,
"jsx": "react"
},
"include": ["src"]
"include": ["src", "vite.config.ts", "vite-env.d.ts", "../../types"],
}
8 changes: 8 additions & 0 deletions types/emotion.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ import "@emotion/react";
import { type Theme as MuiTheme } from "@mui/material/styles";

declare module "@mui/material/styles" {
interface Palette {
highlight: PaletteColor;
}

interface PaletteOptions {
highlight: PaletteColor;
}

interface PaletteColor {
nonFocus?: string;
}
Expand Down
0