๐ PR ๋ฐ๋ก๊ฐ๊ธฐ ๐
Fix: Code block overflow on mobile in N/M Base docs using responsive grid by arty0928 · Pull Request #476 · dev-five-git/devup
Resolves #475 Problem: Code block layout overflow on mobile devices in N/M Base documentation The code examples in the N/M Base documentation page were displayed using a fixed 2-column grid layout...
github.com
๋ค์ด๊ฐ๋ฉฐ
์คํ์์ค ์ปจํธ๋ฆฌ๋ทฐ์ ์์นด๋ฐ๋ฏธ์์ Table ๋ฐ์ํ ์ข์ฐ ์คํฌ๋กค ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋์ค, ๋ฐ์ํ ํ๊ฒฝ์์์ ๋ค๋ฅธ ํ์ด์ง๋ ์ด๋ค๊ฐ ํ์ธํด๋ณด์์ต๋๋ค. ์ด ๊ณผ์ ์์ ๋ค๋ฅธ ํ์ด์ง์ ๋ฐ์ํ ํ๊ฒฝ์์ code ๋ธ๋ญ์ด ๊ณ์ 2์ด๋ก ์ ๋ ฌ๋์ด ์์ด ํ๋ฉด ๋๋น๋ฅผ ๋์ด๊ฐ๋ ๋ฌธ์ ๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค.
๊ธฐ์กด ์ฝ๋
### **Basic Class Names**
<div
style={{
display: 'grid',
gridTemplateColumns: '1fr 1fr',
gap: '2rem',
marginBottom: '2rem',
alignItems: 'start',
}}
>
<div>
```tsx // Input
<div>
<Box bg="red" />
<Box bg="blue" />
<Box color="white" />
</div>
```
</div>
<div>
```tsx // Output (N/M base class names)
<div>
<Box className="a" /> {/* bg: red */}
<Box className="b" /> {/* bg: blue */}
<Box className="c" /> {/* color: white */}
</div>
```
</div>
</div>
์์ธ
gridTemplateColumns: '1fr 1fr',
์ด ๋ถ๋ถ์์ 1fr 1fr๋ก ๋์ด ์์ด์ ํ๋ฉด ํฌ๊ธฐ์ ์๊ด์์ด ํญ์ ๋์ผํ ๋๋น ์ด์ ์์ฑํ๋๋ก ๋์ด ์์ด, ์์ ํ๋ฉด์์ CodeBlock์ด overflow ๋๋ ๋ฌธ์ ์์ต๋๋ค.
โ 1fr
fr = fraction (๋ถ์, ๋น์จ) ์ ์ฝ์
์ฌ์ฉ ๊ฐ๋ฅํ ๊ณต๊ฐ์ ๋น์จ๋ก ๋๋๋ ๋จ์
1fr = ์ฌ์ฉ ๊ฐ๋ฅํ ๊ณต๊ฐ์ 1 ๋น์จ
1fr 1fr = ๊ณต๊ฐ์ 1:1 ๋น์จ๋ก ๋๋ ์ 2๊ฐ์ ์ด ์์ฑ
ํด๊ฒฐ ๋ฐฉ๋ฒ
๋จผ์ ์ ๊ฐ ์๊ฐํ ๋ฐฉ๋ฒ์
1. ๋ฏธ๋์ด ์ฟผ๋ฆฌ
๊ธฐ์กด ์น ํ๋ฉด์์๋ ๋๋น๋ฅผ 1:1 ์ฝ๋ ๋ธ๋ญ์ ์์น์ํค๊ณ , ๋ฐ์ํ์์๋ 2์ด์ด ์๋๋ผ ์ธ๋ก๋ก ์ ๋ ฌ๋๋๋ก ํ๋ ค๊ณ ํ์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์ ๊ฐ ๊ธฐ์ฌํ๋ devup UI๋ zero-tuntime CSS - in -JS ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ธ๋ฐ ๋ฐํ์์ ๋ฏธ๋์ด ์ฟผ๋ฆฌ ์ฒ๋ฆฌ ๋ฐฉ์ ํ์ธ์ด ํ์ํ๋ค๋ ๋ชจ์์ด ์๊ฒผ์ต๋๋ค...
๊ทธ๋ฐ๋ฐ ํ์ผ์ ๊ณ์ ์ฐพ์๋ณด๋ libs.extractor/src/css_utils.rs ํ์ผ์์ ๋ฏธ๋์ด ์ฟผ๋ฆฌ๋ฅผ ํ์ธํ ์ ์์์ต๋๋ค. ์ฆ, devupUI๋ ์ด๋ฏธ ๋ฏธ๋์ด ์ฟผ๋ฆฌ๋ฅผ ์ง์ํ๊ณ ์์์ต๋๋ค.
2. CSS Grid์ ํจ์์ธ repeat
2๋ฒ์งธ ๋ฐฉ๋ฒ์ ๊ธฐ์กด JS์ repeat์ด ์๋, CSS ์ ์ฉ ๋ฌธ๋ฒ์ธ repeat ์ด์์ต๋๋ค.
<Box css={{ gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))' }}>
- auto-fit
- ๊ทธ๋ฆฌ๋ ์ปจํ ์ด๋์ ๋๋น์ ๋ง์ถฐ ๋ค์ด๊ฐ ์ ์๋ ๋งํผ ์๋์ผ๋ก ์นธ์ ์ฑ์ฐ๊ณ
- minmax(300px, 1fr)
- ๊ฐ ์นธ์ ์ต์ ๋๋น๋ฅผ 300px, ์ต๋๋ ๋จ๋ ๊ณต๊ฐ์ ๊ท ๋ฑ๋ถ๋ฐฐ(1fr) ํ๋๋ก ํ์ต๋๋ค.
์ฆ, ํ๋ฉด ํฌ๊ธฐ์ ๋ฐ๋ผ 300px ์ด์์ ์นด๋๊ฐ ๋ค์ด๊ฐ ์ ์๋ ๋งํผ ์๋์ผ๋ก ์ฌ๋ฌ ์นธ์ผ๋ก ๋ฐฐ์น๋๋๋ก ์๊ฐํ์ต๋๋ค.
๊ทธ๋ฌ๋ Box ์ปดํฌ๋ํธ๋ฅผ MDX ํ์ผ์์ ์ฌ์ฉํ ์ ์์์ต๋๋ค.
Box ์ปดํฌ๋ํธ๊ฐ @devup-ui/react์์ client component๋ก๋ง ๋์ํ๋๋ก ์์ฑ๋์ด ์์๊ธฐ ๋๋ฌธ์ MDX ํ์ผ์์ Box ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด import ํ๋ฉด , App Router ํ๊ฒฝ์์ ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฒ ์ปดํฌ๋ํธ๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค.
์ฆ, ์๋ฒ ์ปดํฌ๋ํธ์์๋ client-only ์ฝ๋๋ฅผ ์คํํ ์ ์์ผ๋ฏ๋ก throw new Error("Cannot run on the runtime") ๊ฐ ๋ฐ์ํฉ๋๋ค.
3. ์กฐ๊ฑด๋ถ ์คํ์ผ
<Box css={{ gridTemplateColumns: window.innerWidth < 768 ? '1fr' : '1fr 1fr' }}>
์ด ์ฝ๋๋ ๋ฐํ์์ ๊ณ์ฐํ๊ณ , ๋ฆฌ์ฌ์ด์ฆ ๊ฐ์งํ๋ ์ถ๊ฐ ๋ก์ง์ด ํ์ํฉ๋๋ค.
+ ๋ถํ์ํ ๋ฆฌ๋ ๋๋ง์ด ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ ์กฐ๊ธ ๋ ์ข์ ๋ฐฉ๋ฒ์ ์ฐพ๊ธฐ๋ก ํ์ต๋๋ค.
4. ์์ Box ์ปดํฌ๋ํธ์ gridColoums ์์ฑ์ ์ถ๊ฐ
๊ธฐ์กด์ ์๋ Box ์ปดํฌ๋ํธ์ ๋ฐ์ํ์์๋ ๋ด๋ถ ์์ฑ์ด ํ๋ฉด ๋๋น๋ฅผ ๋์ด๊ฐ์ง ์๊ฒ ์ ๋ ฌํด์ฃผ๋ ์์ฑ์ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ ๋๋ค. ๋ฌผ๋ก ํ์ต ๊ณก์ ์ด ์๊ฒ ์ง๋ง ํ์ฅ์ฑ์ด๋ ์ ์ง๋ณด์์ฑ ์ธก๋ฉด์์ ์ด๊ฒ๋ ์ถ๊ฐํ๋ฉด ๋ ์ข์ ๊ฒ ๊ฐ์์ต๋๋ค.
๊ทธ๋ผ ์ฐ์ Box ์ปดํฌ๋ํธ ์์ฑ์ ํ์ธํด๋ณด๊ฒ ์ต๋๋ค.
Box ์ปดํฌ๋ํธ์ ctrl ์ ๋๋ฅธ ํ ํด๋ฆญํ๋ฉด์ ๋ฐ๋ผ๊ฐ๋ค๋ณด๋ ์๋ ์ฝ๋๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค.
export type DevupCommonProps = Merge<
{
[K in keyof Properties]?: ResponsiveValue<Properties[K]>
},
DevupShortcutsProps
>
๋ชจ๋ CSS ์์ฑ์ด ResponsiveValue๋ก ๊ฐ์ธ์ง๊ณ ์์ต๋๋ค. ์ฆ, Box ๊ฐ ๋ฐ์ํ ๋ฐฐ์ด์ ์ด๋ฏธ ์ง์ํ๊ณ ์์์ต๋๋ค.
ResponsiveValue ์ฝ๋๋ ์๋์ฒ๋ผ ์์ฑ๋์ด ์์ต๋๋ค.
type Value<T> = T | null | undefined | false
export type ResponsiveValue<T> = 0 extends T
? Value<number | T> | Value<number | T>[]
: Value<T> | Value<T>[]
๊ทธ๋ฌ๋ฉด ์ด๋ฏธ ๊ธฐ์กด Box๊ฐ ๋ฐ์ํ ๋ฐฐ์ด์ ์ง์ํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ด๊ฒ์ ์ฌ์ฉํ๋, ๊ธฐ์กด div ํ๊ทธ๋ค๋ก ์์ฑ๋ ์ฝ๋๋ค์ Box๋ก ๋ณ๊ฒฝํ์ฌ ์ฌ์ฌ์ฉ์ฑ๊ณผ ์ ์ฒด ์ฝ๋ ํต์ผ์ฑ์ ๋์ฌ๋ณด๊ฒ ์ต๋๋ค.
์ด ๊ณผ์ ์์ ์ด๋ฐ ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค
## Error Type
Runtime Error
## Error Message
Cannot run on the runtime
at o (..\..\packages\react\dist\components\Box.js:2:9)
## Code Frame
1 | function o(n) {
> 2 | throw new Error("Cannot run on the runtime");
| ^
3 | }
4 | export {
5 | o as Box
Next.js version: 16.0.0 (Turbopack)
์์ธ์ Box ์ปดํฌ๋ํธ๋ ๋น๋ ํ์ ์ ์ฉ ์ปดํฌ๋ํธ์ธ๋ฐ, MDX ํ์ผ์ ๋ฐํ์์ ์คํ๋๊ณ ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
Box ์ปดํฌ๋ํธ์ ๋ํ ์ดํด๊ฐ ๋ถ์กฑํ ๊ฒ ๊ฐ์ devup UI ๋์์ ๋ค์ ์ฐพ์๋ณด์์ต๋๋ค.
- devup UI ์ปดํ์ผ๋ฌ๊ฐ ๋น๋ ํ์์
- Box ์ปดํฌ๋ํธ๋ฅผ <div className = "a b c"> ํํ๋ก ๋ณํ
- ๋ฐํ์์๋ ์ผ๋ฐ HTML๋ง ์กด์ฌ
๊ทธ๋ฌ๋๊น ๊ธฐ์กด ์๋ ์ฝ๋๋
// src/components/MyComponent.tsx
import { Box } from '@devup-ui/react'
export function MyComponent() {
return (
<Box display="grid" gridTemplateColumns={['1fr', '1fr 1fr']}>
<div>A</div>
<div>B</div>
</Box>
)
}
๋น๋ ํ์ ์ด๋ ๊ฒ ์ฒ๋ฆฌ๋ฉ๋๋ค.
// ์ปดํ์ผ ํ
export function MyComponent() {
return (
<div className="a b c"> {/* Box๊ฐ ์ฌ๋ผ์ง! */}
<div>A</div>
<div>B</div>
</div>
)
}
๊ทธ๋ฐ๋ฐ ์ด์ TableProps๋ฅผ ์ ๋ฌํด์ Table ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ๋ mdx ํ์ผ์์๋ ๋ฌธ์ ๊ฐ ์์์ต๋๋ค.
๊ฐ๋ฅ์ฑ์ 2๊ฐ์ง์ ๋๋ค.
1. PropsTable.tsx ๋ devUP ์ปดํ์ผ๋ฌ๋ฅผ ๊ฑฐ์น๋ค.
โ PropsTable.tsx → DevupUI ์ปดํ์ผ๋ฌ → Box๊ฐ div๋ก ๋ณํ → ์๋
2. PropsTable์ ์๋ฒ ์ปดํฌ๋ํธ๋ผ ๋น๋ ํ์์๋ง ์คํ
โ ๋น๋ ํ์์ ์คํ → DevupUI ์ปดํ์ผ → HTML ์์ฑ → ๋ฐํ์์๋ HTML๋ง → ์๋
propsTable์ ์ ๋๋์ง ์ ํํ๊ฒ ์์์ผ ์ Box ๋ฐ์ํ์ด ์๋๋์ง ํ์ธํ ์ ์๊ธฐ ๋๋ฌธ์ ์ 2๊ฐ์ง ์ด์ ์ค propsTable์ด mdx์์ ์ปดํฌ๋ํธ๋ฅผ ๊ฐ์ ธ์์ ์ฌ์ฉํ ์ ์๋ ์ด์ ๋ฅผ ํ์ธํ์ต๋๋ค.
propsTable์ mdxํ์ผ์์ ์๋ํ๋ ์ด์ ์ฐพ๊ธฐ
- ํ
์คํธ
์ผ๋ฐ .tsx ํ์ผ์์ Box ์ปดํฌ๋ํธ๋ฅผ ๋ง๋ค๊ณ mdx ํ์ผ์์ ํด๋น TestBox ์ปดํฌ๋ํธ๋ฅผ import ํ์ต๋๋ค.
// components/TestBox.tsx
import { Box } from '@devup-ui/react'
export function TestBox() {
return (
<Box display="grid" gridTemplateColumns={['1fr', '1fr 1fr']}>
<div>Test 1</div>
<div>Test 2</div>
</Box>
)
}
//mdx ํ์ผ
import { TestBox } from '@/components/TestBox'
<TestBox />
⇒ ๋น๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค.

⇒ MDX ํ์๊ฐ JSX ๋ฐฐ์ด ๋ฌธ๋ฒ์ ํ์ฑํ์ง ๋ชปํ๋ ์๋ฌ
MDX๋ js ์ฝ๋๋ฅผ ํ์ฑํ ๋ js ํ์์ธ acorn์ ์ฌ์ฉํ๋๋ฐ,
<TestBox />
TestBox ๋ด๋ถ์:
gridTemplateColumns={['1fr', '1fr 1fr']} // ← ์ด ๋ฐฐ์ด ๋ฌธ๋ฒ์ ํ์ฑ ๋ชป ํจ!
⇒ ์ฆ ๋ฐ์ํ ๋ฐฐ์ด ๊ฐ์ ํน์ ๋ฌธ๋ฒ์ด MDX ํ์์ ์ถฉ๋ํ๋ ๊ฒ์ด์์ต๋๋ค
⇒ PropsTable์ด ์ ๋๋ก ๋์ํ๋ ์ด์ ๋ ๋จ์ ๋ฌธ์์ด props ๋ง ์ฌ์ฉํ์ฌ, ๋ฐฐ์ด ๊ฐ์ฒด ๊ฐ์ ๋ณต์กํ ํํ์์ด ์์๊ธฐ ๋๋ฌธ์ ๋๋ค.
PropsTable.tsx
↓
1. DevupUI ์ปดํ์ผ๋ฌ๊ฐ ๋น๋ ํ์์ ์ฒ๋ฆฌ
↓
2. Box → <div className="xxx"> ๋ณํ
↓
3. ์๋ฒ ์ปดํฌ๋ํธ๋ก ๋น๋ ํ์์ ์คํ
↓
4. HTML ์์ฑ
↓
5. ๋ฐํ์์๋ ์์ HTML๋ง ์ ๋ฌ
// 1๋จ๊ณ: DevupUI ์ปดํ์ผ (๋น๋ ํ์)
<Box maxWidth="100%"> // ๋จ์ ๋ฌธ์์ด๋ง
↓
<div className="abc">
// 2๋จ๊ณ: ์๋ฒ ์ปดํฌ๋ํธ ์คํ (๋น๋ ํ์)
async function PropsTable() { ... }
↓
HTML ์์ฑ
// 3๋จ๊ณ: MDX์์ ์ฌ์ฉ (๋ฐํ์)
<PropsTable /> // ์ด๋ฏธ HTML์ด๋ฏ๋ก ๋ฌธ์ ์์
๋ฐ๋ฉด TestBox๊ฐ ์๋๋ ์ด์ ๋
// MDX์์
import { TestBox } from './TestBox'
<TestBox />
// MDX ํ์ ๋จ๊ณ
↓
acorn์ด TestBox ๋ด๋ถ๋ฅผ ๋ถ์ ์๋
↓
{['1fr', '1fr 1fr']} ๋ฐ๊ฒฌ
↓
"์ด๊ฒ ๋ญ์ผ?" (SyntaxError) โ
↓
์ค๋จ
ํด๊ฒฐ์ฑ ์ ๊ฒ
๊ทธ๋ ๋ค๋ฉด ์ง๊ธ๊น์ง ์ ๊ฐ ์๊ฐํ ๋ฐฉ๋ฒ 4๊ฐ์ง ์ค
1. ๋ฏธ๋์ด ์ฟผ๋ฆฌ
devup UI๋ ๋น๋ ํ์์ ๋ฏธ๋์ด ์ฟผ๋ฆฌ๋ฅผ ์ง์ํ๊ณ ์์ผ๋ฏ๋ก, ์ฐ๋ฆฌ๊ฐ ๊ตณ์ด js๋ก ํ๋ฉด ํฌ๊ธฐ๋ฅผ ๊ณ์ฐํด์ ์ ์ฉํ ํ์๊ฐ ์์ง๋ง, MDX ํ์ผ ์์์ JS ๋ฐฐ์ด → ๋ฐํ์ ๊ณ์ฐ ์ผ๋ก ์ค๋ฅ๊ฐ ๋ ์ ์์์ต๋๋ค.
2. repeat
์ด ๋ฐฉ๋ฒ์ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ์ ์ฉํ ์ ์์์ง๋ง, ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์ธ Box ์ปดํฌ๋ํธ๋ฅผ ์๋ฒ ์ปดํฌ๋ํธ๋ก ์คํ๋๋ MDX ํ์ผ์์ ์ฌ์ฉํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.
3. ์กฐ๊ฑด๋ถ ์คํ์ผ
๋ฐํ์์์ JS๋ก ํ๋ฉด ๋๋น๋ฅผ ์ฝ์ด ์คํ์ผ์ ๋ฐ๊พธ๊ธฐ ๋๋ฌธ์ MDX/zero-runtime ์ฒ ํ๊ณผ ์์ ์ถฉ๋ํ๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค.
4. Box ์ปดํฌ๋ํธ์ GridColumns ์์ฑ ์ถ๊ฐ
์ฆ MDX ํ์(acorn)๊ฐ ๋ฐฐ์ด ๊ธฐ๋ฐ ๋ฐ์ํ ํํ์์ ์ดํดํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ๋ฐํ์ ์๋ฌ๊ฐ ๋ฐ์ํ์ต๋๋ค. Box ์์ฒด๋ ๋น๋ ํ์ ์ ์ฉ์ด์ง๋ง MDX์์ ๋ฐํ์์ JSX ๋ฐฐ์ด/๊ฐ์ฒด props๋ฅผ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ MDX ๋ฌธ์์์๋ gridColumns ์์ฑ์ ๋ฃ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์ ์์์ต๋๋ค.
์ฆ, ๋ชจ๋ ๋ฐฉ๋ฒ์ด ์๋ฌ๊ฐ ๋๊ณ , ์ ํฉํ์ง ์๋ค๊ณ ํ์ ํ์ต๋๋ค.
MDX ๋ ์ด์์ ์์ด ์ฝํ ์ธ ๋ง ์ ๋ฌํ๊ณ , ๋ ์ด์์ Box๋ .tsx์์ ์ฒ๋ฆฌํด์ผ ํ ๊น?
์์ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์์ ์๊ฐํ์ต๋๋ค. ๋ฌธ์ ์ ๋ฆฌ ์นดํ ๊ณ ๋ฆฌ๊ฐ
- devupUI ๋ฅผ ์๊ฐํ๋ ํ์ด์ง
- devupUI์ ์ปดํฌ๋ํธ ์์ ํ์ด์ง
๊ฐ ์๋๋ฐ 2๋ฒ์ ๊ฒฝ์ฐ page๋ฅผ ๋ ๋๋งํ๊ณ mdx ํ์ผ์์๋ ๋ ์ด์์ ์์ด ์ฝํ ์ธ ๋ง page ํ์ผ๋ก ๋๊ธฐ๊ณ ์์ต๋๋ค.
์ํคํ ์ฒ ์ค๊ณ์ ๋ํ ๊ณ ๋ฏผ…
1๋ฒ๋ 2๋ฒ์ฒ๋ผ ํ ๊น ๊ณ ๋ฏผ์ด ๋์์ต๋๋ค. 2๋ฒ์ ๊ฒฝ์ฐ,
- Example ์น์
- API ์น์
๋ฑ ๊ณตํต ํ์์ด ์๊ณ , ์ฝ๋ ๋ธ๋ก์ด ๊ฐ๊ฐ ๋ค์ด๊ฐ๋ฏ๋ก ํ ํ๋ฆฟ์ผ๋ก ์์ฑํ๋ฉด ํธํ์ต๋๋ค.
ํ์ง๋ง 1๋ฒ์ ๊ฒฝ์ฐ ๋จ์ ๊ธ์๋ง ์๊ณ ์ฝ๋ ๋ธ๋ก์ด ์๋ ๊ณณ๋ ์์ด์ 2๋ฒ์ฒ๋ผ ํ์์ด ์ ํด์ง ๊ฒ์ด ์๋์๊ธฐ ๋๋ฌธ์ 1๋ฒ docs ์ค ํ๊ฐ์ ํ์ด์ง๋ง์ ์ํด์ ๋ค ๊ณ ์น๋ ๊ฒ์ด ๋ง์๊น? ํ๋ ๊ณ ๋ฏผ์ด ๋ค์์ต๋๋ค.
button ๋ฌธ์์์๋ ์๋ ์ฝ๋์ฒ๋ผ Grid ์ปดํฌ๋ํธ๋ฅผ ์ฌ์ฉํ ๊ฒ์ ํ์ธํ์ต๋๋ค. ๋ฐ๋ผ์ ์ด๋ฏธ ์๋ Grid ์ปดํฌ๋ํธ๋ฅผ ํ์ฉํด์ ์์ฑํด๋ณด๊ฒ ์ต๋๋ค.
import { Center, css, Flex, Grid, Text, VStack } from '@devup-ui/react'
...
export default function Page() {
return (
<VStack gap="16px">
...
<Grid
gap={['10px', null, null, null, '20px']}
gridTemplateColumns={[
'repeat(1, 1fr)',
'repeat(3, 1fr)',
null,
'repeat(4, 1fr)',
'repeat(5, 1fr)',
]}
>
....
</VStack>
</VStack>
)
}
ExampleGridProps
๊ทธ๋ผ ExampleGridProps์ ์์ฑ์์ ์ด์ ๊ฐ์๊ฐ ์ ์ฐํ๊ฒ ๋ณ๋๋ ์ ์์ผ๋ cols๋ก ์์ฑ๊ฐ์ ๋ง๋ค๊น? ์ฒ์์ ๊ณ ๋ฏผํ์ต๋๋ค.
interface ExampleGridProps {
children: ReactNode
cols?: number | number[]
}
์ด๋ฐ์์ผ๋ก ๊ณ ๋ฏผํ์ผ๋, children์ ReactNode ์์ฒด๊ฐ React๊ฐ ๋ ๋๋งํ ์ ์๋ ๋ชจ๋ ๊ฒ์ ๋ํ๋ด๋ฏ๋ก children์ ๋จ์ผ ์์, ๋ฐฐ์ด ๊ฐ์ ์ฌ๋ฌ ์์, ํ ์คํธ๋ ์์๋ค์ ํผํฉํด์๋ ๋ชจ๋ ReactNode๋ก ํํ์ด ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ ๊นจ๋ฌ์์ต๋๋ค.
type ReactNode =
| ReactElement // <div>, <Component />
| string // "hello"
| number // 42
| boolean // true, false
| null // null
| undefined // undefined
| ReactNode[] // [<div />, "hello", 123]
| ReactPortal
| Iterable<ReactNode>
์ฆ ReactNode๋ก๋ง ๋๊ฒผ์ ๋๋ ์๋ ๊ทธ๋ฆผ์ฒ๋ผ 3๊ฐ๊ฐ ์๋ ์ ํํ๋๊ณ ์๋ ๊ฒ์ ํ์ธํ์ต๋๋ค
์ต์ข ๊ฒฐ๊ณผ


์ต์ข ์ฝ๋
MDX ์ฉ ExampleGrid ์ปดํฌ๋ํธ ์์ฑ
import { Grid } from '@devup-ui/react'
import { ReactNode } from 'react'
interface ExampleGridProps {
children: ReactNode
}
export function ExampleGrid({ children }: ExampleGridProps) {
return (
<Grid gap="16px" gridTemplateColumns={['repeat(1, 1fr)', 'repeat(2, 1fr)']}>
{children}
</Grid>
)
}
