[OSCCA] 4. devUP UI : MDX ์ฝ”๋“œ ๋ธ”๋ก์ด ๋ชจ๋ฐ”์ผ์—์„œ ๋„˜์น  ๋•Œ, ๋ฐ˜์‘ํ˜• ๊ทธ๋ฆฌ๋“œ๋กœ ํ•ด๊ฒฐํ•˜๊ธฐ

2025. 11. 17. 17:48ยท๐Ÿงก Projects/๐Ÿงก OSCCA ์˜คํ”ˆ์†Œ์Šค ์ปจํŠธ๋ฆฌ๋ทฐ์…˜ ์•„์นด๋ฐ๋ฏธ
728x90

๐Ÿ‘‰ 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 ๋™์ž‘์„ ๋‹ค์‹œ ์ฐพ์•„๋ณด์•˜์Šต๋‹ˆ๋‹ค.

  1. devup UI ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋นŒ๋“œ ํƒ€์ž„์—
  2. Box ์ปดํฌ๋„ŒํŠธ๋ฅผ <div className = "a b c"> ํ˜•ํƒœ๋กœ ๋ณ€ํ™˜
  3. ๋Ÿฐํƒ€์ž„์—๋Š” ์ผ๋ฐ˜ 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ํŒŒ์ผ์—์„œ ์ž‘๋™ํ•˜๋Š” ์ด์œ  ์ฐพ๊ธฐ

  1. ํ…Œ์ŠคํŠธ
    ์ผ๋ฐ˜ .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์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผ ํ• ๊นŒ?

์•„์˜ˆ ๋‹ค๋ฅธ ์ ‘๊ทผ ๋ฐฉ์‹์„ ์ƒ๊ฐํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์„œ ์ •๋ฆฌ ์นดํ…Œ๊ณ ๋ฆฌ๊ฐ€

  1. devupUI ๋ฅผ ์†Œ๊ฐœํ•˜๋Š” ํŽ˜์ด์ง€
  2. 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>
  )
}

 

 

728x90
'๐Ÿงก Projects/๐Ÿงก OSCCA ์˜คํ”ˆ์†Œ์Šค ์ปจํŠธ๋ฆฌ๋ทฐ์…˜ ์•„์นด๋ฐ๋ฏธ' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
  • [OSCCA] 3. devUP UI : ์ฝ”๋“œ๋ธ”๋ก ๋ผ์ดํŠธ๋ชจ๋“œ CSS ๋ฏธ์ ์šฉ ๋ฌธ์ œ ํ•ด๊ฒฐ๊ธฐ
  • [OSCCA] 2. devUP UI : Table ์ปดํฌ๋„ŒํŠธ ์ขŒ์šฐ ์Šคํฌ๋กค ๋ฌธ์ œ ํ•ด๊ฒฐ๊ธฐ
