|
1 | | -import styled from "@emotion/styled"; |
2 | | -import { evaluate } from "@mdx-js/mdx"; |
3 | | -import { MDXProvider } from "@mdx-js/react"; |
4 | | -import { |
5 | | - Box, |
6 | | - Button, |
7 | | - Card, |
8 | | - CardContent, |
9 | | - Stack, |
10 | | - TextField, |
11 | | - Typography, |
12 | | -} from "@mui/material"; |
13 | | -import React, { useState } from "react"; |
14 | | -import * as runtime from "react/jsx-runtime"; |
15 | | - |
16 | | -// styled 컴포넌트 방식 |
17 | | -const StyledCard = styled(Card)` |
18 | | - transition: transform 0.2s; |
19 | | - &:hover { |
20 | | - transform: translateY(-4px); |
21 | | - } |
22 | | -`; |
23 | | - |
24 | | -const StyledCardContent = styled(CardContent)` |
25 | | - animation: fadeIn 0.5s ease-in; |
26 | | - @keyframes fadeIn { |
27 | | - from { |
28 | | - opacity: 0; |
29 | | - } |
30 | | - to { |
31 | | - opacity: 1; |
32 | | - } |
33 | | - } |
34 | | -`; |
| 1 | +import React from "react"; |
| 2 | + |
| 3 | +import { Box, Button, Card, CardContent, TextField, Typography } from "@mui/material"; |
| 4 | + |
| 5 | +import * as Common from "@frontend/common"; |
| 6 | + |
| 7 | +const LOCAL_STEORAGE_KEY = "mdi_test_input"; |
| 8 | +const MDX_TEST_STRING = `\ |
| 9 | +MDX 간단 사용 설명서 |
| 10 | +
|
| 11 | +긴 가로줄을 넣고 싶다면, \`---\`를 사용해주세요! |
| 12 | +
|
| 13 | +--- |
| 14 | +
|
| 15 | +제목은 아래와 같이 표현해요. |
| 16 | +# H1 |
| 17 | +## H2 |
| 18 | +### H3 |
| 19 | +#### H4 |
| 20 | +##### H5 |
| 21 | +###### H6 |
| 22 | +
|
| 23 | +--- |
| 24 | +
|
| 25 | +**굵은 글자는 이렇게** |
| 26 | +*이탤릭(기울어진 글자)는 요렇게* |
| 27 | +응용 표현으로 ***굵으면서 기울어진 글자는 요렇게*** |
| 28 | +
|
| 29 | +[링크는 이렇게 사용하고요,](https://pycon.kr) |
| 30 | +변수명과 같은 짧은 코드는 \`이렇게\` 표현해요! |
| 31 | +\`\`\` |
| 32 | +# 긴 코드는 이렇게 표현할 수 있어요. |
| 33 | +import antigravity |
| 34 | +\`\`\` |
| 35 | +
|
| 36 | +--- |
| 37 | +
|
| 38 | +HTML 태그 중 일부를 사용할 수 있어요! |
| 39 | +
|
| 40 | +예를 들면 <sub>sub</sub> 태그나 |
| 41 | +위로 가는 <sup>sup</sup> 태그도 있고요, |
| 42 | +밑줄도 <ins>표현할 수 있죠!</ins> |
| 43 | +
|
| 44 | +--- |
| 45 | +
|
| 46 | +> 인용구는 이렇게 표현해요. |
| 47 | +> 여러 줄을 표현할수도 있고요! |
| 48 | +
|
| 49 | +--- |
| 50 | +
|
| 51 | +사진 첨부는 이렇게 해요! |
| 52 | + |
| 53 | +
|
| 54 | +만약 크기 조절을 하고 싶다면 HTML 태그도 가능해요! |
| 55 | +<img width="150px" src="https://myoctocat.com/assets/images/base-octocat.svg" /> |
| 56 | +
|
| 57 | +--- |
| 58 | +
|
| 59 | +- 순번이 없는 목록은 이렇게 사용해요. |
| 60 | +- 만약 하위 항목을 표현하고 싶으시다면 |
| 61 | + - 이렇게 앞에 공백 2개를 붙여주세요! |
| 62 | +
|
| 63 | +--- |
| 64 | +
|
| 65 | +1. 순번이 있는 목록은 이렇게 사용해요. |
| 66 | +2. 실수로 다음의 숫자를 잘못 적어도 |
| 67 | +1. 자동으로 제대로 3번으로 나와요! |
| 68 | +
|
| 69 | +--- |
| 70 | +
|
| 71 | +{ /* |
| 72 | +화면 상에는 노출되지 않는 주석은 이렇게 사용해요. |
| 73 | +주의하실 점은, 서버에서 클라이언트로 페이지의 내용을 응답할때는 요 주석 데이터도 같이 보내지므로, 절때 민감한 내용을 주석에 담지는 말아주세요! |
| 74 | +*/ } |
| 75 | +` |
| 76 | + |
| 77 | +const getMdxInputFromLocalStorage: () => string = () => { |
| 78 | + const input = localStorage.getItem(LOCAL_STEORAGE_KEY); |
| 79 | + return input ? input : ""; |
| 80 | +} |
| 81 | + |
| 82 | +const setMdxInputToLocalStorage: (input: string) => string = (input) => { |
| 83 | + localStorage.setItem(LOCAL_STEORAGE_KEY, input); |
| 84 | + return input; |
| 85 | +} |
35 | 86 |
|
36 | 87 | export const MdiTestPage: React.FC = () => { |
37 | | - const [mdxInput, setMdxInput] = useState(""); |
38 | | - const [Content, setContent] = useState<React.ComponentType>(() => () => null); |
39 | | - const [count, setCount] = useState(0); |
40 | | - |
41 | | - const handleInputChange = async (text: string) => { |
42 | | - setMdxInput(text); |
43 | | - try { |
44 | | - const { default: Content } = await evaluate(text, { |
45 | | - ...runtime, |
46 | | - baseUrl: import.meta.url, |
47 | | - }); |
48 | | - setContent(() => Content); |
49 | | - } catch (error) { |
50 | | - console.error("MDX 변환 오류:", error); |
51 | | - } |
52 | | - }; |
| 88 | + const inputRef = React.useRef<HTMLTextAreaElement>(null); |
| 89 | + const [mdxInput, setMdxInput] = React.useState(getMdxInputFromLocalStorage()); |
53 | 90 |
|
54 | 91 | return ( |
55 | 92 | <Box sx={{ p: 3 }}> |
56 | | - <StyledCard sx={{ mb: 3 }}> |
57 | | - <StyledCardContent> |
58 | | - <Typography variant="h4" gutterBottom> |
59 | | - MUI 테스트 |
60 | | - </Typography> |
61 | | - <Stack direction="row" spacing={2} sx={{ mb: 2 }}> |
62 | | - <Button variant="contained" onClick={() => setCount(count + 1)}> |
63 | | - 카운트: {count} |
64 | | - </Button> |
65 | | - <Button variant="outlined" color="secondary"> |
66 | | - 세컨더리 |
67 | | - </Button> |
68 | | - </Stack> |
69 | | - <TextField |
70 | | - fullWidth |
71 | | - label="테스트 입력" |
72 | | - variant="outlined" |
73 | | - sx={{ mb: 2 }} |
74 | | - /> |
75 | | - </StyledCardContent> |
76 | | - </StyledCard> |
77 | | - |
78 | | - <Typography variant="h5" gutterBottom> |
79 | | - MDX 에디터 |
80 | | - </Typography> |
81 | | - <TextField |
82 | | - multiline |
83 | | - fullWidth |
84 | | - minRows={4} |
85 | | - value={mdxInput} |
86 | | - onChange={(e) => handleInputChange(e.target.value)} |
87 | | - sx={{ mb: 2 }} |
88 | | - /> |
| 93 | + <Typography variant="h5" gutterBottom>MDX 에디터</Typography> |
| 94 | + <TextField inputRef={inputRef} defaultValue={mdxInput} multiline fullWidth minRows={4} sx={{ my: 2 }} /> |
| 95 | + <Button variant="contained" onClick={() => inputRef.current && setMdxInput(setMdxInputToLocalStorage(inputRef.current.value))}>변환</Button> |
| 96 | + |
| 97 | + <Button variant="contained" onClick={() => setMdxInput(MDX_TEST_STRING)}>테스트용 Help Text 로딩</Button> |
| 98 | + <br /> |
| 99 | + <br /> |
89 | 100 | <Card> |
90 | 101 | <CardContent> |
91 | | - <MDXProvider> |
92 | | - <Content /> |
93 | | - </MDXProvider> |
| 102 | + <Common.Components.MDXRenderer text={mdxInput} /> |
94 | 103 | </CardContent> |
95 | 104 | </Card> |
96 | 105 | </Box> |
|
0 commit comments