@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,277 @@
1
+ # Toolbar
2
+
3
+ > 버튼 & 링크 · `@iamfiro/design` · 직접 만들지 말고 이 컴포넌트를 쓴다.
4
+
5
+ 버튼 · 토글 · ToggleGroup · 메뉴 트리거를 한 줄로 묶는 WAI-ARIA 툴바. Tab 정지점은 툴바 전체에 하나뿐이고, 안에서는 ←→(세로면 ↑↓) · Home · End로 옮겨 다녀요. 다시 Tab으로 들어오면 마지막에 있던 버튼으로 돌아와요. 아이콘 버튼은 label이 이름 · 툴팁이 되고, 툴팁에 단축키 키캡이 함께 보여요. 테두리 없이 plain(여백만) · floating(흰 바탕 + 그림자) 두 가지.
6
+
7
+ ```tsx
8
+ import { Toolbar, ToolbarButton, ToolbarSeparator, ToolbarSpacer } from '@iamfiro/design'
9
+ ```
10
+
11
+ ## API
12
+
13
+ ### Toolbar
14
+
15
+ role="toolbar" + aria-orientation. 안의 button · input · [data-toolbar-item]이 모두 로빙 tabindex 대상이에요(비활성 · 숨김 제외).
16
+
17
+ | prop | 타입 | 기본값 | 설명 |
18
+ | --- | --- | --- | --- |
19
+ | `children` (필수) | `ReactNode` | | ToolbarButton, ToolbarSeparator, ToggleGroup, DropdownMenu 등. |
20
+ | `aria-label / aria-labelledby` | `string` | | 툴바 이름("서식"). |
21
+ | `orientation` | `'horizontal' \| 'vertical'` | `'horizontal'` | 배치와 화살표 키 방향. |
22
+ | `variant` | `'plain' \| 'floating'` | `'plain'` | plain: 여백만 · floating: 흰 바탕 + 그림자(테두리 없음). |
23
+ | `size` | `'sm' \| 'md'` | `'md'` | 안의 ToolbarButton 크기. ToggleGroup은 size를 직접 맞춰요. |
24
+ | `loop` | `boolean` | `true` | 끝에서 화살표를 누르면 처음으로. |
25
+ | `overflow` | `boolean` | | 자리가 모자라면 ToolbarButton · ToolbarSeparator를 뒤에서부터 "더보기" 메뉴로(가로만). 이때 툴바는 부모 폭을 채워요. |
26
+ | `overflowLabel` | `string` | `'더보기'` | 더보기 버튼 이름. |
27
+
28
+ ### ToolbarButton
29
+
30
+ ghost Button 기반. 나머지 Button 속성(icon, iconRight, onClick, hotkey, disabled…)을 그대로 받아요.
31
+
32
+ | prop | 타입 | 기본값 | 설명 |
33
+ | --- | --- | --- | --- |
34
+ | `label` (필수) | `string` | | 하는 일. 아이콘 버튼의 이름 · 툴팁 · 더보기 메뉴 글자. |
35
+ | `children` | `ReactNode` | | 글자 버튼일 때. 없으면 아이콘만 있는 정사각형 버튼. |
36
+ | `pressed / defaultPressed` | `boolean` | | 주면 토글 버튼(aria-pressed). 제어 / 비제어. |
37
+ | `onPressedChange` | `(pressed: boolean) => void` | | 토글이 바뀔 때. |
38
+ | `shortcut` | `string[]` | | 단축키 힌트(['mod', 'B']). 툴팁 · 더보기 메뉴에 키캡으로. hotkey를 함께 주면 실제로 들어요. |
39
+ | `tooltip` | `boolean \| ReactNode` | `아이콘 버튼이면 true` | 툴팁. false로 끄거나 내용을 바꿔요. |
40
+ | `tooltipSide` | `'top' \| 'bottom' \| 'left' \| 'right'` | | 기본은 가로 툴바 위, 세로 툴바 오른쪽. |
41
+ | `variant` | `ButtonVariant` | `'ghost'` | 끝의 주요 동작은 primary로. |
42
+ | `collapsible` | `boolean` | `true` | 더보기로 옮겨 갈 수 있는지. DropdownMenu 트리거처럼 클릭이 제 동작이 아닌 버튼은 false. |
43
+
44
+ ### ToolbarSeparator
45
+
46
+ 묶음 사이 짧은 선(가로 툴바면 세로선). role="separator".
47
+
48
+ ### ToolbarSpacer
49
+
50
+ 뒤의 항목을 반대쪽 끝으로 밀어요(flex: 1).
51
+
52
+ ## 예제
53
+
54
+ 예제를 감싼 `style={{ ... }}` div는 미리보기 배치용이다. 실제 화면 배치는 `Stack` · `Inline` · `Grid`로 한다.
55
+
56
+ ### 글 서식 툴바
57
+
58
+ 실행 취소 · 문단 스타일 메뉴 · 굵게/기울임/밑줄 토글(⌘/Ctrl+B · I · U로도 눌려요) · 정렬 ToggleGroup · 링크 · 더보기 메뉴. Tab으로 들어와 ←→로 이동하고, 메뉴 트리거에선 ↓ · Enter로 메뉴를 열어요. 정렬 묶음 안에서도 화살표는 툴바 전체를 따라 움직이고, Space · Enter로 골라요.
59
+
60
+ ```tsx
61
+ import { useState } from 'react'
62
+ import {
63
+ AlignCenter,
64
+ AlignLeft,
65
+ AlignRight,
66
+ Bold,
67
+ ChevronDown,
68
+ Code,
69
+ Eraser,
70
+ Italic,
71
+ Link,
72
+ MoreHorizontal,
73
+ Quote,
74
+ Redo2,
75
+ Strikethrough,
76
+ Table2,
77
+ Underline,
78
+ Undo2,
79
+ } from 'lucide-react'
80
+ import { DropdownMenu, DropdownMenuItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, ToggleGroup, ToggleGroupItem, Toolbar, ToolbarButton, ToolbarSeparator, Stack, Text } from '@iamfiro/design'
81
+
82
+ const BLOCKS = { body: '본문', h1: '제목 1', h2: '제목 2', h3: '제목 3' } as const
83
+ type Block = keyof typeof BLOCKS
84
+
85
+ export default function Example() {
86
+ const [block, setBlock] = useState<Block>('body')
87
+ const [marks, setMarks] = useState({ bold: true, italic: false, underline: false, strike: false })
88
+ const [align, setAlign] = useState<string | null>('left')
89
+ const [last, setLast] = useState('')
90
+ const mark = (key: keyof typeof marks) => ({
91
+ pressed: marks[key],
92
+ onPressedChange: (on: boolean) => setMarks((m) => ({ ...m, [key]: on })),
93
+ })
94
+
95
+ const on = Object.entries(marks)
96
+ .filter(([, v]) => v)
97
+ .map(([k]) => ({ bold: '굵게', italic: '기울임', underline: '밑줄', strike: '취소선' })[k])
98
+
99
+ return (
100
+ <Stack gap={4} align="start">
101
+ <Toolbar aria-label="서식" variant="floating">
102
+ <ToolbarButton label="실행 취소" icon={<Undo2 />} shortcut={['mod', 'Z']} onClick={() => setLast('실행 취소')} />
103
+ <ToolbarButton label="다시 실행" icon={<Redo2 />} shortcut={['mod', 'shift', 'Z']} onClick={() => setLast('다시 실행')} />
104
+ <ToolbarSeparator />
105
+ <DropdownMenu
106
+ minWidth={160}
107
+ trigger={
108
+ <ToolbarButton label="문단 스타일" iconRight={<ChevronDown />} tooltip collapsible={false}>
109
+ {BLOCKS[block]}
110
+ </ToolbarButton>
111
+ }
112
+ >
113
+ <DropdownMenuRadioGroup value={block} onValueChange={(v) => setBlock(v as Block)}>
114
+ {(Object.keys(BLOCKS) as Block[]).map((k) => (
115
+ <DropdownMenuRadioItem key={k} value={k}>
116
+ {BLOCKS[k]}
117
+ </DropdownMenuRadioItem>
118
+ ))}
119
+ </DropdownMenuRadioGroup>
120
+ </DropdownMenu>
121
+ <ToolbarSeparator />
122
+ <ToolbarButton label="굵게" icon={<Bold />} shortcut={['mod', 'B']} hotkey {...mark('bold')} />
123
+ <ToolbarButton label="기울임" icon={<Italic />} shortcut={['mod', 'I']} hotkey {...mark('italic')} />
124
+ <ToolbarButton label="밑줄" icon={<Underline />} shortcut={['mod', 'U']} hotkey {...mark('underline')} />
125
+ <ToolbarButton label="취소선" icon={<Strikethrough />} shortcut={['mod', 'shift', 'X']} {...mark('strike')} />
126
+ <ToolbarSeparator />
127
+ <ToggleGroup type="single" required variant="ghost" value={align} onValueChange={setAlign} aria-label="정렬">
128
+ <ToggleGroupItem value="left" icon={<AlignLeft />} aria-label="왼쪽 정렬" />
129
+ <ToggleGroupItem value="center" icon={<AlignCenter />} aria-label="가운데 정렬" />
130
+ <ToggleGroupItem value="right" icon={<AlignRight />} aria-label="오른쪽 정렬" />
131
+ </ToggleGroup>
132
+ <ToolbarSeparator />
133
+ <ToolbarButton label="링크" icon={<Link />} shortcut={['mod', 'K']} onClick={() => setLast('링크 넣기')} />
134
+ <DropdownMenu align="end" trigger={<ToolbarButton label="더보기" icon={<MoreHorizontal />} collapsible={false} />}>
135
+ <DropdownMenuItem icon={<Quote />} onSelect={() => setLast('인용')}>
136
+ 인용
137
+ </DropdownMenuItem>
138
+ <DropdownMenuItem icon={<Code />} shortcut={['mod', 'E']} onSelect={() => setLast('코드 블록')}>
139
+ 코드 블록
140
+ </DropdownMenuItem>
141
+ <DropdownMenuItem icon={<Table2 />} onSelect={() => setLast('표 넣기')}>
142
+ 표 넣기
143
+ </DropdownMenuItem>
144
+ <DropdownMenuSeparator />
145
+ <DropdownMenuItem icon={<Eraser />} onSelect={() => setMarks({ bold: false, italic: false, underline: false, strike: false })}>
146
+ 서식 지우기
147
+ </DropdownMenuItem>
148
+ </DropdownMenu>
149
+ </Toolbar>
150
+ <Text variant="body-sm" tone="secondary">
151
+ {BLOCKS[block]} · {on.length ? on.join(', ') : '서식 없음'} · {{ left: '왼쪽', center: '가운데', right: '오른쪽' }[align ?? 'left']} 정렬
152
+ {last && ` · 방금: ${last}`}
153
+ </Text>
154
+ </Stack>
155
+ )
156
+ }
157
+ ```
158
+
159
+ ### plain · 목록 위 도구
160
+
161
+ 글자 버튼은 툴팁 없이(tooltip={false}), ToolbarSpacer로 뒤쪽 버튼을 오른쪽 끝에 붙여요. 토글은 눌리면 회색 채움이 자라나요.
162
+
163
+ ```tsx
164
+ import { useState } from 'react'
165
+ import { ArrowDownUp, Download, LayoutGrid, List, ListFilter, Plus } from 'lucide-react'
166
+ import { ToggleGroup, ToggleGroupItem, Toolbar, ToolbarButton, ToolbarSeparator, ToolbarSpacer, Stack, Text } from '@iamfiro/design'
167
+
168
+ export default function Example() {
169
+ const [view, setView] = useState<string | null>('list')
170
+ const [filtered, setFiltered] = useState(false)
171
+ return (
172
+ <Stack gap={3}>
173
+ <Toolbar aria-label="문서 목록 도구" size="sm" style={{ width: '100%' }}>
174
+ <ToolbarButton label="필터" icon={<ListFilter />} pressed={filtered} onPressedChange={setFiltered} tooltip={false}>
175
+ 필터
176
+ </ToolbarButton>
177
+ <ToolbarButton label="정렬" icon={<ArrowDownUp />} tooltip={false}>
178
+ 최근 수정순
179
+ </ToolbarButton>
180
+ <ToolbarSeparator />
181
+ <ToggleGroup type="single" required size="sm" variant="ghost" value={view} onValueChange={setView} aria-label="보기">
182
+ <ToggleGroupItem value="list" icon={<List />} aria-label="목록으로 보기" />
183
+ <ToggleGroupItem value="grid" icon={<LayoutGrid />} aria-label="격자로 보기" />
184
+ </ToggleGroup>
185
+ <ToolbarSpacer />
186
+ <ToolbarButton label="내보내기" icon={<Download />} />
187
+ <ToolbarButton label="새 문서" variant="primary" icon={<Plus />} tooltip={false}>
188
+ 새 문서
189
+ </ToolbarButton>
190
+ </Toolbar>
191
+ <Text variant="body-sm" tone="secondary">
192
+ {filtered ? '필터 적용됨' : '전체 문서'} · {view === 'grid' ? '격자' : '목록'} 보기
193
+ </Text>
194
+ </Stack>
195
+ )
196
+ }
197
+ ```
198
+
199
+ ### 세로 · 그리기 도구
200
+
201
+ orientation='vertical'이면 ↑↓로 이동하고 툴팁은 오른쪽에 떠요. 구분선도 가로로 바뀌어요.
202
+
203
+ ```tsx
204
+ import { useState } from 'react'
205
+ import { Circle, Hand, MousePointer2, Pen, Square, Type, ZoomIn, ZoomOut } from 'lucide-react'
206
+ import { ToggleGroup, ToggleGroupItem, Toolbar, ToolbarButton, ToolbarSeparator, Inline, Text } from '@iamfiro/design'
207
+
208
+ const TOOLS = { select: '선택', hand: '손', rect: '사각형', ellipse: '원', pen: '펜', text: '텍스트' } as const
209
+
210
+ export default function Example() {
211
+ const [tool, setTool] = useState<string | null>('select')
212
+ const [zoom, setZoom] = useState(100)
213
+ return (
214
+ <Inline gap={6} align="start">
215
+ <Toolbar aria-label="그리기 도구" orientation="vertical" variant="floating">
216
+ <ToggleGroup type="single" required orientation="vertical" variant="ghost" value={tool} onValueChange={setTool} aria-label="도구">
217
+ <ToggleGroupItem value="select" icon={<MousePointer2 />} aria-label="선택 (V)" />
218
+ <ToggleGroupItem value="hand" icon={<Hand />} aria-label="손 (H)" />
219
+ <ToggleGroupItem value="rect" icon={<Square />} aria-label="사각형 (R)" />
220
+ <ToggleGroupItem value="ellipse" icon={<Circle />} aria-label="원 (O)" />
221
+ <ToggleGroupItem value="pen" icon={<Pen />} aria-label="펜 (P)" />
222
+ <ToggleGroupItem value="text" icon={<Type />} aria-label="텍스트 (T)" />
223
+ </ToggleGroup>
224
+ <ToolbarSeparator />
225
+ <ToolbarButton label="확대" icon={<ZoomIn />} shortcut={['mod', '=']} disabled={zoom >= 400} onClick={() => setZoom((z) => z * 2)} />
226
+ <ToolbarButton label="축소" icon={<ZoomOut />} shortcut={['mod', '-']} disabled={zoom <= 25} onClick={() => setZoom((z) => z / 2)} />
227
+ </Toolbar>
228
+ <Text variant="body-sm" tone="secondary" numeric>
229
+ 도구: {TOOLS[tool as keyof typeof TOOLS]} · 확대 {zoom}%
230
+ </Text>
231
+ </Inline>
232
+ )
233
+ }
234
+ ```
235
+
236
+ ### 자리가 모자라면 더보기로
237
+
238
+ overflow를 주면 들어가지 않는 버튼이 뒤에서부터 "더보기" 메뉴로 옮겨 가요. 토글은 메뉴에서 체크 항목이 되고, 단축키 힌트도 그대로 따라가요. 폭을 줄여 보세요.
239
+
240
+ ```tsx
241
+ import { useState } from 'react'
242
+ import { Bold, Code, Highlighter, Image, Italic, Link, List, ListOrdered, Quote, Strikethrough, Underline } from 'lucide-react'
243
+ import { Slider, Toolbar, ToolbarButton, ToolbarSeparator, Box, Field, Stack } from '@iamfiro/design'
244
+
245
+ export default function Example() {
246
+ const [width, setWidth] = useState(300)
247
+ const [marks, setMarks] = useState<Record<string, boolean>>({ bold: false, italic: true })
248
+ const toggle = (key: string) => ({
249
+ pressed: !!marks[key],
250
+ onPressedChange: (on: boolean) => setMarks((m) => ({ ...m, [key]: on })),
251
+ })
252
+ return (
253
+ <Stack gap={5}>
254
+ <Field label="툴바 폭">
255
+ <Slider value={width} onValueChange={setWidth} min={160} max={560} step={10} formatValue={(v) => `${v}px`} aria-label="툴바 폭" />
256
+ </Field>
257
+ <Box style={{ width }}>
258
+ <Toolbar aria-label="댓글 서식" variant="floating" overflow>
259
+ <ToolbarButton label="굵게" icon={<Bold />} shortcut={['mod', 'B']} {...toggle('bold')} />
260
+ <ToolbarButton label="기울임" icon={<Italic />} shortcut={['mod', 'I']} {...toggle('italic')} />
261
+ <ToolbarButton label="밑줄" icon={<Underline />} shortcut={['mod', 'U']} {...toggle('underline')} />
262
+ <ToolbarButton label="취소선" icon={<Strikethrough />} {...toggle('strike')} />
263
+ <ToolbarButton label="형광펜" icon={<Highlighter />} {...toggle('highlight')} />
264
+ <ToolbarSeparator />
265
+ <ToolbarButton label="글머리 목록" icon={<List />} />
266
+ <ToolbarButton label="번호 목록" icon={<ListOrdered />} />
267
+ <ToolbarButton label="인용" icon={<Quote />} />
268
+ <ToolbarSeparator />
269
+ <ToolbarButton label="링크" icon={<Link />} shortcut={['mod', 'K']} />
270
+ <ToolbarButton label="이미지" icon={<Image />} />
271
+ <ToolbarButton label="코드" icon={<Code />} shortcut={['mod', 'E']} />
272
+ </Toolbar>
273
+ </Box>
274
+ </Stack>
275
+ )
276
+ }
277
+ ```
@@ -0,0 +1,154 @@
1
+ # Tooltip
2
+
3
+ > 메뉴 & 오버레이 · `@iamfiro/design` · 직접 만들지 말고 이 컴포넌트를 쓴다.
4
+
5
+ 아이콘 버튼처럼 글자가 없는 요소에 짧은 설명을 붙여요. 마우스는 500ms 머물러야 열려서 툴바를 훑고 지나갈 때 깜빡이지 않고, 하나가 열린 뒤(또는 닫힌 지 300ms 안에) 옆으로 옮기면 기다림 없이 바로 열려요. 키보드 포커스는 즉시 열리고, 누르거나 Esc를 누르면 닫혀요.
6
+
7
+ ```tsx
8
+ import { Tooltip } from '@iamfiro/design'
9
+ ```
10
+
11
+ ## 디자인 규칙
12
+
13
+ - 툴팁: 첫 번째는 `TIMING.tooltipDelay`(500ms) 뒤, 닫힌 지 `TIMING.tooltipSkip`(300ms) 안에 옆 툴팁으로 옮기면 즉시. 단 "즉시"는 **이미 기다린 시간만큼만** 건너뛴다 — `delay={0}` 툴팁을 거쳐 왔다고 `delay={1000}` 툴팁이 바로 열리면 안 된다(대기 시간 고장 버그). 키보드 포커스는 즉시, 누르면 닫고, Esc로 닫힌다. → `Tooltip`
14
+ - 아바타는 hover하면 이름 `Tooltip`이 기본(`tooltip={false}`로 끔). `title` 속성 툴팁은 쓰지 않는다.
15
+
16
+ ## API
17
+
18
+ ### Tooltip
19
+
20
+ | prop | 타입 | 기본값 | 설명 |
21
+ | --- | --- | --- | --- |
22
+ | `content` (필수) | `ReactNode` | | 말풍선 내용. 짧은 글자나 작은 인라인 요소(Kbd 등). |
23
+ | `children` (필수) | `ReactNode` | | 툴팁을 붙일 트리거. 아이콘 버튼이면 aria-label도 함께 주세요. |
24
+ | `side` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'top'` | 말풍선이 열리는 방향. |
25
+ | `delay` | `number` | `500` | 마우스를 올린 뒤 첫 툴팁이 열리기까지(ms). 다른 툴팁이 열려 있거나 닫힌 지 300ms(TIMING.tooltipSkip) 안이면 그 툴팁에서 이미 기다린 시간만큼 빼고 기다려요(같은 delay끼리는 즉시). |
26
+
27
+ ## 예제
28
+
29
+ 예제를 감싼 `style={{ ... }}` div는 미리보기 배치용이다. 실제 화면 배치는 `Stack` · `Inline` · `Grid`로 한다.
30
+
31
+ ### 툴바
32
+
33
+ 첫 툴팁은 잠깐 기다렸다 열리고, 그다음부터는 옆 버튼으로 옮기는 즉시 바뀌어요. Tab으로 이동해도 바로 보여요.
34
+
35
+ ```tsx
36
+ import { Bold, Code, Italic, Link, List, Strikethrough, Underline } from 'lucide-react'
37
+ import { Button, Tooltip } from '@iamfiro/design'
38
+
39
+ const TOOLS = [
40
+ { label: '굵게', icon: <Bold /> },
41
+ { label: '기울임', icon: <Italic /> },
42
+ { label: '밑줄', icon: <Underline /> },
43
+ { label: '취소선', icon: <Strikethrough /> },
44
+ { label: '링크 삽입', icon: <Link /> },
45
+ { label: '목록', icon: <List /> },
46
+ { label: '코드', icon: <Code /> },
47
+ ]
48
+
49
+ export default function Example() {
50
+ return (
51
+ <div role="toolbar" aria-label="서식" style={{ display: 'flex', gap: 4 }}>
52
+ {TOOLS.map((tool) => (
53
+ <Tooltip key={tool.label} content={tool.label}>
54
+ <Button iconOnly variant="ghost" icon={tool.icon} aria-label={tool.label} />
55
+ </Tooltip>
56
+ ))}
57
+ </div>
58
+ )
59
+ }
60
+ ```
61
+
62
+ ### 방향
63
+
64
+ side로 위 · 아래 · 왼쪽 · 오른쪽. 열릴 때 트리거 쪽에서 살짝 밀려 나와요.
65
+
66
+ ```tsx
67
+ import { Button, Tooltip, type TooltipSide } from '@iamfiro/design'
68
+
69
+ const SIDES: Array<[TooltipSide, string]> = [
70
+ ['top', '위'],
71
+ ['bottom', '아래'],
72
+ ['left', '왼쪽'],
73
+ ['right', '오른쪽'],
74
+ ]
75
+
76
+ export default function Example() {
77
+ return (
78
+ <div style={{ display: 'flex', gap: 16 }}>
79
+ {SIDES.map(([side, label]) => (
80
+ <Tooltip key={side} side={side} content={`${label}에 열려요`}>
81
+ <Button variant="secondary">{label}</Button>
82
+ </Tooltip>
83
+ ))}
84
+ </div>
85
+ )
86
+ }
87
+ ```
88
+
89
+ ### 단축키 함께 보여주기
90
+
91
+ content에 Kbd를 넣으면 어두운 말풍선에 맞춰 키캡 색이 바뀌어요.
92
+
93
+ ```tsx
94
+ import { Bell, Plus, Search } from 'lucide-react'
95
+ import { Button, Kbd, Tooltip } from '@iamfiro/design'
96
+
97
+ export default function Example() {
98
+ return (
99
+ <div style={{ display: 'flex', gap: 8 }}>
100
+ <Tooltip
101
+ content={
102
+ <>
103
+ 검색 <Kbd keys={['mod', 'K']} size="sm" />
104
+ </>
105
+ }
106
+ >
107
+ <Button iconOnly variant="ghost" icon={<Search />} aria-label="검색" aria-keyshortcuts="Meta+K Control+K" />
108
+ </Tooltip>
109
+ <Tooltip
110
+ content={
111
+ <>
112
+ 새 문서 <Kbd keys={['C']} size="sm" />
113
+ </>
114
+ }
115
+ >
116
+ <Button iconOnly variant="ghost" icon={<Plus />} aria-label="새 문서" aria-keyshortcuts="C" />
117
+ </Tooltip>
118
+ <Tooltip
119
+ content={
120
+ <>
121
+ 알림 <Kbd keys={['G', 'N']} separator="다음" size="sm" />
122
+ </>
123
+ }
124
+ >
125
+ <Button iconOnly variant="ghost" icon={<Bell />} aria-label="알림" />
126
+ </Tooltip>
127
+ </div>
128
+ )
129
+ }
130
+ ```
131
+
132
+ ### 대기 시간
133
+
134
+ delay로 첫 툴팁의 대기 시간을 바꿔요. 기본값(TIMING.tooltipDelay, 500ms)을 쓰는 게 좋아요. 옆 툴팁이 막 열려 있었다면 이미 기다린 시간만큼은 건너뛰어요. 기본(500ms) 툴팁을 보다가 delay 1000으로 옮기면 남은 500ms만, delay 0을 보다 옮기면 1초를 다 기다려요.
135
+
136
+ ```tsx
137
+ import { Button, Tooltip } from '@iamfiro/design'
138
+
139
+ export default function Example() {
140
+ return (
141
+ <div style={{ display: 'flex', gap: 16 }}>
142
+ <Tooltip content="바로 열려요" delay={0}>
143
+ <Button variant="secondary">delay 0</Button>
144
+ </Tooltip>
145
+ <Tooltip content="0.5초 뒤에 열려요">
146
+ <Button variant="secondary">기본 (500ms)</Button>
147
+ </Tooltip>
148
+ <Tooltip content="1초 뒤에 열려요" delay={1000}>
149
+ <Button variant="secondary">delay 1000</Button>
150
+ </Tooltip>
151
+ </div>
152
+ )
153
+ }
154
+ ```
@@ -0,0 +1,158 @@
1
+ # Tracker
2
+
3
+ > 데이터 표시 · `@iamfiro/design` · 직접 만들지 말고 이 컴포넌트를 쓴다.
4
+
5
+ 하루(또는 한 시간)에 한 칸씩 상태를 색으로 늘어놓은 기록 띠. 가동률 · 배포 · 장애 이력을 한눈에 보여 줘요. 띠의 양 끝만 둥글고 안쪽 칸은 작은 모서리예요. 처음엔 칸이 왼쪽부터 차례로 올라오고, 마우스를 올리면 날짜와 상태가 차트 툴팁 카드에 떠요. 첫 툴팁은 잠깐 기다린 뒤 열리고, 그다음 칸으로 옮기면 바로 바뀌어요.
6
+
7
+ ```tsx
8
+ import { Tracker } from '@iamfiro/design'
9
+ ```
10
+
11
+ ## 디자인 규칙
12
+
13
+ - 상태 이력(가동률 · 배포 · 장애)은 `Tracker`: 같은 칸이 2–3px 간격으로, 띠의 양 끝만 둥글고 안쪽 칸은 2px. 정상 `--success` · 배포/기록 없음 회색 · 장애 빨강 · 저하 주황. 툴팁은 portal(fixed)로 띄워 Card `overflow: hidden`에 잘리지 않게, 첫 툴팁만 `TIMING.tooltipDelay`.
14
+
15
+ ## API
16
+
17
+ ### Tracker
18
+
19
+ | prop | 타입 | 기본값 | 설명 |
20
+ | --- | --- | --- | --- |
21
+ | `data` (필수) | `TrackerBlock[]` | | { key, tone?, color?, tooltip?, status?, value? } 목록. 오래된 칸부터. |
22
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 칸 높이 24 · 32 · 40px(fixed일 때 칸 폭 6 · 8 · 10px). |
23
+ | `height` | `number` | | 칸 높이(px). size보다 우선. |
24
+ | `layout` | `'fill' \| 'fixed'` | `'fill'` | fill: 폭에 맞춰 칸이 줄고 늘어요 · fixed: 칸 폭 고정. |
25
+ | `tooltip` | `boolean` | `true` | 날짜 · 상태 카드 표시. |
26
+ | `activeIndex / defaultActiveIndex / onActiveIndexChange` | `number \| null` | | 고른 칸(제어/비제어). |
27
+ | `aria-label` | `string` | `'상태 기록'` | 이름. 고른 칸은 aria-live로 읽어요. |
28
+
29
+ ### TrackerBlock
30
+
31
+ | prop | 타입 | 기본값 | 설명 |
32
+ | --- | --- | --- | --- |
33
+ | `key` (필수) | `string` | | 칸의 고유 키. |
34
+ | `tone` | `'success' \| 'warning' \| 'danger' \| 'neutral' \| 'accent' \| 'empty'` | `'success'` | 정상 · 성능 저하 · 장애 · 배포 · 점검 · 기록 없음. |
35
+ | `color` | `string` | | tone 대신 쓸 색. CSS 변수 이름('--chart-3') 또는 색. |
36
+ | `tooltip` | `ReactNode` | | 툴팁 제목(보통 날짜). |
37
+ | `status` | `ReactNode` | | 툴팁 행 이름. 기본은 tone 이름("정상", "장애"…). |
38
+ | `value` | `ReactNode` | | 툴팁 행 오른쪽 값("99.2%"). |
39
+
40
+ ## 예제
41
+
42
+ 예제를 감싼 `style={{ ... }}` div는 미리보기 배치용이다. 실제 화면 배치는 `Stack` · `Inline` · `Grid`로 한다.
43
+
44
+ ### 기본
45
+
46
+ 정상은 초록, 배포 · 기록 없음은 회색, 장애는 빨강 · 성능 저하는 주황이에요. 포커스한 뒤 ←/→, Home/End로 칸을 옮기고 Esc로 닫아요.
47
+
48
+ ```tsx
49
+ import { Tracker, type TrackerBlock, type TrackerTone } from '@iamfiro/design'
50
+
51
+ // 9월 26일 … 10월 25일, 하루에 한 칸. s 정상 · w 성능 저하 · d 장애 · n 배포 · e 기록 없음
52
+ const PATTERN = 'eessssssnssssswssssssdsssnssss'
53
+ const TONES: Record<string, TrackerTone> = { s: 'success', w: 'warning', d: 'danger', n: 'neutral', e: 'empty' }
54
+ const dayLabel = (i: number) => (i < 5 ? `9월 ${26 + i}일` : `10월 ${i - 4}일`)
55
+
56
+ const DAYS: TrackerBlock[] = PATTERN.split('').map((c, i) => ({ key: `d${i}`, tone: TONES[c], tooltip: dayLabel(i) }))
57
+
58
+ export default function Example() {
59
+ return (
60
+ <div style={{ width: '100%', maxWidth: 480 }}>
61
+ <Tracker data={DAYS} aria-label="최근 30일 상태" />
62
+ </div>
63
+ )
64
+ }
65
+ ```
66
+
67
+ ### 크기 · 높이 · 칸 폭
68
+
69
+ size(sm · md · lg)나 height로 높이를 정해요. 기본 layout="fill"은 칸이 폭에 맞춰 줄고 늘며, "fixed"는 칸 폭을 고정해요.
70
+
71
+ ```tsx
72
+ import { Stack, Text, Tracker, type TrackerBlock, type TrackerTone } from '@iamfiro/design'
73
+
74
+ const PATTERN = 'sssssssssssswsssssssssssssdssssssssssssssssnssssssssssss'
75
+ const TONES: Record<string, TrackerTone> = { s: 'success', w: 'warning', d: 'danger', n: 'neutral' }
76
+
77
+ // 지난 56시간, 한 시간에 한 칸.
78
+ const HOURS: TrackerBlock[] = PATTERN.split('').map((c, i) => ({ key: `h${i}`, tone: TONES[c], tooltip: `${56 - i}시간 전` }))
79
+
80
+ export default function Example() {
81
+ return (
82
+ <Stack gap={5} style={{ width: '100%', maxWidth: 520 }}>
83
+ <Stack gap={2}>
84
+ <Text variant="label-sm">sm · 24px</Text>
85
+ <Tracker data={HOURS} size="sm" aria-label="시간별 상태" />
86
+ </Stack>
87
+ <Stack gap={2}>
88
+ <Text variant="label-sm">lg · 40px</Text>
89
+ <Tracker data={HOURS} size="lg" aria-label="시간별 상태" />
90
+ </Stack>
91
+ <Stack gap={2}>
92
+ <Text variant="label-sm">height · 16px</Text>
93
+ <Tracker data={HOURS} height={16} size="sm" aria-label="시간별 상태" />
94
+ </Stack>
95
+ <Stack gap={2}>
96
+ <Text variant="label-sm">layout=&quot;fixed&quot; · 칸 폭 고정</Text>
97
+ <Tracker data={HOURS.slice(-24)} layout="fixed" aria-label="최근 24시간 상태" />
98
+ </Stack>
99
+ </Stack>
100
+ )
101
+ }
102
+ ```
103
+
104
+ ### 가동률 카드
105
+
106
+ CardHeader 아래에 라벨 줄("가동률 99.8%")과 양 끝 날짜("30일 전" … "오늘")를 붙여 조립해요. value는 툴팁 행 오른쪽에 나와요.
107
+
108
+ ```tsx
109
+ import { Badge, Inline, Stack, Text, Card, CardBody, CardHeader, Tracker, type TrackerBlock, type TrackerTone } from '@iamfiro/design'
110
+
111
+ // s 정상 · w 성능 저하 · d 장애 · n 배포
112
+ const PATTERN = 'sssssnsssssssssswsssssssnsdsss'
113
+ const TONES: Record<string, TrackerTone> = { s: 'success', w: 'warning', d: 'danger', n: 'neutral' }
114
+ const UPTIME: Record<string, string> = { s: '100%', w: '99.1%', d: '97.4%', n: '100%' }
115
+ const dayLabel = (i: number) => (i < 5 ? `9월 ${26 + i}일` : `10월 ${i - 4}일`)
116
+
117
+ const DAYS: TrackerBlock[] = PATTERN.split('').map((c, i) => ({
118
+ key: `d${i}`,
119
+ tone: TONES[c],
120
+ tooltip: dayLabel(i),
121
+ value: UPTIME[c],
122
+ }))
123
+
124
+ export default function Example() {
125
+ return (
126
+ <Card style={{ width: '100%', maxWidth: 480 }}>
127
+ <CardHeader
128
+ title="API 서버"
129
+ description="api.example.com"
130
+ actions={
131
+ <Badge tone="success" dot>
132
+ 정상 운영
133
+ </Badge>
134
+ }
135
+ />
136
+ <CardBody>
137
+ <Stack gap={2}>
138
+ <Inline justify="between" gap={3}>
139
+ <Text variant="label-sm">최근 30일</Text>
140
+ <Text variant="label-sm" tone="secondary" numeric>
141
+ 가동률 99.8%
142
+ </Text>
143
+ </Inline>
144
+ <Tracker data={DAYS} aria-label="API 서버 최근 30일 가동 기록" />
145
+ <Inline justify="between" gap={3}>
146
+ <Text variant="caption" tone="tertiary">
147
+ 30일 전
148
+ </Text>
149
+ <Text variant="caption" tone="tertiary">
150
+ 오늘
151
+ </Text>
152
+ </Inline>
153
+ </Stack>
154
+ </CardBody>
155
+ </Card>
156
+ )
157
+ }
158
+ ```