eyes from es
eyes from es
  • eyes from es
    eyes from es
    eyes from es
  • ์ „์ฒด
    ์˜ค๋Š˜
    ์–ด์ œ
    • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ
      • โค๏ธ ๊ฟ€ํŒ ๋ชจ์Œ
        • โค๏ธ ๊ฐ“์ƒ ๊ฟ€ํŒ
        • โค๏ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ
      • ๐Ÿงก Projects
        • ๐Ÿงก Projects: Web
        • ๐ŸŽคPreterview
        • ๐Ÿงก Projects: App
        • ๐Ÿงก๋Œ€์™ธํ™œ๋™
        • ๐Ÿงก OSCCA ์˜คํ”ˆ์†Œ์Šค ์ปจํŠธ๋ฆฌ๋ทฐ์…˜ ์•„์นด๋ฐ๋ฏธ
      • ๐Ÿ’› Frontend
        • ๐Ÿ’› Frontend : React
        • ๐Ÿ’› Frontend : JavaScript
        • ๐Ÿ’› Frontend : TypeScript
      • ๐Ÿ’š Backend
      • ๐Ÿ’™ OS: ์šด์˜์ฒด์ œ
        • ๐Ÿ’™ Linux
      • ๐Ÿ’œ ์ฝ”๋”ฉํ…Œ์ŠคํŠธ
        • ๐Ÿ’œ ์ž๋ฃŒ๊ตฌ์กฐ
        • ๐Ÿ’œ ์•Œ๊ณ ๋ฆฌ์ฆ˜
        • ๐Ÿ’œ ๋ฐฑ์ค€
        • ๐Ÿ’œSWEA
        • ๐Ÿ’œํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค
      • ๐Ÿ”ด Study
        • ๐Ÿ”ด๋ฉด์ ‘ ์Šคํ„ฐ๋””
        • ๐Ÿ”ด ๊ธฐ์—…๋ถ„์„
        • ๐Ÿ”ด ์—๋Ÿฌ๋…ธํŠธ(Error Note)๐Ÿงฑ
        • ๐Ÿ”ด ITNews(Coding)
        • ๐Ÿ”ด ITNews(Tech)
      • ๐ŸŸ  ์ธ์ƒ ๊ณ„ํš
        • ๐ŸŸ  ์˜ฌํ•ด ๋ชฉํ‘œ
      • ๐ŸŸก TIL
        • ๐ŸŸก TIL ์ผ๊ธฐ
  • ๋ธ”๋กœ๊ทธ ๋ฉ”๋‰ด

    • ํ™ˆ
    • ํƒœ๊ทธ
    • ๋ฐฉ๋ช…๋ก
  • ๋งํฌ

  • ๊ณต์ง€์‚ฌํ•ญ

  • ์ธ๊ธฐ ๊ธ€

  • ํƒœ๊ทธ

    ๊ฐœ๋ฐœ
    ์ฝ”๋”ฉํ…Œ์ŠคํŠธ
    ๋„ค์นด๋ผ์ฟ ๋ฐฐ
    html
    ๋‰ด์Šค์Šคํฌ๋žฉ
    ๋ฌธ์ œํ’€์ด
    ์ฝ”๋“œ์Šคํ„ฐ๋””
    ์ฝ”๋“œ๋ฆฌ๋ทฐ
    ๊ธฐ์—…๋ถ„์„
    ๋ฐฑ์ค€
    Ai
    css
    ์•Œ๊ณ ๋ฆฌ์ฆ˜
    SW์ด์Šˆ
    ๋‰ด์Šค๋ฃธ
    ์ŠคํŒŒ๋ฅดํƒ€์ฝ”๋”ฉํด๋Ÿฝ
    ๋ฐฉํ•™์Šคํ„ฐ๋””
    ์ž๋ฃŒ๊ตฌ์กฐ
    ์ตœ๊ทผ์ด์Šˆ
    ์‚ผ์„ฑ์ „์ž
    IT์ด์Šˆ
    ์ฝ”ํ…Œ
    ๊ฐœ๋ฐœ๊ณต๋ถ€
    ๋™ํ–ฅ๋ถ„์„
    ์ฝ”๋”ฉ
    ์Šคํ„ฐ๋””
    ์›น๊ฐœ๋ฐœ
    C
    ๋ถ„์„๋ ˆํฌํŠธ
    ์Šค๋งˆํŠธ์‹ฑ์Šค
  • ์ตœ๊ทผ ๋Œ“๊ธ€

  • ์ตœ๊ทผ ๊ธ€

  • hELLOยท Designed By์ •์ƒ์šฐ.v4.10.5
eyes from es
[OSCCA] 4. devUP UI : MDX ์ฝ”๋“œ ๋ธ”๋ก์ด ๋ชจ๋ฐ”์ผ์—์„œ ๋„˜์น  ๋•Œ, ๋ฐ˜์‘ํ˜• ๊ทธ๋ฆฌ๋“œ๋กœ ํ•ด๊ฒฐํ•˜๊ธฐ
์ƒ๋‹จ์œผ๋กœ

ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”