@nexus-cross/design-system 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/cursor-rules/nexus-project-setup.mdc +292 -0
  2. package/cursor-rules/nexus-ui-api.mdc +698 -0
  3. package/cursor-rules/nexus-ui-components.mdc +136 -0
  4. package/dist/accordion.d.mts +28 -0
  5. package/dist/accordion.d.ts +28 -0
  6. package/dist/accordion.js +28 -0
  7. package/dist/accordion.mjs +3 -0
  8. package/dist/avatar.d.mts +17 -0
  9. package/dist/avatar.d.ts +17 -0
  10. package/dist/avatar.js +16 -0
  11. package/dist/avatar.mjs +3 -0
  12. package/dist/button.d.mts +17 -0
  13. package/dist/button.d.ts +17 -0
  14. package/dist/button.js +16 -0
  15. package/dist/button.mjs +3 -0
  16. package/dist/carousel.d.mts +36 -0
  17. package/dist/carousel.d.ts +36 -0
  18. package/dist/carousel.js +32 -0
  19. package/dist/carousel.mjs +3 -0
  20. package/dist/checkbox.d.mts +21 -0
  21. package/dist/checkbox.d.ts +21 -0
  22. package/dist/checkbox.js +20 -0
  23. package/dist/checkbox.mjs +3 -0
  24. package/dist/chip.d.mts +16 -0
  25. package/dist/chip.d.ts +16 -0
  26. package/dist/chip.js +16 -0
  27. package/dist/chip.mjs +3 -0
  28. package/dist/chunks/chunk-22ULI3BF.js +21 -0
  29. package/dist/chunks/chunk-26BUGBOY.mjs +57 -0
  30. package/dist/chunks/chunk-2JTPRBHZ.mjs +36 -0
  31. package/dist/chunks/chunk-2MC7XJSE.js +98 -0
  32. package/dist/chunks/chunk-2RPRCWKV.mjs +139 -0
  33. package/dist/chunks/chunk-2ZXDXO4I.js +166 -0
  34. package/dist/chunks/chunk-33UFQJIO.mjs +135 -0
  35. package/dist/chunks/chunk-3HHJORN7.mjs +137 -0
  36. package/dist/chunks/chunk-3PCNRCTB.js +61 -0
  37. package/dist/chunks/chunk-3VFBPFZF.mjs +640 -0
  38. package/dist/chunks/chunk-4J3GCZ7W.mjs +102 -0
  39. package/dist/chunks/chunk-54IA2P2Z.mjs +40 -0
  40. package/dist/chunks/chunk-54RBL7J4.mjs +179 -0
  41. package/dist/chunks/chunk-5JHJNN2K.js +83 -0
  42. package/dist/chunks/chunk-5JHN4FCY.mjs +58 -0
  43. package/dist/chunks/chunk-6FMDO6TT.mjs +114 -0
  44. package/dist/chunks/chunk-6H7V2I3X.mjs +270 -0
  45. package/dist/chunks/chunk-7AISZYWL.js +7 -0
  46. package/dist/chunks/chunk-7G65JBTN.js +133 -0
  47. package/dist/chunks/chunk-ADO7PDLY.mjs +66 -0
  48. package/dist/chunks/chunk-AFSEYJZT.js +267 -0
  49. package/dist/chunks/chunk-AOXXE5UQ.mjs +14 -0
  50. package/dist/chunks/chunk-AZ2URLDD.js +39 -0
  51. package/dist/chunks/chunk-B6G5TJRO.js +116 -0
  52. package/dist/chunks/chunk-BLGQHR3M.js +56 -0
  53. package/dist/chunks/chunk-BPUQ2CO2.mjs +48 -0
  54. package/dist/chunks/chunk-BSZ2LN6E.js +129 -0
  55. package/dist/chunks/chunk-CA3SOLI3.mjs +78 -0
  56. package/dist/chunks/chunk-CSJDDREF.js +90 -0
  57. package/dist/chunks/chunk-CVYXRSXT.mjs +8 -0
  58. package/dist/chunks/chunk-CZC76ZD5.js +10 -0
  59. package/dist/chunks/chunk-D6FII7HW.js +202 -0
  60. package/dist/chunks/chunk-DLFV7ZZV.js +112 -0
  61. package/dist/chunks/chunk-DO6VK2QQ.mjs +108 -0
  62. package/dist/chunks/chunk-ECVAVQUY.mjs +243 -0
  63. package/dist/chunks/chunk-EHAUUUWB.mjs +120 -0
  64. package/dist/chunks/chunk-EVOOTSY5.js +59 -0
  65. package/dist/chunks/chunk-GX6GSWX3.mjs +38 -0
  66. package/dist/chunks/chunk-HHXDOKXY.js +108 -0
  67. package/dist/chunks/chunk-HNLI646G.mjs +325 -0
  68. package/dist/chunks/chunk-HUPAHDJ7.js +273 -0
  69. package/dist/chunks/chunk-I252NERB.mjs +21 -0
  70. package/dist/chunks/chunk-IE4DGLMH.js +75 -0
  71. package/dist/chunks/chunk-INP2AH3B.js +27 -0
  72. package/dist/chunks/chunk-IOSIQLZL.js +70 -0
  73. package/dist/chunks/chunk-J5ZKGPBY.js +132 -0
  74. package/dist/chunks/chunk-JNMCYWGY.js +10 -0
  75. package/dist/chunks/chunk-LI7SFBUQ.mjs +89 -0
  76. package/dist/chunks/chunk-LMMON5AU.mjs +81 -0
  77. package/dist/chunks/chunk-LOQXCHKL.js +74 -0
  78. package/dist/chunks/chunk-MA2VCCIY.js +71 -0
  79. package/dist/chunks/chunk-MCKOWMLS.mjs +8 -0
  80. package/dist/chunks/chunk-MRRKW5QN.mjs +108 -0
  81. package/dist/chunks/chunk-MTX7GD3H.js +80 -0
  82. package/dist/chunks/chunk-NFIPQZ4O.js +100 -0
  83. package/dist/chunks/chunk-NHDGKOAM.js +104 -0
  84. package/dist/chunks/chunk-OMN5YQCE.js +143 -0
  85. package/dist/chunks/chunk-OTGS6BDQ.mjs +25 -0
  86. package/dist/chunks/chunk-P2T72N62.mjs +34 -0
  87. package/dist/chunks/chunk-P3DZKXG4.js +116 -0
  88. package/dist/chunks/chunk-QK6NCII4.js +36 -0
  89. package/dist/chunks/chunk-QZ4QR3XV.mjs +142 -0
  90. package/dist/chunks/chunk-RS3SBY3I.js +163 -0
  91. package/dist/chunks/chunk-RX5UKRYK.mjs +76 -0
  92. package/dist/chunks/chunk-SGNRVYYQ.mjs +99 -0
  93. package/dist/chunks/chunk-SJMCPSVH.mjs +76 -0
  94. package/dist/chunks/chunk-T2IY2TSR.js +43 -0
  95. package/dist/chunks/chunk-U53UA76K.js +653 -0
  96. package/dist/chunks/chunk-U56AGSLE.mjs +106 -0
  97. package/dist/chunks/chunk-ULGYTBCT.mjs +47 -0
  98. package/dist/chunks/chunk-V5OTJP6H.mjs +5 -0
  99. package/dist/chunks/chunk-VGO4Z2WH.js +336 -0
  100. package/dist/chunks/chunk-VIGRCJAE.mjs +37 -0
  101. package/dist/chunks/chunk-VVXQZ4XH.mjs +93 -0
  102. package/dist/chunks/chunk-W4GG5A7K.mjs +51 -0
  103. package/dist/chunks/chunk-WKCXACMZ.js +99 -0
  104. package/dist/chunks/chunk-WR55D4ZS.js +80 -0
  105. package/dist/chunks/chunk-X2SHTVZQ.js +89 -0
  106. package/dist/chunks/chunk-XEHFB62A.js +82 -0
  107. package/dist/chunks/chunk-XG6QG65W.mjs +63 -0
  108. package/dist/chunks/chunk-YB5ZKHVB.js +64 -0
  109. package/dist/chunks/chunk-YCG4FZC3.js +167 -0
  110. package/dist/chunks/chunk-YEWKPWK3.mjs +80 -0
  111. package/dist/chunks/chunk-YLO4UKSC.mjs +48 -0
  112. package/dist/chunks/chunk-YZV6FWE7.js +160 -0
  113. package/dist/chunks/chunk-ZWSIIGA3.mjs +58 -0
  114. package/dist/client-only.d.mts +13 -0
  115. package/dist/client-only.d.ts +13 -0
  116. package/dist/client-only.js +11 -0
  117. package/dist/client-only.mjs +2 -0
  118. package/dist/countdown.d.mts +27 -0
  119. package/dist/countdown.d.ts +27 -0
  120. package/dist/countdown.js +16 -0
  121. package/dist/countdown.mjs +3 -0
  122. package/dist/counter.d.mts +15 -0
  123. package/dist/counter.d.ts +15 -0
  124. package/dist/counter.js +11 -0
  125. package/dist/counter.mjs +2 -0
  126. package/dist/data-list.d.mts +33 -0
  127. package/dist/data-list.d.ts +33 -0
  128. package/dist/data-list.js +14 -0
  129. package/dist/data-list.mjs +5 -0
  130. package/dist/divider.d.mts +14 -0
  131. package/dist/divider.d.ts +14 -0
  132. package/dist/divider.js +16 -0
  133. package/dist/divider.mjs +3 -0
  134. package/dist/drawer.d.mts +42 -0
  135. package/dist/drawer.d.ts +42 -0
  136. package/dist/drawer.js +44 -0
  137. package/dist/drawer.mjs +3 -0
  138. package/dist/ellipsis.d.mts +16 -0
  139. package/dist/ellipsis.d.ts +16 -0
  140. package/dist/ellipsis.js +12 -0
  141. package/dist/ellipsis.mjs +3 -0
  142. package/dist/error-boundary.d.mts +20 -0
  143. package/dist/error-boundary.d.ts +20 -0
  144. package/dist/error-boundary.js +11 -0
  145. package/dist/error-boundary.mjs +2 -0
  146. package/dist/hooks/useCheckDevice.d.mts +47 -0
  147. package/dist/hooks/useCheckDevice.d.ts +47 -0
  148. package/dist/hooks/useCheckDevice.js +8 -0
  149. package/dist/hooks/useCheckDevice.mjs +2 -0
  150. package/dist/hooks/useClickOutside.d.mts +12 -0
  151. package/dist/hooks/useClickOutside.d.ts +12 -0
  152. package/dist/hooks/useClickOutside.js +8 -0
  153. package/dist/hooks/useClickOutside.mjs +2 -0
  154. package/dist/hooks/useDraggableBottomSheet.d.mts +24 -0
  155. package/dist/hooks/useDraggableBottomSheet.d.ts +24 -0
  156. package/dist/hooks/useDraggableBottomSheet.js +11 -0
  157. package/dist/hooks/useDraggableBottomSheet.mjs +2 -0
  158. package/dist/hooks/useDraggableWindow.d.mts +21 -0
  159. package/dist/hooks/useDraggableWindow.d.ts +21 -0
  160. package/dist/hooks/useDraggableWindow.js +11 -0
  161. package/dist/hooks/useDraggableWindow.mjs +2 -0
  162. package/dist/hooks/useInView.d.mts +14 -0
  163. package/dist/hooks/useInView.d.ts +14 -0
  164. package/dist/hooks/useInView.js +17 -0
  165. package/dist/hooks/useInView.mjs +2 -0
  166. package/dist/hooks/useModal.d.mts +2 -0
  167. package/dist/hooks/useModal.d.ts +2 -0
  168. package/dist/hooks/useModal.js +11 -0
  169. package/dist/hooks/useModal.mjs +2 -0
  170. package/dist/index.d.mts +76 -0
  171. package/dist/index.d.ts +76 -0
  172. package/dist/index.js +746 -0
  173. package/dist/index.mjs +328 -0
  174. package/dist/infinite-scroll.d.mts +26 -0
  175. package/dist/infinite-scroll.d.ts +26 -0
  176. package/dist/infinite-scroll.js +12 -0
  177. package/dist/infinite-scroll.mjs +3 -0
  178. package/dist/marquee.d.mts +12 -0
  179. package/dist/marquee.d.ts +12 -0
  180. package/dist/marquee.js +12 -0
  181. package/dist/marquee.mjs +3 -0
  182. package/dist/modal/index.d.mts +87 -0
  183. package/dist/modal/index.d.ts +87 -0
  184. package/dist/modal/index.js +54 -0
  185. package/dist/modal/index.mjs +9 -0
  186. package/dist/number-input.d.mts +38 -0
  187. package/dist/number-input.d.ts +38 -0
  188. package/dist/number-input.js +20 -0
  189. package/dist/number-input.mjs +3 -0
  190. package/dist/pagination.d.mts +22 -0
  191. package/dist/pagination.d.ts +22 -0
  192. package/dist/pagination.js +20 -0
  193. package/dist/pagination.mjs +3 -0
  194. package/dist/popover.d.mts +25 -0
  195. package/dist/popover.d.ts +25 -0
  196. package/dist/popover.js +32 -0
  197. package/dist/popover.mjs +3 -0
  198. package/dist/radio-group.d.mts +29 -0
  199. package/dist/radio-group.d.ts +29 -0
  200. package/dist/radio-group.js +24 -0
  201. package/dist/radio-group.mjs +3 -0
  202. package/dist/schemas/_all.json +2250 -0
  203. package/dist/schemas/accordion.json +101 -0
  204. package/dist/schemas/avatar.json +55 -0
  205. package/dist/schemas/button.json +71 -0
  206. package/dist/schemas/carousel.json +32 -0
  207. package/dist/schemas/carouselButton.json +20 -0
  208. package/dist/schemas/carouselDots.json +17 -0
  209. package/dist/schemas/carouselSlide.json +20 -0
  210. package/dist/schemas/checkBox.json +57 -0
  211. package/dist/schemas/chip.json +49 -0
  212. package/dist/schemas/clientOnly.json +19 -0
  213. package/dist/schemas/countdown.json +58 -0
  214. package/dist/schemas/counter.json +57 -0
  215. package/dist/schemas/dataList.json +56 -0
  216. package/dist/schemas/divider.json +40 -0
  217. package/dist/schemas/drawer.json +27 -0
  218. package/dist/schemas/drawerContent.json +50 -0
  219. package/dist/schemas/ellipsis.json +49 -0
  220. package/dist/schemas/errorBoundary.json +22 -0
  221. package/dist/schemas/infiniteScroll.json +65 -0
  222. package/dist/schemas/marquee.json +46 -0
  223. package/dist/schemas/modalCall.json +21 -0
  224. package/dist/schemas/modalTemplate.json +123 -0
  225. package/dist/schemas/numberInput.json +77 -0
  226. package/dist/schemas/pagination.json +50 -0
  227. package/dist/schemas/popover.json +67 -0
  228. package/dist/schemas/radioGroup.json +61 -0
  229. package/dist/schemas/radioItem.json +35 -0
  230. package/dist/schemas/select.json +62 -0
  231. package/dist/schemas/selectItem.json +31 -0
  232. package/dist/schemas/skeleton.json +48 -0
  233. package/dist/schemas/spinner.json +27 -0
  234. package/dist/schemas/switch.json +41 -0
  235. package/dist/schemas/tab.json +89 -0
  236. package/dist/schemas/table.json +75 -0
  237. package/dist/schemas/tableRow.json +32 -0
  238. package/dist/schemas/tdColumn.json +107 -0
  239. package/dist/schemas/textArea.json +44 -0
  240. package/dist/schemas/textInput.json +67 -0
  241. package/dist/schemas/themeProvider.json +65 -0
  242. package/dist/schemas/toaster.json +31 -0
  243. package/dist/schemas/tooltip.json +67 -0
  244. package/dist/schemas/virtualGrid.json +59 -0
  245. package/dist/schemas/virtualList.json +54 -0
  246. package/dist/schemas.d.mts +1263 -0
  247. package/dist/schemas.d.ts +1263 -0
  248. package/dist/schemas.js +513 -0
  249. package/dist/schemas.mjs +469 -0
  250. package/dist/select.d.mts +31 -0
  251. package/dist/select.d.ts +31 -0
  252. package/dist/select.js +24 -0
  253. package/dist/select.mjs +3 -0
  254. package/dist/skeleton.d.mts +15 -0
  255. package/dist/skeleton.d.ts +15 -0
  256. package/dist/skeleton.js +12 -0
  257. package/dist/skeleton.mjs +3 -0
  258. package/dist/spinner.d.mts +9 -0
  259. package/dist/spinner.d.ts +9 -0
  260. package/dist/spinner.js +12 -0
  261. package/dist/spinner.mjs +3 -0
  262. package/dist/styles/layer.d.mts +3 -0
  263. package/dist/styles/layer.d.ts +3 -0
  264. package/dist/styles/layer.js +18 -0
  265. package/dist/styles/layer.mjs +16 -0
  266. package/dist/styles.css +2401 -0
  267. package/dist/styles.d.mts +3 -0
  268. package/dist/styles.d.ts +3 -0
  269. package/dist/styles.js +16 -0
  270. package/dist/styles.layered.css +2404 -0
  271. package/dist/styles.mjs +14 -0
  272. package/dist/switch.d.mts +15 -0
  273. package/dist/switch.d.ts +15 -0
  274. package/dist/switch.js +16 -0
  275. package/dist/switch.mjs +3 -0
  276. package/dist/tab.d.mts +36 -0
  277. package/dist/tab.d.ts +36 -0
  278. package/dist/tab.js +20 -0
  279. package/dist/tab.mjs +3 -0
  280. package/dist/table.d.mts +80 -0
  281. package/dist/table.d.ts +80 -0
  282. package/dist/table.js +33 -0
  283. package/dist/table.mjs +4 -0
  284. package/dist/text-area.d.mts +15 -0
  285. package/dist/text-area.d.ts +15 -0
  286. package/dist/text-area.js +16 -0
  287. package/dist/text-area.mjs +3 -0
  288. package/dist/text-input.d.mts +21 -0
  289. package/dist/text-input.d.ts +21 -0
  290. package/dist/text-input.js +16 -0
  291. package/dist/text-input.mjs +3 -0
  292. package/dist/theme-provider.d.mts +25 -0
  293. package/dist/theme-provider.d.ts +25 -0
  294. package/dist/theme-provider.js +15 -0
  295. package/dist/theme-provider.mjs +2 -0
  296. package/dist/toast.d.mts +42 -0
  297. package/dist/toast.d.ts +42 -0
  298. package/dist/toast.js +20 -0
  299. package/dist/toast.mjs +3 -0
  300. package/dist/tooltip.d.mts +24 -0
  301. package/dist/tooltip.d.ts +24 -0
  302. package/dist/tooltip.js +20 -0
  303. package/dist/tooltip.mjs +3 -0
  304. package/dist/useModal-BsGIcP8t.d.mts +128 -0
  305. package/dist/useModal-BsGIcP8t.d.ts +128 -0
  306. package/dist/utils/cn.d.mts +5 -0
  307. package/dist/utils/cn.d.ts +5 -0
  308. package/dist/utils/cn.js +11 -0
  309. package/dist/utils/cn.mjs +2 -0
  310. package/dist/utils/scroll.d.mts +4 -0
  311. package/dist/utils/scroll.d.ts +4 -0
  312. package/dist/utils/scroll.js +15 -0
  313. package/dist/utils/scroll.mjs +2 -0
  314. package/dist/virtual-scroll.d.mts +34 -0
  315. package/dist/virtual-scroll.d.ts +34 -0
  316. package/dist/virtual-scroll.js +16 -0
  317. package/dist/virtual-scroll.mjs +3 -0
  318. package/package.json +291 -0
  319. package/scripts/setup-cursor-rules.cjs +92 -0
