@conscience-technology/ctds 0.0.0-stage → 0.1.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 (289) hide show
  1. package/README.md +128 -2
  2. package/assets/components/AppFrame/AppFrame.module.css +177 -0
  3. package/assets/components/AppFrame/AppFrame.tsx +93 -0
  4. package/assets/components/AppFrame/index.ts +6 -0
  5. package/assets/components/AttachmentChip/AttachmentChip.module.css +71 -0
  6. package/assets/components/AttachmentChip/AttachmentChip.tsx +74 -0
  7. package/assets/components/AttachmentChip/index.ts +2 -0
  8. package/assets/components/AttachmentThumb/AttachmentThumb.module.css +107 -0
  9. package/assets/components/AttachmentThumb/AttachmentThumb.tsx +91 -0
  10. package/assets/components/AttachmentThumb/index.ts +2 -0
  11. package/assets/components/Avatar/Avatar.module.css +167 -0
  12. package/assets/components/Avatar/Avatar.tsx +228 -0
  13. package/assets/components/Avatar/index.ts +2 -0
  14. package/assets/components/AvatarUpload/AvatarUpload.module.css +130 -0
  15. package/assets/components/AvatarUpload/AvatarUpload.tsx +139 -0
  16. package/assets/components/AvatarUpload/index.ts +2 -0
  17. package/assets/components/Badge/Badge.module.css +76 -0
  18. package/assets/components/Badge/Badge.tsx +68 -0
  19. package/assets/components/Badge/index.ts +2 -0
  20. package/assets/components/Breadcrumb/Breadcrumb.module.css +213 -0
  21. package/assets/components/Breadcrumb/Breadcrumb.tsx +279 -0
  22. package/assets/components/Breadcrumb/index.ts +8 -0
  23. package/assets/components/Button/Button.module.css +216 -0
  24. package/assets/components/Button/Button.tsx +149 -0
  25. package/assets/components/Button/index.ts +2 -0
  26. package/assets/components/Callout/Callout.module.css +146 -0
  27. package/assets/components/Callout/Callout.tsx +138 -0
  28. package/assets/components/Callout/index.ts +2 -0
  29. package/assets/components/ChatInput/ChatInput.module.css +241 -0
  30. package/assets/components/ChatInput/ChatInput.tsx +322 -0
  31. package/assets/components/ChatInput/ModelSelector.tsx +40 -0
  32. package/assets/components/ChatInput/SendButton.tsx +41 -0
  33. package/assets/components/ChatInput/index.ts +10 -0
  34. package/assets/components/Checkbox/Checkbox.module.css +66 -0
  35. package/assets/components/Checkbox/Checkbox.tsx +36 -0
  36. package/assets/components/Checkbox/index.ts +2 -0
  37. package/assets/components/Chip/Chip.module.css +128 -0
  38. package/assets/components/Chip/Chip.tsx +103 -0
  39. package/assets/components/Chip/index.ts +2 -0
  40. package/assets/components/ChoiceCard/ChoiceCard.module.css +142 -0
  41. package/assets/components/ChoiceCard/ChoiceCard.tsx +132 -0
  42. package/assets/components/ChoiceCard/index.ts +2 -0
  43. package/assets/components/ContextMenu/ContextMenu.module.css +102 -0
  44. package/assets/components/ContextMenu/ContextMenu.tsx +392 -0
  45. package/assets/components/ContextMenu/index.ts +9 -0
  46. package/assets/components/DatePicker/Calendar.tsx +234 -0
  47. package/assets/components/DatePicker/DESIGN_NOTES.md +106 -0
  48. package/assets/components/DatePicker/DESIGN_NOTES_TIME.md +125 -0
  49. package/assets/components/DatePicker/DatePicker.module.css +295 -0
  50. package/assets/components/DatePicker/DatePicker.tsx +387 -0
  51. package/assets/components/DatePicker/TimeSelector.tsx +69 -0
  52. package/assets/components/DatePicker/index.ts +8 -0
  53. package/assets/components/DatePicker/presets.ts +80 -0
  54. package/assets/components/DatePicker/utils.ts +148 -0
  55. package/assets/components/Disclosure/Disclosure.module.css +73 -0
  56. package/assets/components/Disclosure/Disclosure.tsx +129 -0
  57. package/assets/components/Disclosure/index.ts +6 -0
  58. package/assets/components/Drawer/Drawer.module.css +257 -0
  59. package/assets/components/Drawer/Drawer.tsx +126 -0
  60. package/assets/components/Drawer/index.ts +7 -0
  61. package/assets/components/EmptyState/EmptyState.module.css +102 -0
  62. package/assets/components/EmptyState/EmptyState.tsx +80 -0
  63. package/assets/components/EmptyState/index.ts +2 -0
  64. package/assets/components/FileIcon/FileIcon.module.css +66 -0
  65. package/assets/components/FileIcon/FileIcon.tsx +84 -0
  66. package/assets/components/FileIcon/fileExtMap.ts +112 -0
  67. package/assets/components/FileIcon/index.ts +9 -0
  68. package/assets/components/FilterButton/FilterButton.module.css +130 -0
  69. package/assets/components/FilterButton/FilterButton.tsx +94 -0
  70. package/assets/components/FilterButton/index.ts +2 -0
  71. package/assets/components/GalleryItem/GalleryItem.module.css +220 -0
  72. package/assets/components/GalleryItem/GalleryItem.tsx +163 -0
  73. package/assets/components/GalleryItem/index.ts +7 -0
  74. package/assets/components/Icon/Icon.tsx +616 -0
  75. package/assets/components/Icon/context.tsx +39 -0
  76. package/assets/components/Icon/index.ts +4 -0
  77. package/assets/components/IconButton/IconButton.module.css +109 -0
  78. package/assets/components/IconButton/IconButton.tsx +110 -0
  79. package/assets/components/IconButton/index.ts +2 -0
  80. package/assets/components/Input/Input.module.css +338 -0
  81. package/assets/components/Input/Input.tsx +371 -0
  82. package/assets/components/Input/index.ts +2 -0
  83. package/assets/components/ListItem/ListItem.module.css +318 -0
  84. package/assets/components/ListItem/ListItem.tsx +262 -0
  85. package/assets/components/ListItem/index.ts +9 -0
  86. package/assets/components/MenuItem/MenuItem.module.css +437 -0
  87. package/assets/components/MenuItem/MenuItem.tsx +529 -0
  88. package/assets/components/MenuItem/index.ts +8 -0
  89. package/assets/components/MetricCard/MetricCard.module.css +153 -0
  90. package/assets/components/MetricCard/MetricCard.tsx +140 -0
  91. package/assets/components/MetricCard/index.ts +2 -0
  92. package/assets/components/Modal/Modal.module.css +175 -0
  93. package/assets/components/Modal/Modal.tsx +98 -0
  94. package/assets/components/Modal/index.ts +2 -0
  95. package/assets/components/Onboarding/DocsIndex.tsx +82 -0
  96. package/assets/components/Onboarding/LayoutBuilder.tsx +160 -0
  97. package/assets/components/Onboarding/Onboarding.module.css +1394 -0
  98. package/assets/components/Onboarding/OnboardingAxisPanel.tsx +515 -0
  99. package/assets/components/Onboarding/OnboardingPage.tsx +1193 -0
  100. package/assets/components/Onboarding/PresetsGallery.tsx +65 -0
  101. package/assets/components/Onboarding/actions.ts +250 -0
  102. package/assets/components/Onboarding/index.ts +8 -0
  103. package/assets/components/Onboarding/palette.css +40 -0
  104. package/assets/components/Onboarding/wizardData.ts +265 -0
  105. package/assets/components/Pagination/Pagination.module.css +82 -0
  106. package/assets/components/Pagination/Pagination.tsx +248 -0
  107. package/assets/components/Pagination/index.ts +6 -0
  108. package/assets/components/ProgressBar/ProgressBar.module.css +64 -0
  109. package/assets/components/ProgressBar/ProgressBar.tsx +54 -0
  110. package/assets/components/ProgressBar/index.ts +2 -0
  111. package/assets/components/QuotationBar/QuotationBar.module.css +61 -0
  112. package/assets/components/QuotationBar/QuotationBar.tsx +48 -0
  113. package/assets/components/QuotationBar/index.ts +2 -0
  114. package/assets/components/Radio/Radio.module.css +63 -0
  115. package/assets/components/Radio/Radio.tsx +33 -0
  116. package/assets/components/Radio/index.ts +2 -0
  117. package/assets/components/Select/Select.module.css +151 -0
  118. package/assets/components/Select/Select.tsx +425 -0
  119. package/assets/components/Select/index.ts +10 -0
  120. package/assets/components/SelectableCard/SelectableCard.module.css +177 -0
  121. package/assets/components/SelectableCard/SelectableCard.tsx +83 -0
  122. package/assets/components/SelectableCard/index.ts +2 -0
  123. package/assets/components/Shortcut/Shortcut.module.css +56 -0
  124. package/assets/components/Shortcut/Shortcut.tsx +156 -0
  125. package/assets/components/Shortcut/index.ts +2 -0
  126. package/assets/components/Sidebar/Sidebar.module.css +242 -0
  127. package/assets/components/Sidebar/Sidebar.tsx +264 -0
  128. package/assets/components/Sidebar/index.ts +7 -0
  129. package/assets/components/SidebarSplit/SidebarSplit.module.css +126 -0
  130. package/assets/components/SidebarSplit/SidebarSplit.tsx +222 -0
  131. package/assets/components/SidebarSplit/index.ts +6 -0
  132. package/assets/components/Slider/Slider.module.css +120 -0
  133. package/assets/components/Slider/Slider.tsx +88 -0
  134. package/assets/components/Slider/index.ts +2 -0
  135. package/assets/components/SplitButton/SplitButton.module.css +190 -0
  136. package/assets/components/SplitButton/SplitButton.tsx +145 -0
  137. package/assets/components/SplitButton/index.ts +6 -0
  138. package/assets/components/Stepper/Stepper.module.css +182 -0
  139. package/assets/components/Stepper/Stepper.tsx +185 -0
  140. package/assets/components/Stepper/index.ts +2 -0
  141. package/assets/components/Switch/Switch.module.css +116 -0
  142. package/assets/components/Switch/Switch.tsx +58 -0
  143. package/assets/components/Switch/index.ts +2 -0
  144. package/assets/components/TableCell/TableCell.module.css +137 -0
  145. package/assets/components/TableCell/TableCellAvatar.tsx +42 -0
  146. package/assets/components/TableCell/TableCellBadge.tsx +23 -0
  147. package/assets/components/TableCell/TableCellIcon.tsx +39 -0
  148. package/assets/components/TableCell/TableCellImage.tsx +49 -0
  149. package/assets/components/TableCell/TableCellLink.tsx +33 -0
  150. package/assets/components/TableCell/TableCellMeter.tsx +55 -0
  151. package/assets/components/TableCell/TableCellNumber.tsx +43 -0
  152. package/assets/components/TableCell/TableCellText.tsx +30 -0
  153. package/assets/components/TableCell/index.ts +23 -0
  154. package/assets/components/TableHeader/TableHeader.module.css +287 -0
  155. package/assets/components/TableHeader/TableHeader.tsx +590 -0
  156. package/assets/components/TableHeader/index.ts +9 -0
  157. package/assets/components/TableRow/TableRow.module.css +290 -0
  158. package/assets/components/TableRow/TableRow.tsx +253 -0
  159. package/assets/components/TableRow/index.ts +8 -0
  160. package/assets/components/TableRowEdit/TableRowEdit.module.css +126 -0
  161. package/assets/components/TableRowEdit/TableRowEdit.tsx +247 -0
  162. package/assets/components/TableRowEdit/index.ts +2 -0
  163. package/assets/components/TableRowSelect/TableRowSelect.module.css +23 -0
  164. package/assets/components/TableRowSelect/TableRowSelect.tsx +175 -0
  165. package/assets/components/TableRowSelect/index.ts +2 -0
  166. package/assets/components/Tabs/Tabs.module.css +234 -0
  167. package/assets/components/Tabs/Tabs.tsx +426 -0
  168. package/assets/components/Tabs/index.ts +9 -0
  169. package/assets/components/Textarea/Textarea.module.css +318 -0
  170. package/assets/components/Textarea/Textarea.tsx +426 -0
  171. package/assets/components/Textarea/index.ts +7 -0
  172. package/assets/components/ThemeController.tsx +271 -0
  173. package/assets/components/TimePicker/TimePicker.module.css +317 -0
  174. package/assets/components/TimePicker/TimePicker.tsx +821 -0
  175. package/assets/components/TimePicker/index.ts +8 -0
  176. package/assets/components/TimePicker/utils.ts +115 -0
  177. package/assets/components/Toast/Toast.module.css +264 -0
  178. package/assets/components/Toast/Toast.tsx +243 -0
  179. package/assets/components/Toast/index.ts +15 -0
  180. package/assets/components/Toolbar/Toolbar.module.css +72 -0
  181. package/assets/components/Toolbar/Toolbar.tsx +75 -0
  182. package/assets/components/Toolbar/index.ts +2 -0
  183. package/assets/components/Tooltip/Tooltip.module.css +42 -0
  184. package/assets/components/Tooltip/Tooltip.tsx +332 -0
  185. package/assets/components/Tooltip/index.ts +2 -0
  186. package/assets/components/Topbar/Topbar.module.css +26 -0
  187. package/assets/components/Topbar/Topbar.tsx +47 -0
  188. package/assets/components/Topbar/index.ts +2 -0
  189. package/assets/components/_cn.ts +3 -0
  190. package/assets/components/_color.ts +48 -0
  191. package/assets/components/_data.ts +659 -0
  192. package/assets/components/_utils.css +19 -0
  193. package/assets/components/axisOptions.ts +24 -0
  194. package/assets/components/tokens.css +742 -0
  195. package/assets/prompts/GUIDE.md +251 -0
  196. package/assets/prompts/OVERRIDE.md +170 -0
  197. package/assets/prompts/PRINCIPLES.md +130 -0
  198. package/assets/prompts/axes/density.md +38 -0
  199. package/assets/prompts/axes/font.md +36 -0
  200. package/assets/prompts/axes/hue.md +36 -0
  201. package/assets/prompts/axes/icon.md +48 -0
  202. package/assets/prompts/axes/mode.md +50 -0
  203. package/assets/prompts/axes/motion.md +77 -0
  204. package/assets/prompts/axes/palette.md +35 -0
  205. package/assets/prompts/axes/shape.md +33 -0
  206. package/assets/prompts/axes/voice.md +54 -0
  207. package/assets/prompts/components/README.md +84 -0
  208. package/assets/prompts/components/app-frame.md +94 -0
  209. package/assets/prompts/components/attachment-chip.md +46 -0
  210. package/assets/prompts/components/attachment-thumb.md +49 -0
  211. package/assets/prompts/components/avatar.md +86 -0
  212. package/assets/prompts/components/badge.md +104 -0
  213. package/assets/prompts/components/breadcrumb.md +77 -0
  214. package/assets/prompts/components/button.md +99 -0
  215. package/assets/prompts/components/callout.md +81 -0
  216. package/assets/prompts/components/chat-input.md +84 -0
  217. package/assets/prompts/components/checkbox.md +46 -0
  218. package/assets/prompts/components/chip.md +84 -0
  219. package/assets/prompts/components/choice-card.md +127 -0
  220. package/assets/prompts/components/context-menu.md +145 -0
  221. package/assets/prompts/components/date-picker.md +104 -0
  222. package/assets/prompts/components/drawer.md +152 -0
  223. package/assets/prompts/components/empty-state.md +69 -0
  224. package/assets/prompts/components/file-icon.md +73 -0
  225. package/assets/prompts/components/filter-button.md +42 -0
  226. package/assets/prompts/components/form-field.md +74 -0
  227. package/assets/prompts/components/gallery-item.md +158 -0
  228. package/assets/prompts/components/icon-button.md +82 -0
  229. package/assets/prompts/components/icon.md +68 -0
  230. package/assets/prompts/components/input.md +95 -0
  231. package/assets/prompts/components/list-item.md +235 -0
  232. package/assets/prompts/components/menu-item.md +234 -0
  233. package/assets/prompts/components/metric-card.md +132 -0
  234. package/assets/prompts/components/modal.md +131 -0
  235. package/assets/prompts/components/pagination.md +92 -0
  236. package/assets/prompts/components/progress-bar.md +61 -0
  237. package/assets/prompts/components/quotation-bar.md +39 -0
  238. package/assets/prompts/components/radio.md +41 -0
  239. package/assets/prompts/components/select.md +104 -0
  240. package/assets/prompts/components/selectable-card.md +67 -0
  241. package/assets/prompts/components/shortcut.md +76 -0
  242. package/assets/prompts/components/sidebar.md +107 -0
  243. package/assets/prompts/components/slider.md +89 -0
  244. package/assets/prompts/components/split-button.md +71 -0
  245. package/assets/prompts/components/stepper.md +93 -0
  246. package/assets/prompts/components/switch.md +86 -0
  247. package/assets/prompts/components/table-cell.md +87 -0
  248. package/assets/prompts/components/table-header.md +157 -0
  249. package/assets/prompts/components/table-row-edit.md +129 -0
  250. package/assets/prompts/components/table-row-select.md +82 -0
  251. package/assets/prompts/components/table-row.md +156 -0
  252. package/assets/prompts/components/tabs.md +122 -0
  253. package/assets/prompts/components/textarea.md +105 -0
  254. package/assets/prompts/components/toast.md +149 -0
  255. package/assets/prompts/components/tooltip.md +71 -0
  256. package/assets/prompts/components/topbar.md +148 -0
  257. package/assets/prompts/primitives/emerge.md +43 -0
  258. package/assets/prompts/primitives/fade.md +31 -0
  259. package/assets/prompts/primitives/scale.md +32 -0
  260. package/assets/prompts/primitives/scroll.md +75 -0
  261. package/assets/prompts/primitives/slide.md +31 -0
  262. package/assets/prompts/themes/_SCHEMA.md +135 -0
  263. package/assets/prompts/themes/_TEMPLATE.md +73 -0
  264. package/assets/prompts/themes/expressive.md +118 -0
  265. package/assets/prompts/themes/pure.md +87 -0
  266. package/assets/prompts/themes/spare.md +73 -0
  267. package/assets/prompts/tokens/breakpoint.md +29 -0
  268. package/assets/prompts/tokens/color.md +78 -0
  269. package/assets/prompts/tokens/radius.md +33 -0
  270. package/assets/prompts/tokens/shadow.md +35 -0
  271. package/assets/prompts/tokens/spacing.md +86 -0
  272. package/assets/prompts/tokens/typography.md +76 -0
  273. package/assets/prompts/tokens/z-index.md +35 -0
  274. package/assets/public/expressive.png +0 -0
  275. package/assets/public/pure.png +0 -0
  276. package/assets/public/spare.png +0 -0
  277. package/assets/skill/SKILL.md +36 -0
  278. package/bin/ctds.js +76 -0
  279. package/package.json +35 -4
  280. package/src/commands/init.js +215 -0
  281. package/src/commands/update.js +275 -0
  282. package/src/utils/assets.js +78 -0
  283. package/src/utils/deps.js +51 -0
  284. package/src/utils/detect.js +47 -0
  285. package/src/utils/diff.js +52 -0
  286. package/src/utils/hash.js +16 -0
  287. package/src/utils/log.js +41 -0
  288. package/src/utils/meta.js +73 -0
  289. package/src/utils/prompt.js +28 -0
