@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,273 @@
1
+ # Progress
2
+
3
+ > 진행 표시 · `@iamfiro/design` · 직접 만들지 말고 이 컴포넌트를 쓴다.
4
+
5
+ 작업이 얼마나 진행됐는지 보여 주는 막대와 원형 표시. value가 바뀌면 부드럽게 채워지고, value를 생략하면 길이를 모르는 작업으로 계속 흘러가요. 접근성용 progressbar 역할이 함께 붙어요.
6
+
7
+ ```tsx
8
+ import { Progress, ProgressCircle } from '@iamfiro/design'
9
+ ```
10
+
11
+ ## 디자인 규칙
12
+
13
+ - 한 수량을 분류별로 나눈 조각(사용량 내역)은 범주색 대신 진한 파랑부터 옅어지는 `--chart-seq-1…5`. → `Progress segments`
14
+
15
+ ## API
16
+
17
+ ### Progress
18
+
19
+ | prop | 타입 | 기본값 | 설명 |
20
+ | --- | --- | --- | --- |
21
+ | `value` | `number` | | 0…max. 생략하면 길이를 모르는 진행(무한 반복) 표시. |
22
+ | `max` | `number` | `100` | 최댓값. |
23
+ | `tone` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | `'default'` | 막대 색. |
24
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 막대 두께. |
25
+ | `label` | `ReactNode` | | 막대 위에 보이는 이름. |
26
+ | `segments` | `{ value, label?, color? }[]` | | 채움을 여러 조각으로 나눠요. value 대신 값의 합으로 채워요. color 기본은 --chart-seq-1부터. |
27
+ | `unlimited` | `boolean` | | 한도 없음. 빗금 트랙, 채움 없음. |
28
+ | `showValue` | `boolean` | | 값을 글자로 보여 줘요(기본은 퍼센트). |
29
+ | `formatValue` | `(value, max) => ReactNode` | | 값 표시 형식. 기본은 반올림한 퍼센트(예: 64%). |
30
+ | `aria-label` | `string` | | label이 없거나 글자가 아닐 때의 접근성 이름. |
31
+ | `className / style` | `string / CSSProperties` | | 루트에 적용돼요. |
32
+ | `aria-valuetext` | `string` | | 숫자만으로 부족할 때 읽어 줄 값(예: "10명 중 8명"). segments에 label이 있으면 자동으로 만들어요. |
33
+
34
+ ### ProgressCircle
35
+
36
+ | prop | 타입 | 기본값 | 설명 |
37
+ | --- | --- | --- | --- |
38
+ | `value` | `number` | | 0…max. 생략하면 길이를 모르는 진행(무한 반복) 표시. |
39
+ | `max` | `number` | `100` | 최댓값. |
40
+ | `tone` | `'default' \| 'accent' \| 'success' \| 'warning' \| 'danger'` | `'default'` | 막대 색. |
41
+ | `size` | `number` | `44` | 지름(px). |
42
+ | `thickness` | `number` | `4` | 고리 두께(px). |
43
+ | `label` | `ReactNode` | | 원 아래에 보이는 이름. |
44
+ | `children` | `ReactNode` | | 가운데 내용. 생략하고 showValue면 값을 보여 줘요. |
45
+ | `showValue` | `boolean` | | 값을 글자로 보여 줘요(기본은 퍼센트). |
46
+ | `formatValue` | `(value, max) => ReactNode` | | 값 표시 형식. 기본은 반올림한 퍼센트(예: 64%). |
47
+ | `aria-label` | `string` | | label이 없거나 글자가 아닐 때의 접근성 이름. |
48
+ | `className / style` | `string / CSSProperties` | | 루트에 적용돼요. |
49
+
50
+ ## 예제
51
+
52
+ 예제를 감싼 `style={{ ... }}` div는 미리보기 배치용이다. 실제 화면 배치는 `Stack` · `Inline` · `Grid`로 한다.
53
+
54
+ ### 기본
55
+
56
+ label은 막대 위 왼쪽, showValue는 오른쪽에 보여요. formatValue로 표시 형식을 바꿀 수 있어요.
57
+
58
+ ```tsx
59
+ import { Progress } from '@iamfiro/design'
60
+
61
+ export default function Example() {
62
+ return (
63
+ <div style={{ display: 'grid', gap: 24, width: 360 }}>
64
+ <Progress value={64} label="프로필 완성도" showValue />
65
+ <Progress value={9.2} max={10} label="저장 공간" showValue formatValue={(value, max) => `${value}GB / ${max}GB`} tone="warning" />
66
+ <Progress value={40} aria-label="온보딩 진행률" />
67
+ </div>
68
+ )
69
+ }
70
+ ```
71
+
72
+ ### 색 · 크기
73
+
74
+ tone으로 상태를 나타내고, size로 막대 두께(sm / md / lg)를 골라요.
75
+
76
+ ```tsx
77
+ import { Progress, type ProgressTone } from '@iamfiro/design'
78
+
79
+ const TONES: Array<[ProgressTone, string, number]> = [
80
+ ['default', '기본', 72],
81
+ ['accent', '강조', 58],
82
+ ['success', '완료', 100],
83
+ ['warning', '주의', 88],
84
+ ['danger', '초과', 96],
85
+ ]
86
+
87
+ export default function Example() {
88
+ return (
89
+ <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(220px, 1fr))', gap: 32, width: '100%', maxWidth: 520 }}>
90
+ <div style={{ display: 'grid', gap: 18 }}>
91
+ {TONES.map(([tone, label, value]) => (
92
+ <Progress key={tone} tone={tone} value={value} label={label} showValue />
93
+ ))}
94
+ </div>
95
+ <div style={{ display: 'grid', gap: 18, alignContent: 'start' }}>
96
+ <Progress size="sm" value={45} label="작게 (sm)" />
97
+ <Progress size="md" value={45} label="기본 (md)" />
98
+ <Progress size="lg" value={45} label="크게 (lg)" />
99
+ </div>
100
+ </div>
101
+ )
102
+ }
103
+ ```
104
+
105
+ ### 원형
106
+
107
+ ProgressCircle은 카드·업로드·용량처럼 좁은 곳에 써요. size와 thickness는 px, 가운데 내용은 children으로 바꿀 수 있어요.
108
+
109
+ ```tsx
110
+ import { Check } from 'lucide-react'
111
+ import { ProgressCircle } from '@iamfiro/design'
112
+
113
+ export default function Example() {
114
+ return (
115
+ <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'flex-end', justifyContent: 'center', gap: 32 }}>
116
+ <ProgressCircle value={30} size={32} thickness={3} aria-label="업로드" />
117
+ <ProgressCircle value={64} showValue label="오늘 목표" />
118
+ <ProgressCircle value={82} size={64} thickness={6} tone="warning" showValue label="저장 공간" />
119
+ <ProgressCircle value={100} size={64} thickness={6} tone="success" label="설정 완료">
120
+ <Check size={22} />
121
+ </ProgressCircle>
122
+ <ProgressCircle value={7} max={10} size={80} thickness={8} tone="accent" showValue formatValue={(value, max) => `${value}/${max}`} label="완료한 할 일" />
123
+ </div>
124
+ )
125
+ }
126
+ ```
127
+
128
+ ### 진행률을 모를 때
129
+
130
+ value를 넘기지 않으면 끝없이 흐르는 막대 · 도는 원으로 바뀌고 aria-busy가 붙어요.
131
+
132
+ ```tsx
133
+ import { Progress, ProgressCircle } from '@iamfiro/design'
134
+
135
+ export default function Example() {
136
+ return (
137
+ <div style={{ display: 'flex', alignItems: 'center', gap: 32 }}>
138
+ <Progress label="파일 목록 불러오는 중" style={{ width: 280 }} />
139
+ <ProgressCircle tone="accent" aria-label="처리 중" />
140
+ </div>
141
+ )
142
+ }
143
+ ```
144
+
145
+ ### 업로드 흐름
146
+
147
+ 확인 중에는 진행률을 모르는 상태로, 업로드가 시작되면 실제 값으로, 끝나면 success 색으로 바꿔요.
148
+
149
+ ```tsx
150
+ import { useEffect, useState } from 'react'
151
+ import { FileText, Upload } from 'lucide-react'
152
+ import { Button, Progress, Card, CardBody, CardFooter, CardHeader } from '@iamfiro/design'
153
+
154
+ type Status = 'idle' | 'preparing' | 'uploading' | 'done'
155
+
156
+ const LABEL: Record<Status, string> = {
157
+ idle: '업로드 대기',
158
+ preparing: '파일 확인 중…',
159
+ uploading: '업로드 중…',
160
+ done: '업로드 완료',
161
+ }
162
+
163
+ export default function Example() {
164
+ const [status, setStatus] = useState<Status>('idle')
165
+ const [percent, setPercent] = useState(0)
166
+
167
+ // 실제 앱에서는 업로드 요청의 progress 이벤트로 percent를 채워요.
168
+ useEffect(() => {
169
+ if (status === 'preparing') {
170
+ const timer = setTimeout(() => setStatus('uploading'), 900)
171
+ return () => clearTimeout(timer)
172
+ }
173
+ if (status !== 'uploading') return
174
+ const timer = setTimeout(() => {
175
+ const next = Math.min(100, Math.round(percent + 4 + Math.random() * 10))
176
+ setPercent(next)
177
+ if (next === 100) setStatus('done')
178
+ }, 300)
179
+ return () => clearTimeout(timer)
180
+ }, [status, percent])
181
+
182
+ const start = () => {
183
+ setPercent(0)
184
+ setStatus('preparing')
185
+ }
186
+
187
+ return (
188
+ <Card style={{ width: 380 }}>
189
+ <CardHeader icon={<FileText />} title="3분기 이사회 보고서.pdf" description="4.2MB" />
190
+ <CardBody>
191
+ <Progress
192
+ value={status === 'preparing' ? undefined : percent}
193
+ tone={status === 'done' ? 'success' : 'accent'}
194
+ label={LABEL[status]}
195
+ showValue
196
+ />
197
+ </CardBody>
198
+ <CardFooter>
199
+ <Button variant="primary" icon={<Upload />} loading={status === 'preparing' || status === 'uploading'} onClick={start}>
200
+ {status === 'done' ? '다시 업로드' : '업로드'}
201
+ </Button>
202
+ </CardFooter>
203
+ </Card>
204
+ )
205
+ }
206
+ ```
207
+
208
+ ### 나눠진 막대 (segments)
209
+
210
+ 한 수량을 분류별로 나눠 보여줘요. 채워진 길이는 값의 합이고, 조각 사이엔 작은 틈, 나머지는 회색 트랙이에요. 색을 생략하면 진한 파랑부터 옅어지는 --chart-seq-1…5. 값이 바뀌면 조각이 새 폭으로 미끄러지고, 조각 이름은 aria-valuetext로 읽어요.
211
+
212
+ ```tsx
213
+ import { useState } from 'react'
214
+ import { Button, Inline, Progress, Stack, type ProgressSegment } from '@iamfiro/design'
215
+
216
+ const MONTHS: Record<string, ProgressSegment[]> = {
217
+ '9월': [
218
+ { label: '문서', value: 42 },
219
+ { label: '사진', value: 23 },
220
+ { label: '동영상', value: 16 },
221
+ { label: '기타', value: 9 },
222
+ ],
223
+ '10월': [
224
+ { label: '문서', value: 30 },
225
+ { label: '사진', value: 18 },
226
+ { label: '동영상', value: 12 },
227
+ { label: '기타', value: 6 },
228
+ ],
229
+ }
230
+
231
+ export default function Example() {
232
+ const [month, setMonth] = useState('10월')
233
+ return (
234
+ <Stack gap={6} style={{ width: '100%', maxWidth: 420 }}>
235
+ <Progress segments={MONTHS[month]} label="저장 공간" showValue aria-label="저장 공간" />
236
+ <Progress
237
+ size="lg"
238
+ label="분류 색 직접 지정"
239
+ segments={[
240
+ { label: '완료', value: 48, color: '--success' },
241
+ { label: '진행 중', value: 22, color: '--accent' },
242
+ { label: '막힘', value: 8, color: '--danger' },
243
+ ]}
244
+ />
245
+ <Inline gap={2}>
246
+ {Object.keys(MONTHS).map((m) => (
247
+ <Button key={m} size="sm" variant={m === month ? 'primary' : 'secondary'} onClick={() => setMonth(m)}>
248
+ {m}
249
+ </Button>
250
+ ))}
251
+ </Inline>
252
+ </Stack>
253
+ )
254
+ }
255
+ ```
256
+
257
+ ### 무제한 (unlimited)
258
+
259
+ 한도가 없을 땐 채움 대신 빗금 트랙을 보여 주고 "무제한"으로 읽어요.
260
+
261
+ ```tsx
262
+ import { Grid, Progress } from '@iamfiro/design'
263
+
264
+ export default function Example() {
265
+ return (
266
+ <Grid columns={3} gap={5} style={{ width: '100%', maxWidth: 480 }}>
267
+ <Progress size="sm" tone="warning" value={8} max={10} label="좌석" />
268
+ <Progress size="sm" tone="accent" value={3.2} max={5} label="저장 공간" />
269
+ <Progress size="sm" unlimited value={12} label="프로젝트 (무제한)" />
270
+ </Grid>
271
+ )
272
+ }
273
+ ```
@@ -0,0 +1,305 @@
1
+ # ProgressTracker
2
+
3
+ > 진행 표시 · `@iamfiro/design` · 직접 만들지 말고 이 컴포넌트를 쓴다.
4
+
5
+ 온보딩 체크리스트 카드. 전용 스타일 없이 기존 컴포넌트(Card · CardHeader · Progress · List · 원형 Checkbox)만 조립해 만들었어요. 단계를 누르면 동그라미가 파랗게 차오르고 글자에 취소선이 그어지며, 막대와 숫자도 함께 따라와요.
6
+
7
+ ```tsx
8
+ import { ProgressTracker, type TrackerGroup, type TrackerStep } from '@iamfiro/design'
9
+ ```
10
+
11
+ ## 디자인 규칙
12
+
13
+ - **조합 컴포넌트는 파운데이션 조립으로 먼저 만든다.** Card · Stack/Inline/Grid · Text · Progress · Checkbox 등 이미 있는 것만으로 짜고, 전용 CSS·음수 여백·내부 변수 참조(`--_pad` 등)를 쓰지 않는다. 그래야 정렬(왼쪽 끝)과 여백이 자동으로 맞는다. 정말 없는 표현만 기존 요소에 옵션으로 추가한다(예: Checkbox `shape="circle"`, Text `strike`). → `ProgressTracker`
14
+ - 읽기 전용 단계 타임라인(계획 · 활동 기록 · 승인 흐름)은 `StepList`(`ol`, 마커 + 연결선, `meta` 시간, 아래 내용엔 Collapsible inline). 번호 원은 `StatusIcon number`(`persistNumber`면 모든 상태에서 번호). 사용자가 체크하는 목록은 `ProgressTracker`. 카드 아래 상태 띠는 `CardFooter band`.
15
+ - 행 안의 진행률은 `ListItem progress`(행 뒤로 옅은 채움), 그룹으로 나눈 체크리스트는 `ProgressTracker groups`(Accordion `filled` + StatusIcon).
16
+
17
+ ## API
18
+
19
+ ### ProgressTracker
20
+
21
+ | prop | 타입 | 기본값 | 설명 |
22
+ | --- | --- | --- | --- |
23
+ | `title` (필수) | `ReactNode` | | 카드 제목. |
24
+ | `steps` | `TrackerStep[]` | | 단계 목록(한 줄로). groups를 쓰면 생략해요. |
25
+ | `groups` | `TrackerGroup[]` | | 단계를 접는 섹션으로 묶어요(시작 가이드). 열린 그룹은 회색 판, 행 앞은 StatusIcon, "n/전체"는 막대 옆으로 가요. |
26
+ | `groupMode` | `'single' \| 'multiple'` | `'single'` | single: 그룹 하나만 열림(다 끝내면 다음 그룹이 열려요) · multiple: 여러 개. |
27
+ | `openGroups / defaultOpenGroups` | `string[]` | | 열린 그룹 id(제어 / 비제어). 기본은 아직 끝나지 않은 첫 그룹. |
28
+ | `onOpenGroupsChange` | `(open: string[]) => void` | | 그룹을 열거나 접을 때. |
29
+ | `actions` | `ReactNode` | | 제목 오른쪽 버튼(편집 · 작게 보기 · 닫기). 숫자나 chevron 앞에 놓여요. |
30
+ | `completed` | `string[]` | | 완료된 단계 id(제어). |
31
+ | `defaultCompleted` | `string[]` | | 처음 완료 상태(비제어). |
32
+ | `onCompletedChange` | `(completed: string[]) => void` | | 완료 목록이 바뀔 때. |
33
+ | `readOnly` | `boolean` | | 행을 눌러도 바뀌지 않음. 완료는 앱이 결정. |
34
+ | `doneMessage` | `ReactNode` | `'모두 끝냈어요!'` | 모두 완료됐을 때 막대 아래 문구. |
35
+ | `collapsible` | `boolean` | | 단계를 chevron 뒤로 접어 제목 · 막대 · summary만 남겨요(사이드바 아래 작은 카드). 실제 높이만큼 펼쳐져요. |
36
+ | `open / defaultOpen` | `boolean` | `false` | collapsible일 때 펼침 상태(제어 / 비제어). |
37
+ | `onOpenChange` | `(open: boolean) => void` | | 펼치거나 접을 때. |
38
+ | `summary` | `ReactNode \| (done, total) => ReactNode` | | 막대 아래 작은 글씨. collapsible이면 기본 "13% 완료". |
39
+
40
+ ### TrackerStep
41
+
42
+ | prop | 타입 | 기본값 | 설명 |
43
+ | --- | --- | --- | --- |
44
+ | `id` (필수) | `string` | | 고유 id. |
45
+ | `label` (필수) | `ReactNode` | | 단계 이름. |
46
+ | `description` | `ReactNode` | | 보조 설명. |
47
+ | `action` | `ReactNode` | | 오른쪽 버튼. 완료되면 사라져요. |
48
+ | `disabled` | `boolean` | | 아직 할 수 없는 단계. |
49
+
50
+ ### TrackerGroup
51
+
52
+ | prop | 타입 | 기본값 | 설명 |
53
+ | --- | --- | --- | --- |
54
+ | `id` (필수) | `string` | | 고유 id. |
55
+ | `title` (필수) | `ReactNode` | | 그룹 제목. 모든 단계를 끝내면 취소선이 그어져요. |
56
+ | `steps` (필수) | `TrackerStep[]` | | 이 그룹의 단계. |
57
+
58
+ ## 예제
59
+
60
+ 예제를 감싼 `style={{ ... }}` div는 미리보기 배치용이다. 실제 화면 배치는 `Stack` · `Inline` · `Grid`로 한다.
61
+
62
+ ### 기본
63
+
64
+ 눌러서 단계를 완료하거나 되돌려요. defaultCompleted로 시작 상태를 정해요.
65
+
66
+ ```tsx
67
+ import { ProgressTracker, type TrackerStep } from '@iamfiro/design'
68
+
69
+ const STEPS: TrackerStep[] = [
70
+ { id: 'tools', label: '쓰는 도구 연결하기' },
71
+ { id: 'notify', label: '알림 켜기' },
72
+ { id: 'blockers', label: '막힌 일 확인하기' },
73
+ { id: 'priorities', label: '우선순위 정리하기' },
74
+ { id: 'project', label: '첫 프로젝트 만들기' },
75
+ ]
76
+
77
+ export default function Example() {
78
+ return <ProgressTracker title="시작하기" steps={STEPS} defaultCompleted={['notify', 'project']} style={{ width: 340 }} />
79
+ }
80
+ ```
81
+
82
+ ### 설명과 액션
83
+
84
+ 단계마다 설명과 오른쪽 버튼을 둘 수 있어요. 완료되면 버튼이 사라져요.
85
+
86
+ ```tsx
87
+ import { useState } from 'react'
88
+ import { Button, ProgressTracker } from '@iamfiro/design'
89
+
90
+ export default function Example() {
91
+ const [completed, setCompleted] = useState<string[]>(['profile'])
92
+ const finish = (id: string) => setCompleted((c) => (c.includes(id) ? c : [...c, id]))
93
+ return (
94
+ <ProgressTracker
95
+ title="워크스페이스 설정"
96
+ completed={completed}
97
+ onCompletedChange={setCompleted}
98
+ style={{ width: 380 }}
99
+ steps={[
100
+ { id: 'profile', label: '프로필 사진 올리기' },
101
+ {
102
+ id: 'slack',
103
+ label: 'Slack 연결',
104
+ description: '새 댓글과 멘션을 채널로 받아요.',
105
+ action: (
106
+ <Button size="sm" variant="secondary" onClick={() => finish('slack')}>
107
+ 연결
108
+ </Button>
109
+ ),
110
+ },
111
+ {
112
+ id: 'invite',
113
+ label: '팀원 초대',
114
+ description: '이메일로 초대하면 바로 참여할 수 있어요.',
115
+ action: (
116
+ <Button size="sm" variant="secondary" onClick={() => finish('invite')}>
117
+ 초대
118
+ </Button>
119
+ ),
120
+ },
121
+ { id: 'billing', label: '결제 수단 등록', description: '팀원을 초대한 뒤에 할 수 있어요.', disabled: !completed.includes('invite') },
122
+ ]}
123
+ />
124
+ )
125
+ }
126
+ ```
127
+
128
+ ### 앱에서 완료 처리 (readOnly)
129
+
130
+ 실제 작업이 끝났을 때 앱이 completed를 바꾸는 방식. 모두 끝나면 막대가 초록이 되고 doneMessage가 나와요.
131
+
132
+ ```tsx
133
+ import { useState } from 'react'
134
+ import { Button, Inline, Stack, ProgressTracker, type TrackerStep } from '@iamfiro/design'
135
+
136
+ const STEPS: TrackerStep[] = [
137
+ { id: 'upload', label: '파일 업로드' },
138
+ { id: 'scan', label: '보안 검사' },
139
+ { id: 'convert', label: '형식 변환' },
140
+ { id: 'publish', label: '게시' },
141
+ ]
142
+
143
+ export default function Example() {
144
+ const [done, setDone] = useState(1)
145
+ return (
146
+ <Stack gap={4} style={{ width: 340 }}>
147
+ <ProgressTracker
148
+ title="배포 진행 상황"
149
+ steps={STEPS}
150
+ completed={STEPS.slice(0, done).map((s) => s.id)}
151
+ readOnly
152
+ doneMessage="배포가 끝났어요. 이제 팀원에게 공유할 수 있어요."
153
+ />
154
+ <Inline gap={2}>
155
+ <Button variant="primary" disabled={done >= STEPS.length} onClick={() => setDone((d) => d + 1)}>
156
+ 다음 단계 완료
157
+ </Button>
158
+ <Button variant="ghost" onClick={() => setDone(0)}>
159
+ 처음부터
160
+ </Button>
161
+ </Inline>
162
+ </Stack>
163
+ )
164
+ }
165
+ ```
166
+
167
+ ### 접는 카드 (collapsible)
168
+
169
+ 사이드바 아래 같은 좁은 자리용. 평소엔 제목 · 얇은 막대 · summary("13% 완료 · 좋은 출발이에요!")만 보이고, chevron을 누르면 단계 목록이 펼쳐져요.
170
+
171
+ ```tsx
172
+ import { ProgressTracker, type TrackerStep } from '@iamfiro/design'
173
+
174
+ const STEPS: TrackerStep[] = [
175
+ { id: 'profile', label: '프로필 사진 올리기' },
176
+ { id: 'invite', label: '팀원 초대하기' },
177
+ { id: 'doc', label: '첫 문서 만들기' },
178
+ { id: 'folder', label: '폴더 정리하기' },
179
+ { id: 'share', label: '문서 공유하기' },
180
+ { id: 'notify', label: '알림 켜기' },
181
+ { id: 'app', label: '모바일 앱 받기' },
182
+ { id: 'theme', label: '테마 고르기' },
183
+ ]
184
+
185
+ const cheer = (done: number, total: number) => {
186
+ const pct = Math.round((done / total) * 100)
187
+ return `${pct}% 완료 · ${pct < 30 ? '좋은 출발이에요!' : pct < 80 ? '절반을 넘었어요' : '거의 다 왔어요'}`
188
+ }
189
+
190
+ export default function Example() {
191
+ return <ProgressTracker collapsible title="시작하기" steps={STEPS} defaultCompleted={['profile']} summary={cheer} style={{ width: 260 }} />
192
+ }
193
+ ```
194
+
195
+ ### 그룹으로 나눈 시작 가이드 (groups)
196
+
197
+ 단계를 접는 섹션으로 묶어요(Accordion variant="filled"). 열린 그룹은 옅은 회색 판 위에 놓이고, 행 앞은 StatusIcon(지금 할 단계 = 파란 링, 대기 = 점선 원, 완료 = 체크)이에요. 그룹을 다 끝내면 제목에 취소선이 그어지고 다음 그룹이 열려요. actions에 편집 · 작게 보기 · 닫기를 두고, "1/6"은 막대 옆으로 와요.
198
+
199
+ ```tsx
200
+ import { useState } from 'react'
201
+ import { Minimize2, X } from 'lucide-react'
202
+ import { Button, ProgressTracker, type TrackerGroup } from '@iamfiro/design'
203
+
204
+ const GROUPS: TrackerGroup[] = [
205
+ {
206
+ id: 'workspace',
207
+ title: '워크스페이스 준비',
208
+ steps: [
209
+ { id: 'name', label: '워크스페이스 이름 정하기' },
210
+ { id: 'invite', label: '팀원 초대하기' },
211
+ { id: 'calendar', label: '캘린더 연결하기' },
212
+ ],
213
+ },
214
+ {
215
+ id: 'billing',
216
+ title: '결제 설정',
217
+ steps: [
218
+ { id: 'card', label: '결제 수단 등록하기' },
219
+ { id: 'address', label: '청구서 받을 주소 입력하기' },
220
+ ],
221
+ },
222
+ { id: 'verify', title: '계정 인증', steps: [{ id: 'email', label: '이메일 인증하기' }] },
223
+ ]
224
+
225
+ export default function Example() {
226
+ const [hidden, setHidden] = useState(false)
227
+ if (hidden) {
228
+ return (
229
+ <Button variant="secondary" onClick={() => setHidden(false)}>
230
+ 시작 가이드 다시 보기
231
+ </Button>
232
+ )
233
+ }
234
+ return (
235
+ <ProgressTracker
236
+ title="시작 가이드"
237
+ groups={GROUPS}
238
+ defaultCompleted={['email']}
239
+ actions={
240
+ <>
241
+ <Button variant="ghost" size="sm">
242
+ 편집
243
+ </Button>
244
+ <Button variant="ghost" size="sm" iconOnly icon={<Minimize2 />} aria-label="작게 보기" />
245
+ <Button variant="ghost" size="sm" iconOnly icon={<X />} aria-label="닫기" onClick={() => setHidden(true)} />
246
+ </>
247
+ }
248
+ style={{ width: 340 }}
249
+ />
250
+ )
251
+ }
252
+ ```
253
+
254
+ ### 여러 그룹 함께 열기
255
+
256
+ groupMode="multiple"이면 여러 그룹을 함께 열어 둬요. openGroups / onOpenGroupsChange로 제어해 모두 펼치기 · 접기를 만들었어요.
257
+
258
+ ```tsx
259
+ import { useState } from 'react'
260
+ import { Button, Inline, Stack, ProgressTracker, type TrackerGroup } from '@iamfiro/design'
261
+
262
+ const GROUPS: TrackerGroup[] = [
263
+ {
264
+ id: 'account',
265
+ title: '계정',
266
+ steps: [
267
+ { id: 'photo', label: '프로필 사진 올리기' },
268
+ { id: 'alarm', label: '알림 켜기' },
269
+ ],
270
+ },
271
+ {
272
+ id: 'team',
273
+ title: '팀',
274
+ steps: [
275
+ { id: 'invite', label: '이도현 님 초대하기' },
276
+ { id: 'role', label: '역할 정하기' },
277
+ ],
278
+ },
279
+ {
280
+ id: 'first',
281
+ title: '첫 작업',
282
+ steps: [
283
+ { id: 'doc', label: '첫 문서 만들기' },
284
+ { id: 'share', label: '문서 공유하기' },
285
+ ],
286
+ },
287
+ ]
288
+
289
+ export default function Example() {
290
+ const [open, setOpen] = useState<string[]>(['account', 'team'])
291
+ return (
292
+ <Stack gap={3} style={{ width: 340 }}>
293
+ <Inline gap={2}>
294
+ <Button size="sm" onClick={() => setOpen(GROUPS.map((g) => g.id))}>
295
+ 모두 펼치기
296
+ </Button>
297
+ <Button size="sm" variant="ghost" onClick={() => setOpen([])}>
298
+ 모두 접기
299
+ </Button>
300
+ </Inline>
301
+ <ProgressTracker title="김민지 님의 할 일" groups={GROUPS} groupMode="multiple" openGroups={open} onOpenGroupsChange={setOpen} defaultCompleted={['photo']} />
302
+ </Stack>
303
+ )
304
+ }
305
+ ```