Skip to content

Commit eb98f21

Browse files
committed
feat: 어드민용 Lottie 플레이어 추가
1 parent 4271bfd commit eb98f21

File tree

4 files changed

+105
-0
lines changed

4 files changed

+105
-0
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"notistack": "^3.0.2",
4848
"react": "^19.1.0",
4949
"react-dom": "^19.1.0",
50+
"react-lottie": "^1.2.10",
5051
"react-router-dom": "^7.6.0",
5152
"remark-gfm": "^4.0.1",
5253
"remeda": "^2.21.5"
@@ -65,6 +66,7 @@
6566
"@types/node": "^22.15.18",
6667
"@types/react": "^19.1.4",
6768
"@types/react-dom": "^19.1.5",
69+
"@types/react-lottie": "^1.2.10",
6870
"@typescript-eslint/parser": "^8.32.1",
6971
"@vitejs/plugin-react": "^4.4.1",
7072
"csstype": "^3.1.3",

packages/common/src/components/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
RouteRenderer as RouteRendererComponent,
77
} from "./dynamic_route";
88
import { ErrorFallback as ErrorFallbackComponent } from "./error_handler";
9+
import { LottieDebugPanel as LottieDebugPanelComponent } from "./lottie";
910
import { MDXRenderer as MDXRendererComponent } from "./mdx";
1011
import type { MapPropType as MapComponentPropType } from "./mdx_components/map";
1112
import { Map as MapComponent } from "./mdx_components/map";
@@ -25,6 +26,7 @@ namespace Components {
2526
export const MDXEditor = MDXEditorComponent;
2627
export const MDXRenderer = MDXRendererComponent;
2728
export const PythonKorea = PythonKoreaComponent;
29+
export const LottieDebugPanel = LottieDebugPanelComponent;
2830
export const ErrorFallback = ErrorFallbackComponent;
2931

3032
export namespace MDX {
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import { Pause, PlayArrow, Stop } from "@mui/icons-material";
2+
import { Box, FormControlLabel, IconButton, Stack, Switch } from "@mui/material";
3+
import * as React from "react";
4+
import Lottie from "react-lottie";
5+
6+
type PlayState = "playing" | "paused" | "stopped";
7+
8+
type LottiePlayerStateType = {
9+
loop: boolean;
10+
isStopped: boolean;
11+
isPaused: boolean;
12+
};
13+
14+
export const LottieDebugPanel: React.FC<{ animationData: unknown }> = ({ animationData }) => {
15+
const [playerState, setPlayerState] = React.useState<LottiePlayerStateType>({
16+
loop: true,
17+
isStopped: false,
18+
isPaused: false,
19+
});
20+
21+
const toggleLoop = () => setPlayerState((ps) => ({ ...ps, loop: !ps.loop }));
22+
const setPlayState = (playState: PlayState) => {
23+
if (playState === "playing") setPlayerState((ps) => ({ ...ps, isStopped: false, isPaused: false }));
24+
if (playState === "paused") setPlayerState((ps) => ({ ...ps, isStopped: false, isPaused: true }));
25+
if (playState === "stopped") setPlayerState((ps) => ({ ...ps, isStopped: true, isPaused: true }));
26+
};
27+
28+
const stop = () => setPlayState("stopped");
29+
const togglePause = () => setPlayState(playerState.isPaused ? "playing" : "paused");
30+
31+
return (
32+
<Stack direction="column">
33+
<Box>
34+
<Lottie
35+
isStopped={playerState.isStopped}
36+
isPaused={playerState.isPaused}
37+
options={{
38+
animationData,
39+
loop: playerState.loop,
40+
autoplay: true,
41+
rendererSettings: { preserveAspectRatio: "xMidYMid slice" },
42+
}}
43+
/>
44+
</Box>
45+
<Stack direction="row" spacing={2}>
46+
<IconButton onClick={togglePause} children={playerState.isPaused ? <PlayArrow /> : <Pause />} />
47+
<IconButton onClick={stop} children={<Stop />} />
48+
<FormControlLabel control={<Switch checked={playerState.loop} onChange={toggleLoop} />} label="반복 재생" />
49+
</Stack>
50+
</Stack>
51+
);
52+
};

pnpm-lock.yaml

Lines changed: 49 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)