@@ -0,0 +1,107 @@
1
+ # Sidebar
2
+
3
+ ### 원칙
4
+ 좌측 세로 nav. **라우팅 전용** — Tabs/필터는 쓸 곳이 아님. Brand(home 링크) + Section(그룹 라벨) + Item(라우트 링크) + Profile(사용자) + Footer가 compound 조합. `collapsed`로 icon-only 축소. Item은 [[components/menu-item]]을 그대로 어댑트 — 시각·상태 규칙 공유.
5
+
6
+ ### Do
7
+ - 라우트 이동은 Item에 `asChild` + Next `<Link>`.
8
+ - 현재 라우트는 `active`로 명시 (MenuItem의 active 시각 그대로).
9
+ - Brand는 Home 링크 자리로. `symbol`(항상 노출) + `wordmark`(expanded만).
10
+ - Section 묶음은 `title`로 그룹. collapsed일 땐 title 자동 숨김.
11
+ - `collapsed` 상태에서는 `aria-label`과 `title`을 자동으로 걸어 접근성 유지.
12
+
13
+ ### Don't
14
+ - 페이지 안 뷰 전환에 쓰지 않는다 — 그건 [[components/tabs]].
15
+ - Item 안에 variant로 다른 톤을 쓰지 않는다. active 외의 강조 금지.
16
+ - Sidebar 자체에 padding/width를 CSS로 덮지 않는다. `--sidebar-w*` 토큰 경유.
17
+ - Brand symbol·wordmark 크기 override 금지. `--sidebar-brand-symbol-max`·`--sidebar-brand-wordmark-max` 상한 안에서만.
18
+
19
+ ### Fallback
20
+ collapsed 결정 애매하면 `false`. Section title 애매하면 생략.
21
+
22
+ ### 관련
23
+ - [[components/menu-item]] — Item 시각·상태 전부 재사용
24
+ - [[components/avatar]] — Profile 왼쪽 아바타
25
+ - [[components/app-frame]] — Sidebar를 담는 grid 쉘
26
+ - [[axes/density]] — `--sidebar-w*` 토큰·control-h가 Density에 반응
27
+ - [[tokens/color]] — `--fg`·`--primary`·active 상태 매핑
28
+
29
+ ### Props 시그니처
30
+ ```tsx
31
+ <Sidebar collapsed={boolean}> // default: false
32
+ <Sidebar.Header>
33
+ <Sidebar.Brand symbol={<Icon />} wordmark={<Logo /> | "CTDS"} />
34
+ </Sidebar.Header>
35
+
36
+ <Sidebar.Section title="워크스페이스">
37
+ <Sidebar.Item
38
+ icon={<Icon name="house" />}
39
+ label="대시보드"
40
+ active={boolean}
41
+ trailing={ReactNode} // 배지·카운트
42
+ shortcut="⌘1"
43
+ hasSubmenu={boolean}
44
+ disabled={boolean}
45
+ asChild={boolean}
46
+ onClick={(e) => void}
47
+ />
48
+ </Sidebar.Section>
49
+
50
+ <Sidebar.Separator />
51
+
52
+ <Sidebar.Footer>
53
+ <Sidebar.Profile
54
+ name="희영"
55
+ sub="admin@ctds.dev"
56
+ avatar={{ src, status }} // Avatar props 패스스루
57
+ trailing={<IconButton />}
58
+ />
59
+ </Sidebar.Footer>
60
+ </Sidebar>
61
+ ```
62
+
63
+ ### 상태 매트릭스
64
+ | 상태 | 시각 |
65
+ |---|---|
66
+ | expanded (기본) | 폭 `--sidebar-w`, 모든 자식 라벨·wordmark·trailing 노출 |
67
+ | collapsed | 폭 `--sidebar-w-collapsed`, Item은 icon-only, wordmark·Section title·Profile 텍스트·trailing 숨김 |
68
+ | Item active | MenuItem active 그대로 — `--bg-muted` 배경 + `fg-strong` + medium weight |
69
+
70
+ ### 조합 예시
71
+ ```tsx
72
+ // 기본 — 섹션 2개 + Profile
73
+ <Sidebar>
74
+ <Sidebar.Header>
75
+ <Sidebar.Brand symbol={<Icon name="rocket-launch" />} wordmark="CTDS" />
76
+ </Sidebar.Header>
77
+
78
+ <Sidebar.Section title="워크스페이스">
79
+ <Sidebar.Item asChild icon={<Icon name="house" />} label="대시보드" active>
80
+ <Link href="/">대시보드</Link>
81
+ </Sidebar.Item>
82
+ <Sidebar.Item asChild icon={<Icon name="chart-line" />} label="분석">
83
+ <Link href="/analytics">분석</Link>
84
+ </Sidebar.Item>
85
+ </Sidebar.Section>
86
+
87
+ <Sidebar.Separator />
88
+
89
+ <Sidebar.Section title="설정">
90
+ <Sidebar.Item icon={<Icon name="gear" />} label="환경설정" shortcut="⌘," />
91
+ </Sidebar.Section>
92
+
93
+ <Sidebar.Footer>
94
+ <Sidebar.Profile name="희영" sub="admin@ctds.dev" avatar={{ status: "online" }} />
95
+ </Sidebar.Footer>
96
+ </Sidebar>
97
+
98
+ // Collapsed — icon-only
99
+ <Sidebar collapsed>
100
+ <Sidebar.Header>
101
+ <Sidebar.Brand symbol={<Icon name="rocket-launch" />} />
102
+ </Sidebar.Header>
103
+ <Sidebar.Section>
104
+ <Sidebar.Item icon={<Icon name="house" />} label="대시보드" active />
105
+ </Sidebar.Section>
106
+ </Sidebar>
107
+ ```
@@ -0,0 +1,89 @@
1
+ # Slider
2
+
3
+ ### 원칙
4
+ 연속·이산 수치를 **드래그로 조정**하는 최소 컨트롤. 트랙 + 채워진 부분 + 썸만 있는 미니멀 스펙 — 값 라벨·마크·range(양끝 두 개)는 이 컴포넌트가 다루지 않는다. 값을 텍스트로 보고 싶으면 옆에 별도 노드로 붙인다.
5
+
6
+ native `<input type="range">` 위에 스타일만 얹어 접근성(키보드 ← → Home End, 드래그, 스크린리더)을 그대로 상속.
7
+
8
+ ### Do
9
+ - **연속·근사 조정에만 씀** — 볼륨, 밝기, 오프셋, 확대율처럼 "대략 이 정도" 조작이 자연스러운 값.
10
+ - **정확한 값 입력이 필요하면 [[components/input]]** (`type="number"`). 슬라이더는 근사, 입력은 정확 — 병행해도 좋다.
11
+ - **현재 값을 어딘가엔 표시**. 슬라이더 오른쪽에 `<span>{value}px</span>` 같은 라벨을 붙여 지금 값이 얼마인지 읽히게.
12
+ - **step은 의미 있는 최소 단위**. px 조정이면 1, 확대율이면 0.1, 볼륨이면 5 같은 식.
13
+
14
+ ### Don't
15
+ - **불연속 3~5개 옵션 선택에 쓰지 않는다** — 그건 [[components/tabs]] `segmented` 또는 [[components/filter-button]].
16
+ - **On/Off 두 값만 있는 자리에 쓰지 않는다** — [[components/switch]].
17
+ - **range slider(양 끝 두 개)로 확장하지 않는다** — 이 컴포넌트는 단일 값만. 범위 선택은 별도 컴포넌트로.
18
+ - 썸 크기·트랙 두께를 CSS로 덮어쓰지 않는다 — Density 축 (`--control-h-*`, `--space-*`)이 결정.
19
+
20
+ ### Fallback
21
+ size 애매하면 `md`, step 애매하면 `1`.
22
+
23
+ ### 관련
24
+ - [[axes/density]] — `--control-h-*`가 썸 크기·트랙 높이에 매핑
25
+ - [[axes/shape]] — 트랙·썸 radius (`--radius-full` 고정, Shape 축 영향 없음)
26
+ - [[axes/motion]] — hover·drag 상태 전환 duration
27
+ - [[axes/palette]] — 채워진 트랙이 `--primary`
28
+ - [[tokens/color]] — `--primary` (채운 부분), `--bg-muted` (트랙 배경), `--border-strong` (썸 경계)
29
+ - [[components/input]] — 정확한 수치 입력 병행
30
+
31
+ ### Props 시그니처
32
+ ```tsx
33
+ <Slider
34
+ size="sm | md | lg" // default: md
35
+ min={number} // default: 0
36
+ max={number} // default: 100
37
+ step={number} // default: 1
38
+ value={number} // controlled
39
+ defaultValue={number} // uncontrolled 초기값
40
+ onValueChange={(n) => void} // 편의 콜백 (숫자로 바로 옴)
41
+ disabled
42
+ aria-label="…" // 시각 라벨 없으면 필수
43
+ />
44
+ ```
45
+
46
+ ### 상태 매트릭스
47
+ | 상태 | 트랙 | 썸 |
48
+ |---|---|---|
49
+ | default | `--bg-muted` 배경 + `--primary` fill | `--bg` + `--border-strong` 경계 + `shadow-xs` |
50
+ | hover | 동일 | 경계 `--primary` |
51
+ | focus-visible | 동일 | `--ring-shadow` + `--primary` 경계 |
52
+ | active (드래그) | 동일 | scale 1.05, cursor grabbing |
53
+ | disabled | opacity 0.5 | opacity 0.5, cursor not-allowed |
54
+
55
+ ### Size 가이드
56
+ | size | 썸 (control-h) | 트랙 두께 | 언제 |
57
+ |---|---|---|---|
58
+ | `sm` | control-h-sm | space-0_5 | 툴바 · 인스펙터 · 조밀한 컨트롤 그룹 |
59
+ | `md` | control-h-md | space-1 | **기본.** 폼 · 설정 페이지 |
60
+ | `lg` | control-h-lg | space-1_5 | 터치 · 랜딩 · 큰 값 조정(볼륨·밝기 등) |
61
+
62
+ ### 접근성
63
+ - 실제 `<input type="range">`라서 키보드 ← → (step), PageUp/PageDown (10*step), Home/End 가 자동 동작.
64
+ - 스크린리더가 min·max·현재 값을 읽음.
65
+ - 시각 라벨이 없으면 `aria-label` 필수. 옆에 값을 표시하는 노드가 있다면 `aria-describedby`로 연결하면 더 좋음.
66
+
67
+ ### 조합 예시
68
+ ```tsx
69
+ // 툴바 안 오프셋 조정 — 값 라벨을 옆에 붙여 현재 값을 노출
70
+ <div className="row">
71
+ <Slider
72
+ size="sm"
73
+ min={-40}
74
+ max={40}
75
+ step={1}
76
+ value={offset}
77
+ onValueChange={setOffset}
78
+ aria-label="Arrow offset"
79
+ />
80
+ <span className="value">{offset}px</span>
81
+ </div>
82
+
83
+ // 폼 안 볼륨 조정 — Input과 병행
84
+ <label>
85
+ 볼륨
86
+ <Slider min={0} max={100} step={5} value={vol} onValueChange={setVol} />
87
+ <Input type="number" min={0} max={100} value={vol} onChange={(e) => setVol(Number(e.target.value))} />
88
+ </label>
89
+ ```
@@ -0,0 +1,71 @@
1
+ # SplitButton
2
+
3
+ ### 원칙
4
+ 시각적으로 하나로 붙어있지만 클릭 영역이 두 개로 분리된 버튼 — `main`(기본 액션) + `menu`(부가 옵션 드롭다운). 사용자에게 "이 액션의 가장 흔한 형태 + 대안" 관계를 한 컨트롤로 압축한다. 예: [저장 | ▾] → 저장 / 다른 이름으로 저장 / 사본 저장.
5
+
6
+ ### Do
7
+ - **main은 예측 가능한 기본값** — 90% 사용자가 원할 액션. menu는 그 외 변형.
8
+ - `menuLabel` prop은 필수. 스크린리더가 caret 영역을 식별해야 함 ("옵션 더보기", "저장 옵션" 등).
9
+ - variant는 [[components/button]]과 동일 규칙 — 한 화면에 `primary` 1개.
10
+ - menu 열림 상태는 부모가 관리하고 `aria-expanded`는 caret button에 얹는다 (필요 시 `...rest`로 전달할 수 있게 컴포넌트 확장).
11
+
12
+ ### Don't
13
+ - 두 액션이 **의미상 무관**하면 SplitButton 아님 → 그냥 Button 2개.
14
+ - menu에 3개 이상 항목이 들어가면 검토. 너무 많으면 그냥 [[components/menu]] 트리거 Button 하나로.
15
+ - 구분선 색·굵기 CSS로 덮어쓰지 않는다. currentColor × 알파로 variant 톤 자동 반응.
16
+ - `ghost` / `destructive`는 지원하지 않는다. Ghost는 무게가 최소인데 옆에 caret이 붙는 순간 시각 위계가 튀고, destructive는 부가 옵션까지 감싸기엔 위험 신호가 과함. 삭제 계열은 [[components/button]] `destructive` / `destructive-ghost` 단독으로.
17
+
18
+ ### Fallback
19
+ variant 애매하면 `secondary`, size 애매하면 `md`.
20
+
21
+ ### 관련
22
+ - [[components/button]] — variant/size 규칙 공유
23
+ - [[components/menu]] — menu 클릭 시 열리는 드롭다운
24
+ - [[axes/density]] — `--control-h-*`가 두 영역 높이·정사각 폭에 매핑
25
+ - [[axes/shape]] — root radius가 Shape 축에 반응
26
+
27
+ ### Props 시그니처
28
+ ```tsx
29
+ <SplitButton
30
+ size="sm | md | lg" // default: md
31
+ variant="primary | inverse | secondary | outline" // default: primary
32
+ leftIcon={ReactNode} // main 라벨 앞
33
+ menuIcon={ReactNode} // 기본 caret-down 대체
34
+ onMainClick={handler}
35
+ onMenuClick={openMenu}
36
+ menuLabel="옵션 더보기" // 필수, 접근성용
37
+ fullWidth loading disabled
38
+ >
39
+ 저장
40
+ </SplitButton>
41
+ ```
42
+
43
+ ### 구조·동작
44
+ - 내부적으로 `<button>` 2개 + 사이 `<span>` divider
45
+ - 각 영역이 독립 `:hover` — main hover 시 menu는 그대로, 반대도 동일
46
+ - Divider는 상하 여백(`--space-1_5`) 두고 세로 hairline, 색은 variant fg의 25% 알파
47
+ - 포커스링은 각 button별로. 링이 옆 영역 위로 올라오게 z-index 처리
48
+
49
+ ### 조합 예시
50
+ ```tsx
51
+ // 저장 + 다른 형식으로 저장 (드롭다운)
52
+ <SplitButton
53
+ variant="primary"
54
+ leftIcon={<Icon name="check" />}
55
+ onMainClick={save}
56
+ onMenuClick={() => setMenuOpen(true)}
57
+ menuLabel="저장 옵션"
58
+ >
59
+ 저장
60
+ </SplitButton>
61
+
62
+ // 필터 적용 + 필터 편집
63
+ <SplitButton
64
+ variant="outline"
65
+ onMainClick={applyLastFilter}
66
+ onMenuClick={openFilterMenu}
67
+ menuLabel="필터 편집"
68
+ >
69
+ 최근 필터
70
+ </SplitButton>
71
+ ```
@@ -0,0 +1,93 @@
1
+ # Stepper
2
+
3
+ ### 원칙
4
+ 다단계 프로세스의 진행 위치를 시각적으로 보여주는 컴포넌트. 각 스텝은 `upcoming | active | done` 세 상태를 가지며, 상태 대비로 사용자가 "지금 어디에 있고 얼마나 남았는지"를 즉시 파악하게 한다. Rail·툴바 같은 껍데기(브랜드 슬롯·푸터)는 이 컴포넌트가 담지 않는다 — Stepper는 **스텝 리스트만** 담당.
5
+
6
+ ### Do
7
+ - **기본은 `orientation="vertical"`**. 온보딩·설정·긴 폼처럼 화면 좌측 사이드에 붙는 표준 케이스.
8
+ - **좁은 헤더·상단 배너에는 `orientation="horizontal"`**. 세로 공간이 부족하고 스텝 개수가 3~5개일 때.
9
+ - **스텝이 6개를 넘으면 hint를 지운다** — title만 남기고 밀도를 확보.
10
+ - **활성 스텝은 한 번에 하나**. `activeIndex`로만 제어. 자식 Item에 `state`를 직접 넣는 건 예외 케이스(비선형 진행)에서만.
11
+ - **미도달 스텝 클릭은 막는다** — 상위에서 `disabled` prop 또는 `onStepClick`에서 조건 처리. 스텝 스킵을 허용하면 진행률의 의미가 무너진다.
12
+ - **marker는 `dot` 기본**. `number`는 순서가 정보 그 자체일 때만 (예: "3단계 결제 프로세스"처럼 숫자가 사용자 언어에 이미 있는 경우).
13
+ - **색은 로컬 CSS 변수로 오버라이드**. 특수 팔레트(온보딩 다크 rail 등)에서는 `--stepper-fg` · `--stepper-fg-muted` · `--stepper-fg-subtle` · `--stepper-line` · `--stepper-dot-idle` · `--stepper-marker-fg`를 부모에서 재정의.
14
+
15
+ ### Don't
16
+ - Stepper 안에 브랜드 로고·푸터·CTA 버튼을 넣지 않는다 — 상위 shell(Rail)의 책임.
17
+ - marker 안에 이모지·아바타·커스텀 배지 삽입 금지. dot / number / check만 허용.
18
+ - 활성 스텝을 진하게, 미도달을 진하게 동시에 강조하지 않는다. 위계는 하나(active만 `--stepper-fg`).
19
+ - 스텝 사이 dashed line을 solid로 바꾸지 않는다 — dashed는 "진행 여지"의 시각 신호.
20
+ - Motion 축과 무관하게 marker에 커스텀 애니메이션(bounce, spin 등) 붙이지 않는다. 상태 전환은 `--transition-colors`로 통일.
21
+ - `data-state="active"` 위에 hover가 border/bg를 덮어쓰지 않는다. [[feedback/hover-over-active]] 원칙.
22
+
23
+ ### Fallback
24
+ orientation 애매하면 `vertical`, marker 애매하면 `dot`. 스텝 6개 초과에 orientation·marker 판단 안 서면 사용자에게 확인.
25
+
26
+ ### 관련
27
+ - [[components/progress-bar]] — 연속형 진행률. 스텝이 discrete 하지 않으면 이쪽.
28
+ - [[components/tabs]] — 순서·진행 개념 없이 병렬 전환이면 Tabs.
29
+ - [[axes/density]] — `--space-scale`이 스텝 간격 · marker 크기에 반영
30
+ - [[axes/motion]] — 상태 전환 duration/easing
31
+ - [[tokens/color]] — `--fg` · `--fg-muted` · `--fg-subtle` · `--border` 매핑
32
+ - [[tokens/spacing]] — `--space-5`(marker), `--space-6`(item-gap) 참고
33
+
34
+ ### Props 시그니처
35
+ ```tsx
36
+ <Stepper
37
+ activeIndex={number}
38
+ orientation="vertical | horizontal" // default: vertical
39
+ marker="dot | number" // default: dot
40
+ onStepClick={(index: number) => void}
41
+ >
42
+ <Stepper.Item title="..." hint="..." disabled={boolean} state="upcoming | active | done" />
43
+ </Stepper>
44
+ ```
45
+
46
+ ### Variant 매트릭스
47
+ | orientation | marker | 용도 | 금지 조합 |
48
+ |---|---|---|---|
49
+ | `vertical` | `dot` | **기본.** 온보딩·설정·긴 폼의 좌측 rail | — |
50
+ | `vertical` | `number` | 순서가 사용자 언어에 이미 있는 세로 rail (드묾) | 스텝 6개 초과 시 hint까지 붙이면 답답 |
51
+ | `horizontal` | `dot` | 좁은 헤더·상단 배너, 스텝 3~5개 | 스텝 6개 초과 금지 (dashed line이 짧아짐) |
52
+ | `horizontal` | `number` | 결제·체크아웃 같은 "명시적 순서" 헤더 프로세스 | 스텝 6개 초과 금지 |
53
+
54
+ ### 색 오버라이드 예 (특수 팔레트)
55
+ ```css
56
+ /* 예: 온보딩 다크 rail에서 Stepper를 밝은 톤으로 뒤집기 */
57
+ .myDarkRail {
58
+ --stepper-fg: var(--onb-rail-fg);
59
+ --stepper-fg-muted: var(--onb-rail-fg-muted);
60
+ --stepper-fg-subtle: var(--onb-rail-fg-subtle);
61
+ --stepper-line: var(--onb-rail-line);
62
+ --stepper-dot-idle: var(--onb-rail-dot-idle);
63
+ --stepper-marker-fg: var(--onb-rail);
64
+ }
65
+ ```
66
+
67
+ ### 조합 예시
68
+ ```tsx
69
+ // 온보딩 세로 rail — 기본 dot
70
+ <Stepper
71
+ activeIndex={stepIdx}
72
+ onStepClick={(i) => {
73
+ if (i <= stepIdx || isReachable(i)) setStepIdx(i);
74
+ }}
75
+ >
76
+ {STEPS.map((s, i) => (
77
+ <Stepper.Item
78
+ key={s.key}
79
+ title={s.title}
80
+ hint={s.hint}
81
+ disabled={i > stepIdx && !isReachable(i)}
82
+ />
83
+ ))}
84
+ </Stepper>
85
+
86
+ // 체크아웃 상단 헤더 — horizontal + number
87
+ <Stepper activeIndex={1} orientation="horizontal" marker="number">
88
+ <Stepper.Item title="장바구니" />
89
+ <Stepper.Item title="배송 정보" />
90
+ <Stepper.Item title="결제" />
91
+ <Stepper.Item title="완료" />
92
+ </Stepper>
93
+ ```
@@ -0,0 +1,86 @@
1
+ # Switch
2
+
3
+ ### 원칙
4
+ **즉시 적용되는 on/off** 컨트롤. 토글하는 순간 상태가 변한다 — 저장 버튼이 따로 없는 자리에 쓴다.
5
+ 시맨틱은 `role="switch"`가 붙은 native checkbox. 시각은 알약 트랙 + 원형 썸 — 켜지면 트랙이 `--primary`로 채워지고 썸이 우측으로 이동.
6
+
7
+ ### Do
8
+ - **즉시 반영에만**: 다크모드, 알림 on/off, 자동 저장, 필터 옵션. 토글 → 부작용까지 즉시.
9
+ - **"선택 여부"가 아니라 "상태 전환"에만**: 폼 제출 후 반영되는 옵션은 [[components/checkbox]].
10
+ - **라벨은 별도 컴포넌트로**: Switch 자체는 컨트롤만. 라벨은 `<label>` wrap이나 옆 텍스트 노드로 배치. 컴팩트한 툴바에서는 라벨을 아예 생략(그룹 자체가 라벨 역할)해도 됨.
11
+ - **폼 안이면 `name` 필수**: native checkbox 위에 얹은 거라 폼 제출에 자연스럽게 포함됨.
12
+
13
+ ### Don't
14
+ - **다중 선택에 쓰지 않는다** — [[components/checkbox]].
15
+ - **저장이 필요한 자리에 쓰지 않는다** — Switch를 켜자마자 부작용이 없다면 사용자는 "정말 켜졌나?" 헷갈린다.
16
+ - 트랙 색을 status(성공/경고/삭제)로 바꾸지 않는다 — 켜짐은 항상 `--primary`. 상태 표현은 다른 컴포넌트가 담당.
17
+ - 썸·트랙 크기를 CSS로 덮어쓰지 않는다. `size` prop · Density 축이 결정.
18
+
19
+ ### Fallback
20
+ size 애매하면 `md`.
21
+
22
+ ### 관련
23
+ - [[components/checkbox]] — 선택 여부(폼 제출 후 반영)
24
+ - [[components/tabs]] `segmented` — 세 개 이상 배타 옵션
25
+ - [[axes/density]] — `--space-*` 스케일이 트랙·썸 크기에 매핑
26
+ - [[axes/motion]] — 썸 이동 duration
27
+ - [[tokens/color]] — `--primary` (켜짐), `--bg-muted` (꺼짐), `--fg-disabled` (disabled 썸)
28
+
29
+ ### Props 시그니처
30
+ ```tsx
31
+ <Switch
32
+ size="sm | md | lg" // default: md
33
+ checked / defaultChecked // native input props
34
+ onCheckedChange={(on) => void} // 편의 콜백 (boolean 바로 옴)
35
+ disabled
36
+ name
37
+ aria-label="…" // 시각 라벨 없으면 필수
38
+ />
39
+ ```
40
+
41
+ ### 상태 매트릭스
42
+ | 상태 | 트랙 | 썸 |
43
+ |---|---|---|
44
+ | off · default | `--bg-muted` + `--border` hairline | `--bg` 원 + `shadow-xs` |
45
+ | off · hover | 경계 `--border-strong` | 동일 |
46
+ | on · default | `--primary` fill, 보더도 `--primary` | 우측 이동 |
47
+ | on · hover | `--primary`를 fg 12% 섞어 살짝 진하게 | 동일 |
48
+ | focus-visible | 트랙에 `--ring-shadow` | 동일 |
49
+ | disabled | `--bg-muted`, 투명 보더 | `--fg-disabled`, shadow none |
50
+
51
+ ### Size 가이드
52
+ | size | 트랙 (w × h) | 언제 |
53
+ |---|---|---|
54
+ | `sm` | space-6 × space-3 | 툴바, 인스펙터, 밀집 폼 |
55
+ | `md` | space-8 × space-4 | **기본.** 설정 페이지, 일반 폼 |
56
+ | `lg` | space-10 × space-5 | 터치, 온보딩, 큰 옵션 그룹 |
57
+
58
+ ### 접근성
59
+ - `role="switch"` + native `input type="checkbox"` → 스크린리더가 "스위치, 켜짐/꺼짐"으로 읽음.
60
+ - 시각 라벨이 없으면 `aria-label` 필수.
61
+ - `<label>` 래퍼가 있어서 트랙·썸 어디 클릭해도 토글.
62
+ - 키보드: Space로 토글, Tab으로 포커스.
63
+
64
+ ### 조합 예시
65
+ ```tsx
66
+ // 툴바 안 옵션 토글 — 그룹이 라벨 역할, aria-label로만 시맨틱 라벨
67
+ <div className="toolbar-group">
68
+ <span>Time</span>
69
+ <Switch size="sm" checked={withTime} onCheckedChange={setWithTime} aria-label="Time" />
70
+ </div>
71
+
72
+ // 폼 안 옵션 — 텍스트 라벨과 세트
73
+ <label className="row">
74
+ <Switch checked={notify} onCheckedChange={setNotify} name="notify" />
75
+ <span>이메일 알림 받기</span>
76
+ </label>
77
+
78
+ // 설정 페이지 — 라벨 왼쪽, Switch 오른쪽 (justify-between)
79
+ <div className="setting-row">
80
+ <div>
81
+ <div>다크 모드</div>
82
+ <div className="hint">시스템 설정을 따르지 않고 강제 적용</div>
83
+ </div>
84
+ <Switch checked={dark} onCheckedChange={setDark} aria-label="다크 모드" />
85
+ </div>
86
+ ```
@@ -0,0 +1,87 @@
1
+ # TableCell
2
+
3
+ ### 원칙
4
+ [[components/table-row]]·[[components/table-row-edit]]의 셀 자리에 넣는 **의미별 서브 컴포넌트 세트**. 하나의 TableCell이 아니라 **9종** — Text·Number·Image·Tag·Badge·Icon·Avatar·Link·Meter. 셀 안 콘텐츠 종류마다 톤·정렬·간격이 다른데 그 결정을 셀 레벨에서 끊어내 Row는 레이아웃만 담당하게 한다.
5
+
6
+ ### Do
7
+ - 콘텐츠 성격에 맞는 서브 컴포넌트를 고른다. 성격 혼재 금지.
8
+ - Number는 `tabular-nums`가 자동. 숫자 셀은 반드시 Number 사용.
9
+ - Avatar 셀은 `label` + `sublabel`(이메일·역할) 2행 구조. 이름만이면 label만.
10
+ - Tag는 **다중값**(기술 스택·태그 모음), Badge는 **단일 상태**.
11
+ - 색은 톤(`tone`) prop으로만. hex·custom color 금지.
12
+
13
+ ### Don't
14
+ - 숫자를 Text로 렌더하지 않는다 — tabular 정렬 깨짐.
15
+ - 숫자 셀 **우측정렬 금지** ([[feedback_no_right_align_numbers]]). 좌측정렬 유지.
16
+ - 셀 안에 두 종류 섞지 않는다(Avatar + Badge 등). 그러려면 상위 Row 커스텀 셀로.
17
+ - Tag·Badge를 Icon 셀에 섞어 쓰지 않는다. 아이콘은 상태 시그널 전용.
18
+ - 셀 자체에 padding override 금지. Row의 셀 간격 토큰이 전담.
19
+
20
+ ### Fallback
21
+ tone 애매하면 Text=`default`, Icon=`default`, Meter=`default`.
22
+
23
+ ### 관련
24
+ - [[components/table-row]] · [[components/table-row-edit]] · [[components/table-row-select]] — 담는 Row
25
+ - [[components/table-header]] — 컬럼 정의
26
+ - [[components/avatar]] — Avatar 셀 안쪽
27
+ - [[components/badge]] · [[components/tag]] — 각 셀의 소스
28
+ - [[tokens/color]] — tone 매핑
29
+
30
+ ### Props 시그니처
31
+ ```tsx
32
+ // 공통: 모든 TableCell*은 <span>으로 렌더. HTML attributes 통과.
33
+ <TableCellText tone="default | strong | muted | subtle">{string | ReactNode}</TableCellText>
34
+ <TableCellNumber value={number} format?={Intl.NumberFormatOptions} />
35
+ <TableCellImage src={string} alt={string} size={number} shape="circle | rounded | square" />
36
+ <TableCellBadge status="success | warning | destructive | info" variant="soft | solid">
37
+ {string}
38
+ </TableCellBadge>
39
+ <TableCellIcon icon={<Icon />} tone="default | success | warning | destructive | info" />
40
+ <TableCellAvatar
41
+ src?={string} name?={string} initials?={string}
42
+ shape="circle | rounded" // default: circle
43
+ status?="online | offline | busy | away"
44
+ label?={ReactNode} // 미지정 시 name 재사용
45
+ sublabel?={ReactNode} // 이메일·역할
46
+ />
47
+ <TableCellLink href={string} external?={boolean}>{ReactNode}</TableCellLink>
48
+ <TableCellMeter value={0..100} tone="default | success | warning | destructive" label?={string} />
49
+ ```
50
+
51
+ ### 서브 컴포넌트 선택 가이드
52
+ | 셀 콘텐츠 | 사용 |
53
+ |---|---|
54
+ | 일반 텍스트 | `TableCellText` (tone 조절) |
55
+ | 금액·개수·비율 | `TableCellNumber` (tabular-nums) |
56
+ | 썸네일·프로덕트 사진 | `TableCellImage` |
57
+ | 다중 메타 라벨 (기술·분류·속성) | `TableCellBadge` 여러 개를 `inline-flex` + `space-1` gap으로 나열 |
58
+ | 단일 상태 라벨 | `TableCellBadge` |
59
+ | 상태 아이콘만 | `TableCellIcon` |
60
+ | 사람·팀 식별 | `TableCellAvatar` |
61
+ | 외부 링크·상세 라우팅 | `TableCellLink` |
62
+ | 진행률·사용량 바 | `TableCellMeter` |
63
+
64
+ ### 조합 예시
65
+ ```tsx
66
+ // 사용자 리스트 — Avatar + 숫자 + Badge
67
+ <TableRow
68
+ cells={[
69
+ <TableCellAvatar src={u.avatar} name={u.name} sublabel={u.email} />,
70
+ <TableCellText tone="muted">{u.role}</TableCellText>,
71
+ <TableCellNumber value={u.projects} />,
72
+ <TableCellBadge status={u.active ? "success" : "warning"}>
73
+ {u.active ? "활성" : "휴면"}
74
+ </TableCellBadge>,
75
+ ]}
76
+ />
77
+
78
+ // 분석 테이블 — 숫자 + Meter + Link
79
+ <TableRow
80
+ cells={[
81
+ <TableCellText tone="strong">{row.name}</TableCellText>,
82
+ <TableCellNumber value={row.visits} />,
83
+ <TableCellMeter value={row.conversion} tone="success" label={`${row.conversion}%`} />,
84
+ <TableCellLink href={`/reports/${row.id}`}>자세히</TableCellLink>,
85
+ ]}
86
+ />
87
+ ```