@iamfiro/design 0.0.0-stage → 0.3.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 (416) hide show
  1. package/AGENTS.md +82 -0
  2. package/README.md +15 -2
  3. package/agents/INDEX.md +157 -0
  4. package/agents/accordion/AGENTS.md +279 -0
  5. package/agents/action-bar/AGENTS.md +90 -0
  6. package/agents/alert/AGENTS.md +212 -0
  7. package/agents/alert-dialog/AGENTS.md +193 -0
  8. package/agents/app-shell/AGENTS.md +409 -0
  9. package/agents/area-chart/AGENTS.md +183 -0
  10. package/agents/aspect-ratio/AGENTS.md +143 -0
  11. package/agents/avatar/AGENTS.md +130 -0
  12. package/agents/badge/AGENTS.md +217 -0
  13. package/agents/bar-chart/AGENTS.md +386 -0
  14. package/agents/bar-list/AGENTS.md +223 -0
  15. package/agents/brand-icon/AGENTS.md +82 -0
  16. package/agents/breadcrumb/AGENTS.md +133 -0
  17. package/agents/button/AGENTS.md +195 -0
  18. package/agents/card/AGENTS.md +141 -0
  19. package/agents/card-frame/AGENTS.md +227 -0
  20. package/agents/chat-bubble/AGENTS.md +266 -0
  21. package/agents/chat-composer/AGENTS.md +251 -0
  22. package/agents/checkbox/AGENTS.md +113 -0
  23. package/agents/code-block/AGENTS.md +144 -0
  24. package/agents/color-dot/AGENTS.md +120 -0
  25. package/agents/color-picker/AGENTS.md +224 -0
  26. package/agents/colors/AGENTS.md +168 -0
  27. package/agents/combobox/AGENTS.md +218 -0
  28. package/agents/command-menu/AGENTS.md +169 -0
  29. package/agents/comment/AGENTS.md +206 -0
  30. package/agents/context-menu/AGENTS.md +303 -0
  31. package/agents/copy-button/AGENTS.md +84 -0
  32. package/agents/count-badge/AGENTS.md +115 -0
  33. package/agents/countdown/AGENTS.md +101 -0
  34. package/agents/data-grid/AGENTS.md +460 -0
  35. package/agents/date-picker/AGENTS.md +197 -0
  36. package/agents/delta/AGENTS.md +114 -0
  37. package/agents/description-list/AGENTS.md +251 -0
  38. package/agents/dialog/AGENTS.md +391 -0
  39. package/agents/drawer/AGENTS.md +471 -0
  40. package/agents/dropdown-menu/AGENTS.md +322 -0
  41. package/agents/dropzone/AGENTS.md +116 -0
  42. package/agents/elapsed/AGENTS.md +160 -0
  43. package/agents/empty-state/AGENTS.md +203 -0
  44. package/agents/file-chip/AGENTS.md +79 -0
  45. package/agents/file-icon/AGENTS.md +66 -0
  46. package/agents/file-upload/AGENTS.md +168 -0
  47. package/agents/filter-chips/AGENTS.md +167 -0
  48. package/agents/flag/AGENTS.md +67 -0
  49. package/agents/funnel-chart/AGENTS.md +131 -0
  50. package/agents/highlight/AGENTS.md +119 -0
  51. package/agents/hover-card/AGENTS.md +271 -0
  52. package/agents/icon-stack/AGENTS.md +120 -0
  53. package/agents/icon-tile/AGENTS.md +94 -0
  54. package/agents/inline-diff/AGENTS.md +211 -0
  55. package/agents/input/AGENTS.md +261 -0
  56. package/agents/kanban/AGENTS.md +352 -0
  57. package/agents/kbd/AGENTS.md +160 -0
  58. package/agents/layout/AGENTS.md +351 -0
  59. package/agents/line-chart/AGENTS.md +393 -0
  60. package/agents/link/AGENTS.md +53 -0
  61. package/agents/list/AGENTS.md +392 -0
  62. package/agents/marker/AGENTS.md +142 -0
  63. package/agents/masked-text/AGENTS.md +127 -0
  64. package/agents/menubar/AGENTS.md +276 -0
  65. package/agents/multi-select/AGENTS.md +159 -0
  66. package/agents/navigation-menu/AGENTS.md +315 -0
  67. package/agents/notice-stack/AGENTS.md +101 -0
  68. package/agents/number-stepper/AGENTS.md +96 -0
  69. package/agents/otp-input/AGENTS.md +162 -0
  70. package/agents/pagination/AGENTS.md +189 -0
  71. package/agents/phone-input/AGENTS.md +131 -0
  72. package/agents/pie-chart/AGENTS.md +243 -0
  73. package/agents/popover/AGENTS.md +190 -0
  74. package/agents/progress/AGENTS.md +273 -0
  75. package/agents/progress-tracker/AGENTS.md +305 -0
  76. package/agents/rating/AGENTS.md +165 -0
  77. package/agents/relative-time/AGENTS.md +103 -0
  78. package/agents/resizable/AGENTS.md +390 -0
  79. package/agents/scaled-preview/AGENTS.md +111 -0
  80. package/agents/scatter-chart/AGENTS.md +160 -0
  81. package/agents/scroll-area/AGENTS.md +271 -0
  82. package/agents/search-input/AGENTS.md +105 -0
  83. package/agents/segmented-control/AGENTS.md +153 -0
  84. package/agents/select/AGENTS.md +159 -0
  85. package/agents/selector-button/AGENTS.md +122 -0
  86. package/agents/sidebar/AGENTS.md +201 -0
  87. package/agents/skeleton/AGENTS.md +166 -0
  88. package/agents/slider/AGENTS.md +181 -0
  89. package/agents/social-login-button/AGENTS.md +156 -0
  90. package/agents/spark-chart/AGENTS.md +257 -0
  91. package/agents/sparkbar/AGENTS.md +92 -0
  92. package/agents/spinner/AGENTS.md +123 -0
  93. package/agents/split-view/AGENTS.md +290 -0
  94. package/agents/stat/AGENTS.md +138 -0
  95. package/agents/status-icon/AGENTS.md +243 -0
  96. package/agents/step-list/AGENTS.md +313 -0
  97. package/agents/table/AGENTS.md +286 -0
  98. package/agents/tabs/AGENTS.md +305 -0
  99. package/agents/tag-input/AGENTS.md +246 -0
  100. package/agents/time-picker/AGENTS.md +228 -0
  101. package/agents/timeline/AGENTS.md +1018 -0
  102. package/agents/toast/AGENTS.md +266 -0
  103. package/agents/toggle-group/AGENTS.md +216 -0
  104. package/agents/toolbar/AGENTS.md +277 -0
  105. package/agents/tooltip/AGENTS.md +154 -0
  106. package/agents/tracker/AGENTS.md +158 -0
  107. package/agents/tree-diagram/AGENTS.md +260 -0
  108. package/agents/tree-view/AGENTS.md +329 -0
  109. package/agents/typography/AGENTS.md +396 -0
  110. package/lib/components/Accordion/Accordion2.js +135 -0
  111. package/lib/components/ActionBar/ActionBar2.js +65 -0
  112. package/lib/components/Alert/Alert2.js +131 -0
  113. package/lib/components/AppShell/AppShell2.js +94 -0
  114. package/lib/components/AreaChart/AreaChart.js +59 -0
  115. package/lib/components/BarChart/BarChart2.js +243 -0
  116. package/lib/components/BarList/BarList2.js +172 -0
  117. package/lib/components/Breadcrumb/Breadcrumb2.js +87 -0
  118. package/lib/components/Calendar/Calendar2.js +309 -0
  119. package/lib/components/Calendar/DatePicker2.js +229 -0
  120. package/lib/components/Calendar/date.js +121 -0
  121. package/lib/components/Card/Card2.js +104 -0
  122. package/lib/components/CardFrame/CardFrame2.js +72 -0
  123. package/lib/components/Chart/ChartParts.js +150 -0
  124. package/lib/components/Chart/chart2.js +96 -0
  125. package/lib/components/Chart/useChartInteraction.js +94 -0
  126. package/lib/components/ChatBubble/ChatBubble2.js +174 -0
  127. package/lib/components/ChatBubble/formatChatTime.js +53 -0
  128. package/lib/components/ChatComposer/ChatComposer2.js +153 -0
  129. package/lib/components/CodeBlock/CodeBlock2.js +93 -0
  130. package/lib/components/CodeBlock/highlight.js +114 -0
  131. package/lib/components/ColorPicker/ColorPicker2.js +610 -0
  132. package/lib/components/ColorPicker/color.js +180 -0
  133. package/lib/components/ColorPicker/presets.js +75 -0
  134. package/lib/components/Combobox/Combobox2.js +229 -0
  135. package/lib/components/CommandMenu/CommandMenu.js +267 -0
  136. package/lib/components/Comment/Comment2.js +134 -0
  137. package/lib/components/ContextMenu/ContextMenu2.js +168 -0
  138. package/lib/components/DataGrid/DataGrid2.js +1996 -0
  139. package/lib/components/DataGrid/GridPopover.js +154 -0
  140. package/lib/components/DataGrid/anchor.js +50 -0
  141. package/lib/components/DataGrid/model.js +558 -0
  142. package/lib/components/DataGrid/panels.js +703 -0
  143. package/lib/components/DataGrid/typeMeta.js +76 -0
  144. package/lib/components/DataGrid/types.js +54 -0
  145. package/lib/components/DescriptionList/DescriptionList2.js +180 -0
  146. package/lib/components/Dialog/AlertDialog.js +118 -0
  147. package/lib/components/Dialog/Dialog2.js +109 -0
  148. package/lib/components/Dialog/modal.js +92 -0
  149. package/lib/components/Drawer/Drawer2.js +244 -0
  150. package/lib/components/DropdownMenu/DropdownMenu2.js +394 -0
  151. package/lib/components/DropdownMenu/menuCore.js +63 -0
  152. package/lib/components/Dropzone/Dropzone2.js +144 -0
  153. package/lib/components/EmptyState/EmptyState2.js +72 -0
  154. package/lib/components/FileChip/FileChip2.js +118 -0
  155. package/lib/components/FileUpload/FileUpload.js +258 -0
  156. package/lib/components/FilterChips/FilterChips2.js +101 -0
  157. package/lib/components/FunnelChart/FunnelChart2.js +283 -0
  158. package/lib/components/FunnelChart/funnel.js +69 -0
  159. package/lib/components/Highlight/Highlight2.js +100 -0
  160. package/lib/components/HoverCard/HoverCard.js +134 -0
  161. package/lib/components/InlineDiff/InlineDiff2.js +215 -0
  162. package/lib/components/InlineDiff/diff.js +126 -0
  163. package/lib/components/InlineDiff/useDiffReview.js +109 -0
  164. package/lib/components/Kanban/Kanban2.js +691 -0
  165. package/lib/components/Kanban/KanbanCard.js +159 -0
  166. package/lib/components/Kanban/move.js +69 -0
  167. package/lib/components/LineChart/LineChart2.js +342 -0
  168. package/lib/components/List/List2.js +133 -0
  169. package/lib/components/Listbox/Listbox2.js +163 -0
  170. package/lib/components/Marker/Marker2.js +82 -0
  171. package/lib/components/Menubar/Menubar2.js +223 -0
  172. package/lib/components/MultiSelect/MultiSelect2.js +204 -0
  173. package/lib/components/NavigationMenu/NavigationMenu2.js +481 -0
  174. package/lib/components/NoticeStack/NoticeStack2.js +178 -0
  175. package/lib/components/NumberStepper/NumberStepper2.js +129 -0
  176. package/lib/components/OtpInput/OtpInput2.js +122 -0
  177. package/lib/components/Pagination/Pagination2.js +210 -0
  178. package/lib/components/Pagination/paginationRange.js +53 -0
  179. package/lib/components/PhoneInput/PhoneInput.js +175 -0
  180. package/lib/components/PieChart/PieChart2.js +246 -0
  181. package/lib/components/PieChart/arc.js +66 -0
  182. package/lib/components/PieChart/useArcTween.js +94 -0
  183. package/lib/components/Popover/Popover2.js +112 -0
  184. package/lib/components/ProgressTracker/ProgressTracker2.js +226 -0
  185. package/lib/components/Rating/Rating2.js +186 -0
  186. package/lib/components/Resizable/Resizable2.js +236 -0
  187. package/lib/components/Resizable/layout.js +115 -0
  188. package/lib/components/ScaledPreview/ScaledPreview2.js +100 -0
  189. package/lib/components/ScatterChart/ScatterChart2.js +356 -0
  190. package/lib/components/ScatterChart/scatter.js +83 -0
  191. package/lib/components/ScrollArea/ScrollArea2.js +218 -0
  192. package/lib/components/Select/Select2.js +153 -0
  193. package/lib/components/Sidebar/Sidebar2.js +127 -0
  194. package/lib/components/Skeleton/Skeleton2.js +91 -0
  195. package/lib/components/Slider/Slider2.js +142 -0
  196. package/lib/components/SocialLoginButton/SocialLoginButton.js +85 -0
  197. package/lib/components/SparkChart/SparkChart2.js +217 -0
  198. package/lib/components/SparkChart/spark.js +76 -0
  199. package/lib/components/Sparkbar/Sparkbar2.js +111 -0
  200. package/lib/components/SplitView/SplitView2.js +95 -0
  201. package/lib/components/Stat/Stat2.js +164 -0
  202. package/lib/components/StepList/StepList2.js +131 -0
  203. package/lib/components/Table/Table2.js +104 -0
  204. package/lib/components/Tabs/Tabs2.js +131 -0
  205. package/lib/components/TagInput/TagInput2.js +360 -0
  206. package/lib/components/TimePicker/TimePicker2.js +388 -0
  207. package/lib/components/TimePicker/time.js +83 -0
  208. package/lib/components/Timeline/Timeline2.js +369 -0
  209. package/lib/components/Timeline/scale.js +83 -0
  210. package/lib/components/Toast/Toaster.js +212 -0
  211. package/lib/components/Toast/store.js +129 -0
  212. package/lib/components/ToggleGroup/ToggleGroup2.js +125 -0
  213. package/lib/components/Toolbar/Toolbar2.js +281 -0
  214. package/lib/components/Tracker/Tracker2.js +172 -0
  215. package/lib/components/TreeDiagram/TreeDiagram2.js +223 -0
  216. package/lib/components/TreeView/TreeView2.js +284 -0
  217. package/lib/hooks/timing.js +55 -0
  218. package/lib/hooks/useControllableState.js +49 -0
  219. package/lib/hooks/useCountdown.js +80 -0
  220. package/lib/hooks/useDigitInput.js +105 -0
  221. package/lib/hooks/useDismiss.js +71 -0
  222. package/lib/hooks/useElapsed.js +83 -0
  223. package/lib/hooks/useFloating.js +70 -0
  224. package/lib/hooks/useFocusTrap.js +61 -0
  225. package/lib/hooks/usePresence.js +60 -0
  226. package/lib/hooks/usePressToOpen.js +69 -0
  227. package/lib/hooks/useScrollLock.js +70 -0
  228. package/lib/hooks/useSelection.js +68 -0
  229. package/lib/index.js +178 -0
  230. package/lib/primitives/AspectRatio2.js +80 -0
  231. package/lib/primitives/BrandIcon.js +245 -0
  232. package/lib/primitives/ColorDot2.js +70 -0
  233. package/lib/primitives/CopyButton2.js +85 -0
  234. package/lib/primitives/CountBadge2.js +78 -0
  235. package/lib/primitives/Countdown2.js +65 -0
  236. package/lib/primitives/Delta2.js +67 -0
  237. package/lib/primitives/Elapsed.js +62 -0
  238. package/lib/primitives/FileIcon2.js +125 -0
  239. package/lib/primitives/Flag2.js +263 -0
  240. package/lib/primitives/IconStack2.js +85 -0
  241. package/lib/primitives/IconTile2.js +68 -0
  242. package/lib/primitives/Kbd2.js +88 -0
  243. package/lib/primitives/Layout2.js +118 -0
  244. package/lib/primitives/Link2.js +53 -0
  245. package/lib/primitives/MaskedText2.js +120 -0
  246. package/lib/primitives/Progress2.js +137 -0
  247. package/lib/primitives/RelativeTime.js +84 -0
  248. package/lib/primitives/SearchInput2.js +84 -0
  249. package/lib/primitives/SelectorButton2.js +97 -0
  250. package/lib/primitives/Spinner2.js +98 -0
  251. package/lib/primitives/StatusIcon2.js +126 -0
  252. package/lib/primitives/Swatch2.js +79 -0
  253. package/lib/primitives/Tooltip2.js +132 -0
  254. package/lib/primitives/Typography2.js +97 -0
  255. package/lib/primitives/formatCountdown.js +51 -0
  256. package/lib/primitives/formatElapsed.js +66 -0
  257. package/lib/primitives/formatRelativeTime.js +64 -0
  258. package/lib/primitives/hotkey.js +94 -0
  259. package/lib/primitives/index.js +352 -0
  260. package/lib/primitives/maskValue.js +65 -0
  261. package/lib/style.css +2 -0
  262. package/lib/types/components/Accordion/Accordion.d.ts +57 -0
  263. package/lib/types/components/ActionBar/ActionBar.d.ts +24 -0
  264. package/lib/types/components/Alert/Alert.d.ts +36 -0
  265. package/lib/types/components/AppShell/AppShell.d.ts +38 -0
  266. package/lib/types/components/AreaChart/AreaChart.d.ts +17 -0
  267. package/lib/types/components/BarChart/BarChart.d.ts +57 -0
  268. package/lib/types/components/BarList/BarList.d.ts +56 -0
  269. package/lib/types/components/Breadcrumb/Breadcrumb.d.ts +15 -0
  270. package/lib/types/components/Calendar/Calendar.d.ts +34 -0
  271. package/lib/types/components/Calendar/DatePicker.d.ts +45 -0
  272. package/lib/types/components/Calendar/date.d.ts +32 -0
  273. package/lib/types/components/Card/Card.d.ts +64 -0
  274. package/lib/types/components/CardFrame/CardFrame.d.ts +15 -0
  275. package/lib/types/components/Chart/ChartParts.d.ts +38 -0
  276. package/lib/types/components/Chart/chart.d.ts +46 -0
  277. package/lib/types/components/Chart/useChartInteraction.d.ts +39 -0
  278. package/lib/types/components/ChatBubble/ChatBubble.d.ts +61 -0
  279. package/lib/types/components/ChatBubble/formatChatTime.d.ts +2 -0
  280. package/lib/types/components/ChatComposer/ChatComposer.d.ts +42 -0
  281. package/lib/types/components/CodeBlock/CodeBlock.d.ts +18 -0
  282. package/lib/types/components/CodeBlock/highlight.d.ts +10 -0
  283. package/lib/types/components/ColorPicker/ColorPicker.d.ts +61 -0
  284. package/lib/types/components/ColorPicker/color.d.ts +48 -0
  285. package/lib/types/components/ColorPicker/presets.d.ts +7 -0
  286. package/lib/types/components/Combobox/Combobox.d.ts +48 -0
  287. package/lib/types/components/CommandMenu/CommandMenu.d.ts +51 -0
  288. package/lib/types/components/Comment/Comment.d.ts +45 -0
  289. package/lib/types/components/ContextMenu/ContextMenu.d.ts +40 -0
  290. package/lib/types/components/DataGrid/DataGrid.d.ts +43 -0
  291. package/lib/types/components/DataGrid/GridPopover.d.ts +43 -0
  292. package/lib/types/components/DataGrid/anchor.d.ts +5 -0
  293. package/lib/types/components/DataGrid/model.d.ts +61 -0
  294. package/lib/types/components/DataGrid/panels.d.ts +63 -0
  295. package/lib/types/components/DataGrid/typeMeta.d.ts +6 -0
  296. package/lib/types/components/DataGrid/types.d.ts +77 -0
  297. package/lib/types/components/DescriptionList/DescriptionList.d.ts +77 -0
  298. package/lib/types/components/Dialog/AlertDialog.d.ts +26 -0
  299. package/lib/types/components/Dialog/Dialog.d.ts +42 -0
  300. package/lib/types/components/Dialog/modal.d.ts +38 -0
  301. package/lib/types/components/Drawer/Drawer.d.ts +62 -0
  302. package/lib/types/components/DropdownMenu/DropdownMenu.d.ts +97 -0
  303. package/lib/types/components/DropdownMenu/menuCore.d.ts +23 -0
  304. package/lib/types/components/Dropzone/Dropzone.d.ts +30 -0
  305. package/lib/types/components/EmptyState/EmptyState.d.ts +26 -0
  306. package/lib/types/components/FileChip/FileChip.d.ts +32 -0
  307. package/lib/types/components/FileUpload/FileUpload.d.ts +52 -0
  308. package/lib/types/components/FilterChips/FilterChips.d.ts +37 -0
  309. package/lib/types/components/FunnelChart/FunnelChart.d.ts +38 -0
  310. package/lib/types/components/FunnelChart/funnel.d.ts +25 -0
  311. package/lib/types/components/Highlight/Highlight.d.ts +35 -0
  312. package/lib/types/components/HoverCard/HoverCard.d.ts +47 -0
  313. package/lib/types/components/InlineDiff/InlineDiff.d.ts +36 -0
  314. package/lib/types/components/InlineDiff/diff.d.ts +42 -0
  315. package/lib/types/components/InlineDiff/useDiffReview.d.ts +57 -0
  316. package/lib/types/components/Kanban/Kanban.d.ts +64 -0
  317. package/lib/types/components/Kanban/KanbanCard.d.ts +35 -0
  318. package/lib/types/components/Kanban/move.d.ts +25 -0
  319. package/lib/types/components/LineChart/LineChart.d.ts +85 -0
  320. package/lib/types/components/List/List.d.ts +62 -0
  321. package/lib/types/components/Listbox/Listbox.d.ts +60 -0
  322. package/lib/types/components/Marker/Marker.d.ts +28 -0
  323. package/lib/types/components/Menubar/Menubar.d.ts +50 -0
  324. package/lib/types/components/MultiSelect/MultiSelect.d.ts +38 -0
  325. package/lib/types/components/NavigationMenu/NavigationMenu.d.ts +101 -0
  326. package/lib/types/components/NoticeStack/NoticeStack.d.ts +41 -0
  327. package/lib/types/components/NumberStepper/NumberStepper.d.ts +32 -0
  328. package/lib/types/components/OtpInput/OtpInput.d.ts +31 -0
  329. package/lib/types/components/Pagination/Pagination.d.ts +54 -0
  330. package/lib/types/components/Pagination/paginationRange.d.ts +7 -0
  331. package/lib/types/components/PhoneInput/PhoneInput.d.ts +47 -0
  332. package/lib/types/components/PieChart/PieChart.d.ts +67 -0
  333. package/lib/types/components/PieChart/arc.d.ts +26 -0
  334. package/lib/types/components/PieChart/useArcTween.d.ts +15 -0
  335. package/lib/types/components/Popover/Popover.d.ts +28 -0
  336. package/lib/types/components/ProgressTracker/ProgressTracker.d.ts +64 -0
  337. package/lib/types/components/Rating/Rating.d.ts +42 -0
  338. package/lib/types/components/Resizable/Resizable.d.ts +50 -0
  339. package/lib/types/components/Resizable/layout.d.ts +31 -0
  340. package/lib/types/components/ScaledPreview/ScaledPreview.d.ts +38 -0
  341. package/lib/types/components/ScatterChart/ScatterChart.d.ts +81 -0
  342. package/lib/types/components/ScatterChart/scatter.d.ts +14 -0
  343. package/lib/types/components/ScrollArea/ScrollArea.d.ts +34 -0
  344. package/lib/types/components/Select/Select.d.ts +39 -0
  345. package/lib/types/components/Sidebar/Sidebar.d.ts +39 -0
  346. package/lib/types/components/Skeleton/Skeleton.d.ts +47 -0
  347. package/lib/types/components/Slider/Slider.d.ts +36 -0
  348. package/lib/types/components/SocialLoginButton/SocialLoginButton.d.ts +10 -0
  349. package/lib/types/components/SparkChart/SparkChart.d.ts +55 -0
  350. package/lib/types/components/SparkChart/spark.d.ts +16 -0
  351. package/lib/types/components/Sparkbar/Sparkbar.d.ts +39 -0
  352. package/lib/types/components/SplitView/SplitView.d.ts +31 -0
  353. package/lib/types/components/Stat/Stat.d.ts +58 -0
  354. package/lib/types/components/StepList/StepList.d.ts +61 -0
  355. package/lib/types/components/Table/Table.d.ts +39 -0
  356. package/lib/types/components/Tabs/Tabs.d.ts +47 -0
  357. package/lib/types/components/TagInput/TagInput.d.ts +46 -0
  358. package/lib/types/components/TimePicker/TimePicker.d.ts +43 -0
  359. package/lib/types/components/TimePicker/time.d.ts +15 -0
  360. package/lib/types/components/Timeline/Timeline.d.ts +154 -0
  361. package/lib/types/components/Timeline/scale.d.ts +22 -0
  362. package/lib/types/components/Toast/Toaster.d.ts +19 -0
  363. package/lib/types/components/Toast/index.d.ts +4 -0
  364. package/lib/types/components/Toast/store.d.ts +75 -0
  365. package/lib/types/components/ToggleGroup/ToggleGroup.d.ts +28 -0
  366. package/lib/types/components/Toolbar/Toolbar.d.ts +70 -0
  367. package/lib/types/components/Tracker/Tracker.d.ts +43 -0
  368. package/lib/types/components/TreeDiagram/TreeDiagram.d.ts +68 -0
  369. package/lib/types/components/TreeView/TreeView.d.ts +107 -0
  370. package/lib/types/components/index.d.ts +188 -0
  371. package/lib/types/hooks/index.d.ts +17 -0
  372. package/lib/types/hooks/timing.d.ts +29 -0
  373. package/lib/types/hooks/useControllableState.d.ts +5 -0
  374. package/lib/types/hooks/useCountdown.d.ts +19 -0
  375. package/lib/types/hooks/useDigitInput.d.ts +24 -0
  376. package/lib/types/hooks/useDismiss.d.ts +3 -0
  377. package/lib/types/hooks/useElapsed.d.ts +28 -0
  378. package/lib/types/hooks/useFloating.d.ts +21 -0
  379. package/lib/types/hooks/useFocusTrap.d.ts +7 -0
  380. package/lib/types/hooks/usePresence.d.ts +8 -0
  381. package/lib/types/hooks/usePressToOpen.d.ts +20 -0
  382. package/lib/types/hooks/useScrollLock.d.ts +2 -0
  383. package/lib/types/hooks/useSelection.d.ts +29 -0
  384. package/lib/types/index.d.ts +5 -0
  385. package/lib/types/primitives/AspectRatio.d.ts +14 -0
  386. package/lib/types/primitives/BrandIcon.d.ts +12 -0
  387. package/lib/types/primitives/ColorDot.d.ts +20 -0
  388. package/lib/types/primitives/CopyButton.d.ts +12 -0
  389. package/lib/types/primitives/CountBadge.d.ts +28 -0
  390. package/lib/types/primitives/Countdown.d.ts +21 -0
  391. package/lib/types/primitives/Delta.d.ts +33 -0
  392. package/lib/types/primitives/Elapsed.d.ts +23 -0
  393. package/lib/types/primitives/FileIcon.d.ts +17 -0
  394. package/lib/types/primitives/Flag.d.ts +15 -0
  395. package/lib/types/primitives/IconStack.d.ts +27 -0
  396. package/lib/types/primitives/IconTile.d.ts +24 -0
  397. package/lib/types/primitives/Kbd.d.ts +19 -0
  398. package/lib/types/primitives/Layout.d.ts +64 -0
  399. package/lib/types/primitives/Link.d.ts +12 -0
  400. package/lib/types/primitives/MaskedText.d.ts +28 -0
  401. package/lib/types/primitives/Progress.d.ts +52 -0
  402. package/lib/types/primitives/RelativeTime.d.ts +22 -0
  403. package/lib/types/primitives/SearchInput.d.ts +8 -0
  404. package/lib/types/primitives/SelectorButton.d.ts +23 -0
  405. package/lib/types/primitives/Spinner.d.ts +15 -0
  406. package/lib/types/primitives/StatusIcon.d.ts +40 -0
  407. package/lib/types/primitives/Swatch.d.ts +11 -0
  408. package/lib/types/primitives/Tooltip.d.ts +17 -0
  409. package/lib/types/primitives/Typography.d.ts +48 -0
  410. package/lib/types/primitives/formatCountdown.d.ts +2 -0
  411. package/lib/types/primitives/formatElapsed.d.ts +8 -0
  412. package/lib/types/primitives/formatRelativeTime.d.ts +16 -0
  413. package/lib/types/primitives/hotkey.d.ts +10 -0
  414. package/lib/types/primitives/index.d.ts +188 -0
  415. package/lib/types/primitives/maskValue.d.ts +24 -0
  416. package/package.json +55 -4