@@ -0,0 +1,292 @@
1
+ ---
2
+ description: "NEXUS Design System 프로젝트 설정 — 이 프로젝트의 기술 스택과 필수 규칙"
3
+ alwaysApply: true
4
+ ---
5
+
6
+ # NEXUS Design System 프로젝트 설정
7
+
8
+ 이 프로젝트는 NEXUS Design System을 사용한다. 코드를 생성할 때 반드시 아래를 따른다.
9
+
10
+ ## 기술 스택
11
+
12
+ - **디자인 토큰**: `@nexus-cross/tokens` (CSS 변수 기반)
13
+ - **UI 컴포넌트**: `@nexus-cross/design-system` (React, CVA + Plain CSS)
14
+ - **스타일링**: Tailwind CSS v4 + NEXUS 시맨틱 토큰
15
+
16
+ ## 디자인 시스템 CSS 설정
17
+
18
+ UI 컴포넌트 스타일은 사용처 환경에 따라 두 가지 entry point 중 하나를 선택한다.
19
+
20
+ | 환경 | import | 설명 |
21
+ |---|---|---|
22
+ | Tailwind v3 / Plain CSS / CSS Modules | `@nexus-cross/design-system/styles` | unlayered CSS |
23
+ | Tailwind v4 | `@nexus-cross/design-system/styles/layer` | `@layer nexus`로 래핑 |
24
+
25
+ ```tsx
26
+ // Tailwind v3, Plain CSS, CSS Modules
27
+ import '@nexus-cross/design-system/styles'
28
+
29
+ // Tailwind v4
30
+ import '@nexus-cross/design-system/styles/layer'
31
+ ```
32
+
33
+ Tailwind v4 프로젝트는 `globals.css`에 layer 순서도 선언한다:
34
+ ```css
35
+ @layer base, nexus, components, utilities;
36
+ ```
37
+
38
+ ## 절대 규칙
39
+
40
+ 1. **색상은 반드시 NEXUS 토큰을 사용한다.** 하드코딩 금지.
41
+ - `bg-bg-default`, `text-text-primary`, `border-border-default` 등
42
+ - `#ffffff`, `#000000`, `rgb()` 등 직접 색상값 사용 금지
43
+ - 참고: `.cursor/rules/nexus-tokens.mdc`
44
+
45
+ 2. **UI 컴포넌트는 반드시 `@nexus-cross/design-system`에서 import한다.** 직접 구현 금지.
46
+ - `<Button>`, `<TextInput>`, `<Modal>`, `<Toast>` 등
47
+ - Radix UI, Headless UI 등을 직접 import하여 동일 기능 컴포넌트를 만들지 않는다
48
+ - 참고: `.cursor/rules/nexus-ui-components.mdc`, `.cursor/rules/nexus-ui-api.mdc`
49
+
50
+ 3. **Figma 디자인 구현 시:**
51
+ - NEXUS 토큰과 공용 UI를 적극 활용하되, **Figma 디자인에 충실하게** 구현한다
52
+ - Figma의 색상값을 보고 가장 가까운 NEXUS 토큰으로 매핑한다
53
+ - Figma의 UI 요소(버튼, 입력필드 등)는 `@nexus-cross/design-system` 컴포넌트로 구현한다
54
+ - Figma 디자인과 공용 UI의 스타일이 다를 경우, `className`으로 Figma에 맞게 오버라이드한다
55
+ - Figma에 없는 커스텀 스타일만 Tailwind 유틸리티로 작성한다
56
+
57
+ ## Figma MCP → NEXUS 변환 워크플로우
58
+
59
+ **Figma MCP 도구(get_design_context, get_code 등)의 출력을 절대 그대로 사용하지 않는다.**
60
+ Figma MCP는 바닐라 HTML + Tailwind를 출력하지만, 이 프로젝트는 `@nexus-cross/design-system`을 사용한다.
61
+ **MCP 출력은 "디자인 의도를 파악하는 참고 자료"일 뿐, 최종 코드가 아니다.**
62
+
63
+ ### 필수 3단계 워크플로우
64
+
65
+ **1단계: 디자인 분석 (MCP 호출)**
66
+ - `get_design_context`로 구조와 레이아웃 파악
67
+ - `get_screenshot`으로 시각적 참조 확인
68
+ - 이 단계에서 MCP가 출력하는 코드는 **읽기만 하고 사용하지 않는다**
69
+
70
+ **2단계: 컴포넌트 매핑 (코드 작성 전에 반드시 수행)**
71
+ MCP 출력의 각 요소를 NEXUS 컴포넌트로 매핑한다. **코드를 한 줄이라도 쓰기 전에** 이 매핑을 먼저 완료한다.
72
+
73
+ ```
74
+ MCP 출력 분석:
75
+ - <button> 2개 발견 → Button (primary, ghost)
76
+ - <input type="text"> 1개 → TextInput
77
+ - <select> 1개 → Select + SelectItem
78
+ - 색상 #09B498 → bg-accent-primary (NEXUS 토큰)
79
+ - 색상 #1E232E → text-text-primary (NEXUS 토큰)
80
+ - 간격 16px → var(--spacing-padding-md)
81
+ ```
82
+
83
+ **3단계: NEXUS 코드 생성**
84
+ 매핑을 기반으로 코드를 작성한다. 이 단계에서는 MCP 출력 코드를 참조하지 않는다.
85
+
86
+ ### 컴포넌트 변환 테이블
87
+
88
+ | MCP 출력 (네이티브 HTML) | → NEXUS 컴포넌트 |
89
+ |---|---|
90
+ | `<button>`, `<a>` 버튼 스타일 | `<Button>` (variant, size 지정) |
91
+ | `<input type="text">` | `<TextInput>` (prefixIcon, suffixIcon 지원) |
92
+ | `<textarea>` | `<TextArea>` (showCount, maxLength 지원) |
93
+ | `<input type="number">` | `<NumberInput>` |
94
+ | `<select>` | `<Select>` + `<SelectItem>` |
95
+ | `<input type="checkbox">` | `<CheckBox>` |
96
+ | `<input type="radio">` | `<RadioGroup>` + `<RadioItem>` |
97
+ | 토글/스위치 UI | `<Switch>` |
98
+ | 탭 UI | `<Tab>` (items 배열로 구성) |
99
+ | 칩/태그/필터/뱃지 | `<Chip>` (variant, onClose 지원) |
100
+ | 아바타/프로필 이미지 | `<Avatar>` (fallback, shape 지원) |
101
+ | 구분선/`<hr>` | `<Divider>` (orientation, variant 지정) |
102
+ | 드롭다운 메뉴 | `<Select>` 또는 `<Popover>` |
103
+ | 툴팁 | `<Tooltip>` |
104
+ | 아코디언/접기 | `<Accordion>` |
105
+ | 캐러셀/슬라이더 | `<Carousel>` + `<CarouselSlide>` |
106
+ | 페이지네이션 | `<Pagination>` |
107
+ | 모달/다이얼로그 | `modal()` + `<ModalTemplate>` |
108
+ | 토스트/알림 | `toast()` |
109
+ | 드로어/바텀시트 | `<Drawer>` |
110
+ | 로딩 스피너 | `<Spinner>` |
111
+ | 스켈레톤 로딩 | `<Skeleton>` |
112
+ | 데이터 리스트 | `<DataList>` |
113
+ | 테이블 | `<Table>` + `<TableRow>` + `<TdColumn>` |
114
+ | 숫자 카운트 애니메이션 | `<Counter>` |
115
+ | 카운트다운 타이머 | `<Countdown>` |
116
+ | 텍스트 말줄임 | `<Ellipsis>` |
117
+ | 흐르는 텍스트 | `<Marquee>` |
118
+ | 무한 스크롤 리스트 | `<InfiniteScroll>` |
119
+ | 대량 리스트 (가상 스크롤) | `<VirtualList>` / `<VirtualGrid>` |
120
+
121
+ **위 교체를 하지 않고 네이티브 HTML을 사용하면 규칙 위반이다.**
122
+
123
+ ### 색상 변환 테이블
124
+
125
+ MCP가 출력하는 색상값을 NEXUS 토큰으로 변환한다:
126
+
127
+ | MCP 출력 색상 | → NEXUS 토큰 |
128
+ |---|---|
129
+ | `#FFFFFF`, `bg-white` | `bg-bg-default` |
130
+ | `#F3F6F8`, `bg-gray-50` | `bg-bg-subtle` |
131
+ | `#1E232E`, `text-gray-900` | `text-text-primary` |
132
+ | `#7E8597`, `text-gray-500` | `text-text-secondary` |
133
+ | `#A2AABA`, `text-gray-400` | `text-text-muted` |
134
+ | `#ECF0F2`, `border-gray-200` | `border-border-default` |
135
+ | `#09B498`, `bg-green-*`, `bg-teal-*` | `bg-accent-primary` |
136
+ | `#7346F3`, `bg-purple-*`, `bg-violet-*` | `bg-accent-secondary` |
137
+ | `#DB0A2D`, `bg-red-*` | `bg-status-danger` |
138
+ | `#00B784` | `bg-status-success` |
139
+ | `#FF9D00`, `bg-amber-*` | `bg-status-warning` |
140
+ | `#0095FF`, `bg-blue-*` | `bg-status-info` |
141
+
142
+ 위에 정확히 매칭되지 않는 색상은 가장 가까운 NEXUS 토큰을 선택한다.
143
+ **어떤 경우에도 hex 값이나 Tailwind 기본 색상(bg-blue-500 등)을 사용하지 않는다.**
144
+
145
+ ### Button variant 판단 기준
146
+
147
+ Figma에서 버튼의 시각적 스타일을 보고 variant를 결정한다:
148
+
149
+ | Figma 시각적 특징 | → variant |
150
+ |---|---|
151
+ | 채워진 accent 색상 배경 (초록/틸) | `variant="primary"` |
152
+ | 채워진 회색/중립 배경 | `variant="secondary"` |
153
+ | 테두리만 있고 배경 투명 | `variant="outline"` |
154
+ | 배경/테두리 없이 텍스트만 | `variant="ghost"` |
155
+ | 빨간색/위험 표시 | `variant="danger"` |
156
+
157
+ ### 자기 검증 체크리스트
158
+
159
+ 코드를 출력하기 전에 아래를 확인한다:
160
+
161
+ - [ ] `<button>`, `<input>`, `<select>`, `<textarea>` 등 네이티브 HTML 폼 요소가 없는가?
162
+ - [ ] hex 색상값(`#...`)이 없는가?
163
+ - [ ] Tailwind 기본 색상(`bg-blue-500`, `text-gray-900` 등)이 없는가?
164
+ - [ ] 모든 import가 `@nexus-cross/design-system`에서 오는가?
165
+ - [ ] 모달은 `ModalTemplate`으로 감쌌는가?
166
+ - [ ] 간격/크기에 하드코딩 px이 없는가?
167
+
168
+ **하나라도 실패하면 코드를 수정한 후 출력한다.**
169
+
170
+ ```tsx
171
+ // ❌ Figma MCP 코드 그대로 사용 (금지)
172
+ <button className="bg-[#09B498] text-white px-4 py-2 rounded-lg">확인</button>
173
+ <input className="border border-[#C6D0DA] px-3 py-2 rounded" placeholder="검색" />
174
+ <div className="w-8 h-8 rounded-full bg-gray-200" /> {/* 아바타 */}
175
+ <hr className="border-[#ECF0F2]" /> {/* 구분선 */}
176
+
177
+ // ✅ NEXUS 컴포넌트로 교체 (필수)
178
+ <Button variant="primary">확인</Button>
179
+ <TextInput placeholder="검색" prefixIcon={<SearchIcon />} />
180
+ <Avatar fallback="JD" size="sm" />
181
+ <Divider />
182
+ ```
183
+
184
+ ## 전역 설정 (앱 루트에 필수)
185
+
186
+ 아래 컴포넌트를 앱 루트(layout.tsx 또는 App.tsx)에 **반드시** 배치한다.
187
+
188
+ | 컴포넌트 | import | 필수 조건 | 설명 |
189
+ |----------|--------|----------|------|
190
+ | `<ModalContainer />` | `@nexus-cross/design-system/modal` | `modal()` 또는 `useModal()` 사용 시 | 모달 렌더링 컨테이너 |
191
+ | `<Toaster />` | `@nexus-cross/design-system` | `toast()` 사용 시 | 토스트 알림 렌더링 |
192
+
193
+ ```tsx
194
+ // layout.tsx 또는 App.tsx
195
+ import { ModalContainer } from '@nexus-cross/design-system/modal';
196
+ import { Toaster } from '@nexus-cross/design-system';
197
+
198
+ export default function RootLayout({ children }) {
199
+ return (
200
+ <>
201
+ {children}
202
+ <ModalContainer />
203
+ <Toaster position="top-right" />
204
+ </>
205
+ );
206
+ }
207
+ ```
208
+
209
+ **전역 설정이 필요 없는 컴포넌트** (별도 Provider 없이 바로 사용 가능):
210
+ - Tooltip (내부에 Provider 내장)
211
+ - Popover, Drawer, Select, Accordion 등 모든 나머지 컴포넌트
212
+
213
+ ## Import 패턴
214
+
215
+ ```tsx
216
+ // 일반 컴포넌트
217
+ import { Button, TextInput, TextArea, Select, Switch, Chip, Spinner, Divider } from '@nexus-cross/design-system';
218
+
219
+ // 오버레이 컴포넌트
220
+ import { Tooltip, Popover, Drawer, Accordion } from '@nexus-cross/design-system';
221
+
222
+ // 토스트
223
+ import { toast, Toaster } from '@nexus-cross/design-system';
224
+
225
+ // 모달 시스템 (별도 서브패스)
226
+ import { modal, useModal, ModalTemplate, ModalContainer } from '@nexus-cross/design-system/modal';
227
+
228
+ // 토큰 (JS API가 필요한 경우만)
229
+ import { getTheme } from '@nexus-cross/tokens';
230
+ ```
231
+
232
+ ## 모달 작성 규칙
233
+
234
+ 모달 컴포넌트는 **반드시 `ModalTemplate`으로 감싸야 한다.** `<div>`만으로 모달을 만들지 않는다.
235
+
236
+ ```tsx
237
+ // ✅ 올바른 모달
238
+ import { ModalTemplate } from '@nexus-cross/design-system/modal';
239
+
240
+ function MyModal({ close, resolve }: { close: () => void; resolve: (value: any) => void }) {
241
+ return (
242
+ <ModalTemplate title="제목" close={close}>
243
+ <p className="text-text-secondary">내용</p>
244
+ <Button onClick={() => resolve({ confirmed: true })}>확인</Button>
245
+ </ModalTemplate>
246
+ );
247
+ }
248
+
249
+ // 호출
250
+ const result = await modal({ component: MyModal });
251
+ ```
252
+
253
+ ```tsx
254
+ // ❌ 잘못된 모달 — ModalTemplate 없이 div만 사용
255
+ function MyModal({ close }: { close: () => void }) {
256
+ return (
257
+ <div className="p-6 bg-white rounded-lg">
258
+ <h2>제목</h2>
259
+ <p>내용</p>
260
+ </div>
261
+ );
262
+ }
263
+ ```
264
+
265
+ ## 토스트 사용 규칙
266
+
267
+ ```tsx
268
+ import { toast } from '@nexus-cross/design-system';
269
+
270
+ toast('기본 메시지');
271
+ toast.success('성공!');
272
+ toast.error('오류가 발생했습니다');
273
+ toast.loading('처리 중...');
274
+ ```
275
+
276
+ 루트에 `<Toaster />` 없이 `toast()`를 호출하면 아무것도 표시되지 않는다.
277
+
278
+ ## 토큰 사용 예시
279
+
280
+ ```tsx
281
+ // ✅ 올바른 사용
282
+ <div className="bg-bg-default text-text-primary border border-border-default">
283
+ <Button variant="primary">확인</Button>
284
+ <TextInput placeholder="검색..." />
285
+ </div>
286
+
287
+ // ❌ 잘못된 사용
288
+ <div className="bg-white text-gray-900 border border-gray-200">
289
+ <button className="bg-green-500 text-white px-4 py-2 rounded">확인</button>
290
+ <input className="border border-gray-300 px-3 py-2" placeholder="검색..." />
291
+ </div>
292
+ ```