@@ -0,0 +1,313 @@
1
+ # StepList
2
+
3
+ > 진행 표시 · `@iamfiro/design` · 직접 만들지 말고 이 컴포넌트를 쓴다.
4
+
5
+ 단계를 세로로 이어 보여 주는 읽기 전용 타임라인. 단계마다 왼쪽에 상태 마커(StatusIcon 또는 번호 원)가 있고 가는 연결선으로 이어져요. 제목 오른쪽엔 걸린 시간 같은 meta, 아래엔 회색 설명과 접는 줄 · 경고 줄 같은 내용을 넣어요. 상태가 바뀌면 마커가 자연스럽게 넘어가고, connector="progress"면 끝난 구간의 선이 아래로 차올라요. 사용자가 직접 체크하는 목록은 ProgressTracker를 써요.
6
+
7
+ ```tsx
8
+ import { StepList, StepListItem } from '@iamfiro/design'
9
+ ```
10
+
11
+ ## 디자인 규칙
12
+
13
+ - 읽기 전용 단계 타임라인(계획 · 활동 기록 · 승인 흐름)은 `StepList`(`ol`, 마커 + 연결선, `meta` 시간, 아래 내용엔 Collapsible inline). 번호 원은 `StatusIcon number`(`persistNumber`면 모든 상태에서 번호). 사용자가 체크하는 목록은 `ProgressTracker`. 카드 아래 상태 띠는 `CardFooter band`.
14
+
15
+ ## API
16
+
17
+ ### StepList
18
+
19
+ <ol>로 그려지고 진행 중(active) 단계엔 aria-current="step"이 붙어요.
20
+
21
+ | prop | 타입 | 기본값 | 설명 |
22
+ | --- | --- | --- | --- |
23
+ | `steps` | `StepListStep[]` | | 단계 데이터. 대신 StepListItem을 children으로 조립해도 돼요. |
24
+ | `marker` | `'status' \| 'number' \| 'status-number'` | `'status'` | status: StatusIcon · number: 모든 단계에 번호(테두리가 상태 색) · status-number: StatusIcon인데 대기 단계만 번호. |
25
+ | `connector` | `'default' \| 'progress' \| 'none'` | `'default'` | default: 회색 선 · progress: 끝난 단계 아래 구간이 파랗게 차올라요 · none: 선 없음. |
26
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 마커 16 · 18 · 22px와 제목 · 설명 글자 크기. |
27
+ | `density` | `'compact' \| 'default' \| 'comfortable'` | `'default'` | 단계 사이 간격 12 · 20 · 32px. |
28
+ | `start` | `number` | `1` | 번호 마커의 첫 번호. |
29
+ | `aria-label` | `string` | | 목록 이름. |
30
+ | `className / style` | `string / CSSProperties` | | <ol>에 전달. |
31
+
32
+ ### StepListStep / StepListItem
33
+
34
+ steps 배열의 항목(id 필수)과 StepListItem의 props는 같아요.
35
+
36
+ | prop | 타입 | 기본값 | 설명 |
37
+ | --- | --- | --- | --- |
38
+ | `id` (필수) | `string` | | steps 배열에서만. key로 쓰여요. |
39
+ | `status` (필수) | `'done' \| 'active' \| 'pending' \| 'error' \| 'warning'` | | 단계 상태. |
40
+ | `title` (필수) | `ReactNode` | | 제목. |
41
+ | `description` | `ReactNode` | | 제목 아래 회색 글. Text variant="code" 칩을 함께 넣을 수 있어요. |
42
+ | `meta` | `ReactNode` | | 제목 줄 오른쪽 끝(걸린 시간 "1.9초", Elapsed). |
43
+ | `children` | `ReactNode` | | 설명 아래 내용(Collapsible inline, 경고 줄, FileChip). |
44
+ | `marker` | `'status' \| 'number' \| 'status-number' \| ReactNode` | | 이 단계만 다른 마커. 노드를 넘기면 그대로 그려요. |
45
+ | `number` | `number \| string` | | 번호 마커의 숫자. 기본은 순서(start부터). |
46
+ | `progress` | `number` | | active일 때 0–100. 링이 돌지 않고 그만큼 채워져요. |
47
+
48
+ ## 예제
49
+
50
+ 예제를 감싼 `style={{ ... }}` div는 미리보기 배치용이다. 실제 화면 배치는 `Stack` · `Inline` · `Grid`로 한다.
51
+
52
+ ### 계획 카드
53
+
54
+ Card + CardHeader(eyebrow 오버라인) + StepList + CardFooter band. marker="status-number"라 대기 단계는 번호, 진행 중은 파란 링, 완료는 회색 체크예요. 진행 중 단계와 아래 띠의 경과 시간은 Elapsed로 계속 올라가요.
55
+
56
+ ```tsx
57
+ import { ListChecks } from 'lucide-react'
58
+ import { Elapsed, Inline, StatusIcon, Text, formatElapsed, Card, CardBody, CardFooter, CardHeader, StepList, type StepListStep } from '@iamfiro/design'
59
+
60
+ const STEPS: StepListStep[] = [
61
+ {
62
+ id: 'collect',
63
+ status: 'done',
64
+ title: '분기 실적 자료 모으기',
65
+ description: (
66
+ <>
67
+ 재무팀 공유 폴더에서 <Text variant="code">q3-actuals.xlsx</Text> 불러옴
68
+ </>
69
+ ),
70
+ meta: '1.9초',
71
+ },
72
+ {
73
+ id: 'compare',
74
+ status: 'done',
75
+ title: '계획 대비 실적 비교',
76
+ description: (
77
+ <>
78
+ 부서별 차이를 <Text variant="code">variance</Text> 시트로 정리
79
+ </>
80
+ ),
81
+ meta: '42초',
82
+ },
83
+ {
84
+ id: 'charts',
85
+ status: 'done',
86
+ title: '핵심 지표 차트 만들기',
87
+ description: '매출 · 영업이익 · 현금흐름 차트 3개',
88
+ meta: '3분 12초',
89
+ },
90
+ {
91
+ id: 'draft',
92
+ status: 'active',
93
+ title: '보고서 초안 작성',
94
+ description: (
95
+ <>
96
+ <Text variant="code">board-update-q3.docx</Text>에 요약과 차트를 넣는 중
97
+ </>
98
+ ),
99
+ // The running step keeps its own timer.
100
+ meta: <Elapsed initial={1052} format={(s) => formatElapsed(s, 'text')} />,
101
+ },
102
+ { id: 'review', status: 'pending', title: '검토 요청 보내기', description: '김민지 팀장에게 검토 요청' },
103
+ ]
104
+
105
+ export default function Example() {
106
+ const done = STEPS.filter((s) => s.status === 'done').length
107
+ return (
108
+ <Card style={{ width: '100%', maxWidth: 480 }}>
109
+ <CardHeader
110
+ eyebrow={
111
+ <Inline gap={1} wrap={false}>
112
+ <ListChecks size={14} aria-hidden />
113
+ 계획 · {STEPS.length}단계
114
+ </Inline>
115
+ }
116
+ title="3분기 이사회 보고서 준비"
117
+ />
118
+ <CardBody>
119
+ <StepList steps={STEPS} marker="status-number" aria-label="보고서 준비 단계" />
120
+ </CardBody>
121
+ <CardFooter band align="between">
122
+ <Inline gap={2} wrap={false}>
123
+ <StatusIcon status="active" size="sm" decorative />
124
+ <Text variant="label-sm" tone="secondary" numeric>
125
+ 실행 중 · {done + 1}/{STEPS.length}
126
+ </Text>
127
+ </Inline>
128
+ <Text variant="label-sm" tone="tertiary">
129
+ <Elapsed initial={1060} />
130
+ </Text>
131
+ </CardFooter>
132
+ </Card>
133
+ )
134
+ }
135
+ ```
136
+
137
+ ### 활동 기록
138
+
139
+ StepListItem을 직접 조립해요. marker="number"는 모든 단계에 번호를 두고 테두리 색만 상태를 따라가요. 내용 자리엔 IconStack 타일을 단 Collapsible variant="inline"과 주황 경고 줄을 넣었어요. 마지막 단계처럼 marker에 노드를 넘기면 원하는 아이콘을 써요.
140
+
141
+ ```tsx
142
+ import type { ReactNode } from 'react'
143
+ import { FileSearch, ListChecks, Server, ShieldCheck, TestTube } from 'lucide-react'
144
+ import { IconStack, IconTile, Inline, Stack, Text, Collapsible, StepList, StepListItem } from '@iamfiro/design'
145
+
146
+ const tile = (key: string, icon: ReactNode) => (
147
+ <IconTile key={key} size={18}>
148
+ {icon}
149
+ </IconTile>
150
+ )
151
+
152
+ export default function Example() {
153
+ return (
154
+ <Stack gap={3} style={{ width: '100%', maxWidth: 480 }}>
155
+ <Text as="h3" variant="heading-xs">
156
+ 활동
157
+ </Text>
158
+ <StepList marker="number" aria-label="배포 활동">
159
+ <StepListItem status="done" title="배포 설정 확인">
160
+ <Collapsible
161
+ variant="inline"
162
+ icon={
163
+ <IconStack
164
+ shape="square"
165
+ size={18}
166
+ overlap={4}
167
+ icons={[tile('config', <FileSearch size={11} />), tile('security', <ShieldCheck size={11} />)]}
168
+ label="설정 검사, 보안 검사"
169
+ />
170
+ }
171
+ label="검사 2개 · 1.2초"
172
+ >
173
+ <Text variant="body-sm" tone="secondary">
174
+ 환경 변수 14개, 보안 정책 3개 모두 통과
175
+ </Text>
176
+ </Collapsible>
177
+ </StepListItem>
178
+ <StepListItem status="done" title="테스트 실행">
179
+ <Collapsible
180
+ variant="inline"
181
+ icon={<IconStack shape="square" size={18} icons={[tile('unit', <TestTube size={11} />)]} label="단위 테스트" />}
182
+ label="테스트 묶음 1개 · 2분 4초"
183
+ >
184
+ <Text variant="body-sm" tone="secondary">
185
+ 812개 통과 · 건너뜀 3개
186
+ </Text>
187
+ </Collapsible>
188
+ </StepListItem>
189
+ <StepListItem status="done" title="스테이징 서버에 배포" description="v2.14.0 · 서버 4대" />
190
+ <StepListItem status="warning" title="운영 서버에 배포">
191
+ <Inline gap={1} wrap={false}>
192
+ <Text as="span" tone="warning" style={{ display: 'inline-flex' }}>
193
+ <ListChecks size={14} aria-hidden />
194
+ </Text>
195
+ <Text variant="label-sm" tone="warning">
196
+ 승인을 기다리고 있어요
197
+ </Text>
198
+ </Inline>
199
+ </StepListItem>
200
+ <StepListItem
201
+ status="pending"
202
+ title="배포 후 모니터링"
203
+ description="마커는 직접 넣을 수도 있어요"
204
+ marker={
205
+ <IconTile size={18} round>
206
+ <Server size={11} />
207
+ </IconTile>
208
+ }
209
+ />
210
+ </StepList>
211
+ </Stack>
212
+ )
213
+ }
214
+ ```
215
+
216
+ ### 상태 변화
217
+
218
+ "다음 단계"를 누르면 마커가 링 → 체크로 넘어가고, connector="progress"의 파란 선이 다음 단계까지 위에서 아래로 차올라요.
219
+
220
+ ```tsx
221
+ import { useState } from 'react'
222
+ import { RotateCcw } from 'lucide-react'
223
+ import { Button, Inline, Stack, StepList, type StepListStatus, type StepListStep } from '@iamfiro/design'
224
+
225
+ const TITLES = ['코드 가져오기', '빌드', '테스트', '이미지 올리기', '배포']
226
+
227
+ export default function Example() {
228
+ // How many steps are finished; the one after them is running.
229
+ const [done, setDone] = useState(1)
230
+ const steps: StepListStep[] = TITLES.map((title, i) => {
231
+ const status: StepListStatus = i < done ? 'done' : i === done ? 'active' : 'pending'
232
+ return { id: title, status, title, meta: i < done ? `${(i + 1) * 7}초` : undefined }
233
+ })
234
+ return (
235
+ <Stack gap={4} style={{ width: '100%', maxWidth: 360 }}>
236
+ <StepList steps={steps} connector="progress" marker="status-number" density="compact" aria-label="배포 파이프라인" />
237
+ <Inline gap={2}>
238
+ <Button size="sm" variant="primary" disabled={done >= TITLES.length} onClick={() => setDone((d) => d + 1)}>
239
+ 다음 단계
240
+ </Button>
241
+ <Button size="sm" variant="ghost" icon={<RotateCcw />} onClick={() => setDone(0)}>
242
+ 처음부터
243
+ </Button>
244
+ </Inline>
245
+ </Stack>
246
+ )
247
+ }
248
+ ```
249
+
250
+ ### 상태
251
+
252
+ done · active · pending · error · warning. 기본 marker="status"는 대기를 회색 점선 원으로 그려요.
253
+
254
+ ```tsx
255
+ import { Text, StepList, type StepListStep } from '@iamfiro/design'
256
+
257
+ const STEPS: StepListStep[] = [
258
+ { id: 'submit', status: 'done', title: '휴가 신청서 제출', description: '이도현 · 10월 25일 오전 9:30' },
259
+ { id: 'lead', status: 'done', title: '팀장 승인', description: '김민지', meta: '12분' },
260
+ {
261
+ id: 'hr',
262
+ status: 'error',
263
+ title: '인사팀 확인',
264
+ description: (
265
+ <>
266
+ 남은 연차가 부족해요 · <Text variant="code">잔여 1.5일</Text>
267
+ </>
268
+ ),
269
+ meta: '3분',
270
+ },
271
+ { id: 'fix', status: 'warning', title: '신청 기간 수정', description: '3일 → 1.5일로 바꿔 주세요' },
272
+ { id: 'final', status: 'pending', title: '최종 승인' },
273
+ ]
274
+
275
+ export default function Example() {
276
+ return <StepList steps={STEPS} aria-label="휴가 승인 단계" style={{ width: '100%', maxWidth: 400 }} />
277
+ }
278
+ ```
279
+
280
+ ### 크기 · 밀도
281
+
282
+ size는 마커와 글자 크기(sm 16 · md 18 · lg 22px), density는 단계 사이 간격(compact 12 · default 20 · comfortable 32px)이에요.
283
+
284
+ ```tsx
285
+ import { Grid, Stack, Text, StepList, type StepListDensity, type StepListSize, type StepListStep } from '@iamfiro/design'
286
+
287
+ const STEPS: StepListStep[] = [
288
+ { id: 'quote', status: 'done', title: '견적 요청', meta: '2분' },
289
+ { id: 'review', status: 'active', title: '견적서 검토' },
290
+ { id: 'sign', status: 'pending', title: '계약서 서명' },
291
+ ]
292
+
293
+ const VARIANTS: Array<{ size: StepListSize; density: StepListDensity }> = [
294
+ { size: 'sm', density: 'compact' },
295
+ { size: 'md', density: 'default' },
296
+ { size: 'lg', density: 'comfortable' },
297
+ ]
298
+
299
+ export default function Example() {
300
+ return (
301
+ <Grid minItemWidth={160} gap={6} style={{ width: '100%' }}>
302
+ {VARIANTS.map(({ size, density }) => (
303
+ <Stack key={size} gap={3}>
304
+ <Text variant="overline">
305
+ {size} · {density}
306
+ </Text>
307
+ <StepList steps={STEPS} size={size} density={density} marker="number" aria-label={`${size} 크기`} />
308
+ </Stack>
309
+ ))}
310
+ </Grid>
311
+ )
312
+ }
313
+ ```
@@ -0,0 +1,286 @@
1
+ # Table
2
+
3
+ > 데이터 표시 · `@iamfiro/design` · 직접 만들지 말고 이 컴포넌트를 쓴다.
4
+
5
+ 격자선 없는 데이터 표. 머리글은 작은 회색 글씨로, 행은 선 대신 옅은 채움으로 구분해요. 열마다 render로 셀을 직접 그리고, 숫자 열은 자릿수가 맞게 정렬해요. 가로로 넘치면 표만 스크롤돼요.
6
+
7
+ ```tsx
8
+ import { Table, type TableColumn } from '@iamfiro/design'
9
+ ```
10
+
11
+ ## 디자인 규칙
12
+
13
+ - 차트에서 한 칸을 고르는 화면(피벗)은 `BarChart selected` + `Table selectedKey`를 같은 상태로 묶는다. 고르지 않은 칸은 옅은 색, 고른 칸의 x축 아이콘(`xIcon`)은 흰 칩으로 펼친다. 임계치·이상 구간은 `LineChart referenceLines` · `bands`, 실시간 데이터는 `streaming`(모양 변형 대신 한 칸 미끄러짐) + `endDot="pulse"`.
14
+ - 표: 보여 주기만 하면 `Table`, 편집·정렬·필터·범위 선택이 필요하면 `DataGrid`. 셀 편집·키 입력·클립보드·한글 IME는 셀 위에 놓인 textarea 하나가 모두 받는다(조합 중에 포커스를 옮기면 한글이 깨진다).
15
+
16
+ ## API
17
+
18
+ ### Table
19
+
20
+ | prop | 타입 | 기본값 | 설명 |
21
+ | --- | --- | --- | --- |
22
+ | `columns` (필수) | `TableColumn<Row>[]` | | 열 정의. |
23
+ | `rows` (필수) | `Row[]` | | 데이터 행. |
24
+ | `rowKey` | `(row, index) => string \| number` | | 행마다 고유한 key. 생략하면 index. |
25
+ | `density` | `'default' \| 'compact'` | `'default'` | 행 높이. |
26
+ | `striped` | `boolean` | `true` | 행을 번갈아 채워 구분해요. |
27
+ | `headerVariant` | `'label' \| 'overline'` | `'label'` | 머리글 모양. overline은 작은 대문자. |
28
+ | `selectedKey` | `string \| number \| null` | | rowKey가 같은 행을 옅은 회색으로 채워요. |
29
+ | `onRowClick` | `(row, index) => void` | | 행을 누를 때(클릭 · Enter/Space). 주면 hover 채움과 포커스가 생겨요. |
30
+ | `empty` | `ReactNode` | | 행이 없을 때 보여 줄 내용. |
31
+ | `caption` | `ReactNode` | | 표 위 작은 제목. |
32
+ | `className / style` | `string / CSSProperties` | | 스크롤 래퍼에 적용돼요. |
33
+
34
+ ### TableColumn
35
+
36
+ | prop | 타입 | 기본값 | 설명 |
37
+ | --- | --- | --- | --- |
38
+ | `key` (필수) | `string` | | 열 id. render가 없으면 row[key]를 보여 줘요. |
39
+ | `header` (필수) | `ReactNode` | | 머리글. |
40
+ | `headerLeading` | `ReactNode` | | 머리글 앞 요소(시리즈 열의 ColorDot). |
41
+ | `render` | `(row, index) => ReactNode` | | 셀 내용을 직접 그릴 때. |
42
+ | `leading` | `(row, index) => ReactNode` | | 셀 내용 앞 요소(첫 열 아이콘). |
43
+ | `width` | `number \| string` | | 열 너비. |
44
+ | `align` | `'start' \| 'center' \| 'end'` | `numeric ? 'end' : 'start'` | 머리글과 셀 정렬. |
45
+ | `numeric` | `boolean` | | 숫자 열. 자릿수가 맞는 tabular 숫자에 기본 오른쪽 정렬. |
46
+
47
+ ## 예제
48
+
49
+ 예제를 감싼 `style={{ ... }}` div는 미리보기 배치용이다. 실제 화면 배치는 `Stack` · `Inline` · `Grid`로 한다.
50
+
51
+ ### 기본
52
+
53
+ columns와 rows를 넘겨요. render가 없으면 row[key]를 그대로 보여 주고, numeric 열은 tabular 숫자로, align="end"면 오른쪽 정렬돼요.
54
+
55
+ ```tsx
56
+ import { Avatar, Badge, Text, type Tone, Table, type TableColumn } from '@iamfiro/design'
57
+
58
+ interface Member {
59
+ id: string
60
+ name: string
61
+ email: string
62
+ role: string
63
+ status: 'active' | 'invited' | 'suspended'
64
+ lastSeen: string
65
+ storage: number
66
+ }
67
+
68
+ const MEMBERS: Member[] = [
69
+ { id: 'u1', name: '김민지', email: 'minji@lumen.app', role: '관리자', status: 'active', lastSeen: '2분 전', storage: 12.4 },
70
+ { id: 'u2', name: '이도현', email: 'dohyun@lumen.app', role: '편집자', status: 'active', lastSeen: '1시간 전', storage: 8.15 },
71
+ { id: 'u3', name: '박서연', email: 'seoyeon@lumen.app', role: '편집자', status: 'invited', lastSeen: '—', storage: 0 },
72
+ { id: 'u4', name: '최준호', email: 'junho@lumen.app', role: '뷰어', status: 'suspended', lastSeen: '10월 3일', storage: 1.02 },
73
+ ]
74
+
75
+ const STATUS: Record<Member['status'], { label: string; tone: Tone }> = {
76
+ active: { label: '활성', tone: 'success' },
77
+ invited: { label: '초대됨', tone: 'info' },
78
+ suspended: { label: '정지', tone: 'danger' },
79
+ }
80
+
81
+ const COLUMNS: TableColumn<Member>[] = [
82
+ {
83
+ key: 'name',
84
+ header: '멤버',
85
+ render: (m) => (
86
+ <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
87
+ <Avatar name={m.name} />
88
+ <div>
89
+ <Text variant="label-md" as="div">
90
+ {m.name}
91
+ </Text>
92
+ <Text variant="caption" tone="tertiary" as="div">
93
+ {m.email}
94
+ </Text>
95
+ </div>
96
+ </div>
97
+ ),
98
+ },
99
+ { key: 'role', header: '역할' },
100
+ {
101
+ key: 'status',
102
+ header: '상태',
103
+ render: (m) => (
104
+ <Badge tone={STATUS[m.status].tone} dot>
105
+ {STATUS[m.status].label}
106
+ </Badge>
107
+ ),
108
+ },
109
+ { key: 'lastSeen', header: '최근 활동' },
110
+ { key: 'storage', header: '사용량', align: 'end', numeric: true, render: (m) => `${m.storage.toFixed(2)} GB` },
111
+ ]
112
+
113
+ export default function Example() {
114
+ return <Table caption="멤버 4명" columns={COLUMNS} rows={MEMBERS} rowKey={(m) => m.id} style={{ width: 640 }} />
115
+ }
116
+ ```
117
+
118
+ ### 간격 · 줄무늬
119
+
120
+ density="compact"는 행 높이를 줄여요. striped를 끄면 행 구분 채움이 사라져요.
121
+
122
+ ```tsx
123
+ import { useState } from 'react'
124
+ import { SegmentedControl, Switch, Table, type TableColumn } from '@iamfiro/design'
125
+
126
+ interface Invoice {
127
+ id: string
128
+ date: string
129
+ plan: string
130
+ seats: number
131
+ amount: number
132
+ }
133
+
134
+ const INVOICES: Invoice[] = [
135
+ { id: 'INV-2610', date: '10월 1일', plan: '팀', seats: 12, amount: 180000 },
136
+ { id: 'INV-2609', date: '9월 1일', plan: '팀', seats: 10, amount: 150000 },
137
+ { id: 'INV-2608', date: '8월 1일', plan: '팀', seats: 10, amount: 150000 },
138
+ { id: 'INV-2607', date: '7월 1일', plan: '스타터', seats: 4, amount: 36000 },
139
+ { id: 'INV-2606', date: '6월 1일', plan: '스타터', seats: 3, amount: 27000 },
140
+ ]
141
+
142
+ const COLUMNS: TableColumn<Invoice>[] = [
143
+ { key: 'id', header: '청구서' },
144
+ { key: 'date', header: '발행일' },
145
+ { key: 'plan', header: '플랜' },
146
+ { key: 'seats', header: '좌석', align: 'end', numeric: true },
147
+ { key: 'amount', header: '금액', align: 'end', numeric: true, render: (r) => `${r.amount.toLocaleString('ko-KR')}원` },
148
+ ]
149
+
150
+ export default function Example() {
151
+ const [density, setDensity] = useState<'default' | 'compact'>('default')
152
+ const [striped, setStriped] = useState(true)
153
+
154
+ return (
155
+ <div style={{ display: 'grid', gap: 16, width: 560 }}>
156
+ <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
157
+ <SegmentedControl
158
+ value={density}
159
+ onChange={setDensity}
160
+ ariaLabel="행 간격"
161
+ options={[
162
+ { value: 'default', label: '기본' },
163
+ { value: 'compact', label: '촘촘하게' },
164
+ ]}
165
+ />
166
+ <Switch label="줄무늬" checked={striped} onChange={(e) => setStriped(e.target.checked)} />
167
+ </div>
168
+ <Table columns={COLUMNS} rows={INVOICES} rowKey={(r) => r.id} density={density} striped={striped} />
169
+ </div>
170
+ )
171
+ }
172
+ ```
173
+
174
+ ### 빈 상태
175
+
176
+ 행이 없으면 empty에 넣은 내용(보통 EmptyState)을 표 너비 전체에 보여 줘요.
177
+
178
+ ```tsx
179
+ import { useState } from 'react'
180
+ import { SearchX } from 'lucide-react'
181
+ import { Button, SearchInput, EmptyState, Table, type TableColumn } from '@iamfiro/design'
182
+
183
+ interface Project {
184
+ name: string
185
+ owner: string
186
+ updated: string
187
+ }
188
+
189
+ const PROJECTS: Project[] = [
190
+ { name: '웹사이트 리뉴얼', owner: '김민지', updated: '2분 전' },
191
+ { name: '모바일 앱 2.0', owner: '이도현', updated: '어제' },
192
+ { name: '디자인 시스템', owner: '박서연', updated: '10월 21일' },
193
+ ]
194
+
195
+ const COLUMNS: TableColumn<Project>[] = [
196
+ { key: 'name', header: '프로젝트' },
197
+ { key: 'owner', header: '담당자' },
198
+ { key: 'updated', header: '수정', align: 'end' },
199
+ ]
200
+
201
+ export default function Example() {
202
+ const [query, setQuery] = useState('결제')
203
+ const rows = PROJECTS.filter((p) => p.name.includes(query.trim()))
204
+
205
+ return (
206
+ <div style={{ display: 'grid', gap: 16, width: 520 }}>
207
+ <SearchInput size="sm" placeholder="프로젝트 검색" value={query} onChange={(e) => setQuery(e.target.value)} aria-label="프로젝트 검색" />
208
+ <Table
209
+ columns={COLUMNS}
210
+ rows={rows}
211
+ rowKey={(p) => p.name}
212
+ empty={
213
+ <EmptyState
214
+ size="sm"
215
+ icon={<SearchX />}
216
+ title="검색 결과가 없어요"
217
+ description={`‘${query}’와 일치하는 프로젝트가 없어요.`}
218
+ actions={
219
+ <Button size="sm" onClick={() => setQuery('')}>
220
+ 검색어 지우기
221
+ </Button>
222
+ }
223
+ />
224
+ }
225
+ />
226
+ </div>
227
+ )
228
+ }
229
+ ```
230
+
231
+ ### 행 선택 · 오버라인 머리글
232
+
233
+ onRowClick을 주면 행에 hover 채움이 생기고 Tab · Enter/Space로도 눌러요. selectedKey와 같은 행은 옅은 회색으로 채워요. headerVariant="overline"은 작은 대문자 머리글, headerLeading은 머리글 앞 ColorDot, leading은 첫 열 아이콘이에요. numeric 열은 오른쪽 정렬 + tabular 숫자예요. 차트와 연동하는 예는 BarChart의 "표와 연동"을 보세요.
234
+
235
+ ```tsx
236
+ import { useState, type ReactNode } from 'react'
237
+ import { CreditCard, Globe, Search, Server, Smartphone } from 'lucide-react'
238
+ import { Table, type TableColumn, ColorDot, Stack, Text } from '@iamfiro/design'
239
+
240
+ interface Service {
241
+ id: string
242
+ name: string
243
+ icon: ReactNode
244
+ success: number
245
+ rollback: number
246
+ failed: number
247
+ }
248
+
249
+ const SERVICES: Service[] = [
250
+ { id: 'web', name: '웹', icon: <Globe size={16} color="var(--text-3)" />, success: 42, rollback: 3, failed: 2 },
251
+ { id: 'mobile', name: '모바일', icon: <Smartphone size={16} color="var(--text-3)" />, success: 18, rollback: 1, failed: 1 },
252
+ { id: 'api', name: 'API', icon: <Server size={16} color="var(--text-3)" />, success: 57, rollback: 5, failed: 4 },
253
+ { id: 'billing', name: '결제', icon: <CreditCard size={16} color="var(--text-3)" />, success: 12, rollback: 2, failed: 0 },
254
+ { id: 'search', name: '검색', icon: <Search size={16} color="var(--text-3)" />, success: 25, rollback: 0, failed: 1 },
255
+ ]
256
+
257
+ const COLUMNS: TableColumn<Service>[] = [
258
+ { key: 'name', header: '서비스', leading: (s) => s.icon },
259
+ { key: 'total', header: '배포', numeric: true, render: (s) => s.success + s.rollback + s.failed },
260
+ { key: 'success', header: '성공', headerLeading: <ColorDot color="--chart-3" />, numeric: true },
261
+ { key: 'rollback', header: '롤백', headerLeading: <ColorDot color="--warning" />, numeric: true },
262
+ { key: 'failed', header: '실패', headerLeading: <ColorDot color="--danger" />, numeric: true },
263
+ ]
264
+
265
+ export default function Example() {
266
+ const [selected, setSelected] = useState<string | null>('api')
267
+ const service = SERVICES.find((s) => s.id === selected)
268
+
269
+ return (
270
+ <Stack gap={3} style={{ width: 560 }}>
271
+ <Table
272
+ columns={COLUMNS}
273
+ rows={SERVICES}
274
+ rowKey={(s) => s.id}
275
+ headerVariant="overline"
276
+ striped={false}
277
+ selectedKey={selected}
278
+ onRowClick={(s) => setSelected((cur) => (cur === s.id ? null : s.id))}
279
+ />
280
+ <Text variant="body-sm" tone="secondary">
281
+ {service ? `${service.name} 서비스를 골랐어요. 다시 누르면 선택이 풀려요.` : '행을 누르거나 Tab으로 옮겨 Enter를 눌러 보세요.'}
282
+ </Text>
283
+ </Stack>
284
+ )
285
+ }
286
+ ```