@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,224 @@
1
+ # ColorPicker
2
+
3
+ > 선택 컨트롤 · `@iamfiro/design` · 직접 만들지 말고 이 컴포넌트를 쓴다.
4
+
5
+ 색을 고르는 패널. 채도·밝기 영역과 색상 · 불투명도 슬라이더를 끌거나 화살표 키로 움직이고, HEX · RGB · HSL 값을 직접 입력해요. 프리셋, 최근 사용한 색, 화면 스포이트(지원 브라우저), 값 복사가 함께 있어요. 끄는 동안은 미리보기(onValueChange), 놓을 때 확정(onValueCommit)이고 끄는 중 Esc는 원래 색으로 돌아가요. 입력칸처럼 생긴 트리거가 필요하면 ColorField.
6
+
7
+ ```tsx
8
+ import { ColorField, ColorPicker, CHART_COLOR_PRESETS } from '@iamfiro/design'
9
+ ```
10
+
11
+ ## API
12
+
13
+ ### ColorPicker
14
+
15
+ | prop | 타입 | 기본값 | 설명 |
16
+ | --- | --- | --- | --- |
17
+ | `value` | `string` | | 값(제어). #rrggbb, alpha가 있고 반투명이면 #rrggbbaa(소문자). |
18
+ | `defaultValue` | `string` | `'#3b82f6'` | 처음 값(비제어). |
19
+ | `onValueChange` | `(value: string) => void` | | 끄는 동안·입력 중 매번 호출(미리보기). |
20
+ | `onValueCommit` | `(value: string) => void` | | 놓을 때, 키 한 번, Enter·칸 벗어남, 스와치·스포이트 선택 때 한 번 호출(확정). Esc로 취소하면 호출되지 않아요. |
21
+ | `alpha` | `boolean` | `false` | 불투명도 슬라이더와 A 칸. |
22
+ | `format / defaultFormat` | `'hex' \| 'rgb' \| 'hsl'` | `'hex'` | 입력칸과 복사에 쓰는 형식. onFormatChange로 받아요. |
23
+ | `presets` | `Array<string \| { color: string; label?: string }>` | | 프리셋 스와치. CSS 색이나 토큰 이름(--chart-1). CHART_COLOR_PRESETS가 준비돼 있어요. |
24
+ | `presetsLabel` | `ReactNode` | `'기본 색'` | 프리셋 줄 제목. |
25
+ | `recentColors / defaultRecentColors` | `string[]` | | 최근 사용한 색. 바꾼 뒤 포커스가 피커를 벗어나면 맨 앞에 추가돼요(onRecentColorsChange). |
26
+ | `maxRecent` | `number` | `8` | 최근 색 최대 개수. |
27
+ | `showRecent` | `boolean` | `true` | 최근 사용 줄을 보일지. |
28
+ | `eyeDropper` | `boolean` | `true` | EyeDropper API가 있는 브라우저에서만 스포이트 버튼을 보여요. |
29
+ | `copyable` | `boolean` | `true` | 현재 형식의 값을 복사하는 버튼. |
30
+ | `disabled` | `boolean` | | 비활성. |
31
+ | `aria-label` | `string` | `'색 선택'` | 피커 그룹 이름. |
32
+
33
+ ### ColorField
34
+
35
+ ColorPicker의 props를 모두 받고, 아래가 더해져요.
36
+
37
+ | prop | 타입 | 기본값 | 설명 |
38
+ | --- | --- | --- | --- |
39
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 입력칸 높이 36 / 44 / 52. |
40
+ | `open / defaultOpen` | `boolean` | | 팝오버 열림(onOpenChange). |
41
+ | `invalid` | `boolean` | | 오류 테두리. |
42
+ | `popoverWidth` | `number` | `264` | 팝오버 폭(px). |
43
+ | `name` | `string` | | 폼 제출용 hidden input 이름. |
44
+ | `aria-label` | `string` | `'색'` | 트리거 이름. 화면 읽기에는 "이름: 값"으로 읽혀요. |
45
+
46
+ ## 예제
47
+
48
+ 예제를 감싼 `style={{ ... }}` div는 미리보기 배치용이다. 실제 화면 배치는 `Stack` · `Inline` · `Grid`로 한다.
49
+
50
+ ### 기본
51
+
52
+ 영역은 가로 = 채도, 세로 = 밝기. 화살표 키로 1%씩, Shift를 누르면 10%씩 움직여요. presets에 토큰 이름(--chart-1)을 주면 현재 테마의 실제 색으로 풀어서 써요.
53
+
54
+ ```tsx
55
+ import { useState } from 'react'
56
+ import { Stack, Text, CHART_COLOR_PRESETS, Card, ColorPicker } from '@iamfiro/design'
57
+
58
+ export default function Example() {
59
+ const [color, setColor] = useState('#4a6cf7')
60
+ return (
61
+ <Stack gap={3} style={{ width: 264 }}>
62
+ <Card variant="raised" padding="sm">
63
+ <ColorPicker value={color} onValueChange={setColor} presets={CHART_COLOR_PRESETS} aria-label="차트 색" />
64
+ </Card>
65
+ <Text variant="body-sm" tone="secondary" numeric>
66
+ 선택한 색 {color}
67
+ </Text>
68
+ </Stack>
69
+ )
70
+ }
71
+ ```
72
+
73
+ ### 입력칸 트리거 (ColorField)
74
+
75
+ 색 칩 + 값이 보이는 입력칸 모양 트리거. 누르면 팝오버로 피커가 열리고 첫 포커스는 영역 손잡이에 가요. 바꾼 뒤 닫으면 그 색이 "최근 사용"에 쌓여요.
76
+
77
+ ```tsx
78
+ import { Field, Stack, CHART_COLOR_PRESETS, ColorField } from '@iamfiro/design'
79
+
80
+ export default function Example() {
81
+ return (
82
+ <Stack gap={4} style={{ width: 280 }}>
83
+ <Field label="라벨 색" htmlFor="label-color">
84
+ <ColorField id="label-color" defaultValue="#2bb39b" presets={CHART_COLOR_PRESETS} aria-label="라벨 색" />
85
+ </Field>
86
+ <Field label="워크스페이스 강조색" htmlFor="brand-color">
87
+ <ColorField
88
+ id="brand-color"
89
+ defaultValue="#e5488f"
90
+ defaultRecentColors={['#9b5cf6', '#f08a2a', '#1f1f1f']}
91
+ presets={CHART_COLOR_PRESETS}
92
+ aria-label="워크스페이스 강조색"
93
+ />
94
+ </Field>
95
+ </Stack>
96
+ )
97
+ }
98
+ ```
99
+
100
+ ### 불투명도
101
+
102
+ alpha를 켜면 체커보드 위 불투명도 슬라이더와 A 칸이 생기고, 값은 반투명일 때만 #rrggbbaa가 돼요.
103
+
104
+ ```tsx
105
+ import { useState } from 'react'
106
+ import { Stack, Text, Card, ColorPicker } from '@iamfiro/design'
107
+
108
+ export default function Example() {
109
+ const [overlay, setOverlay] = useState('#1f1f1f80')
110
+ return (
111
+ <Stack gap={3} style={{ width: 264 }}>
112
+ <Card variant="raised" padding="sm">
113
+ <ColorPicker
114
+ alpha
115
+ value={overlay}
116
+ onValueChange={setOverlay}
117
+ presets={[
118
+ { color: '#1f1f1f80', label: '어두운 오버레이' },
119
+ { color: '#ffffffcc', label: '밝은 오버레이' },
120
+ { color: '#3b82f633', label: '선택 영역' },
121
+ { color: '#d1393f26', label: '오류 배경' },
122
+ ]}
123
+ presetsLabel="오버레이 프리셋"
124
+ aria-label="오버레이 색"
125
+ />
126
+ </Card>
127
+ <Text variant="body-sm" tone="secondary" numeric>
128
+ 오버레이 {overlay}
129
+ </Text>
130
+ </Stack>
131
+ )
132
+ }
133
+ ```
134
+
135
+ ### HEX · RGB · HSL 입력
136
+
137
+ 형식을 바꾸면 칸이 나뉘어요. 맞는 값을 입력하는 즉시 미리보기되고, Enter나 칸을 벗어날 때 확정돼요. 틀린 값은 빨갛게 표시되고 벗어나면 마지막 올바른 값으로 돌아가요. 입력 중 Esc는 입력 전 색으로 되돌려요.
138
+
139
+ ```tsx
140
+ import { useState } from 'react'
141
+ import { Stack, Text, Card, ColorPicker, type ColorFormat } from '@iamfiro/design'
142
+
143
+ const NAMES: Record<ColorFormat, string> = { hex: 'HEX', rgb: 'RGB', hsl: 'HSL' }
144
+
145
+ export default function Example() {
146
+ const [format, setFormat] = useState<ColorFormat>('rgb')
147
+ return (
148
+ <Stack gap={3} style={{ width: 264 }}>
149
+ <Card variant="raised" padding="sm">
150
+ <ColorPicker defaultValue="#2bb39b" format={format} onFormatChange={setFormat} showRecent={false} aria-label="테마 색" />
151
+ </Card>
152
+ <Text variant="body-sm" tone="secondary">
153
+ {NAMES[format]} 형식으로 입력하고 복사해요. 칸에 300처럼 범위를 벗어난 값을 넣어 보세요.
154
+ </Text>
155
+ </Stack>
156
+ )
157
+ }
158
+ ```
159
+
160
+ ### 미리보기와 확정
161
+
162
+ 저장·서버 요청은 onValueCommit에서. 끄는 중에 Esc를 누르면 미리보기가 취소되고 아무것도 확정되지 않아요.
163
+
164
+ ```tsx
165
+ import { useState } from 'react'
166
+ import { Inline, Stack, Text, Card, ColorPicker, toast } from '@iamfiro/design'
167
+
168
+ export default function Example() {
169
+ const [preview, setPreview] = useState('#9b5cf6')
170
+ const [saved, setSaved] = useState('#9b5cf6')
171
+ return (
172
+ <Stack gap={3} style={{ width: 264 }}>
173
+ <Card variant="raised" padding="sm">
174
+ <ColorPicker
175
+ value={preview}
176
+ onValueChange={setPreview}
177
+ onValueCommit={(c) => {
178
+ setSaved(c)
179
+ toast.success('프로젝트 색을 저장했어요', { description: c })
180
+ }}
181
+ copyable={false}
182
+ showRecent={false}
183
+ aria-label="프로젝트 색"
184
+ />
185
+ </Card>
186
+ <Inline justify="between">
187
+ <Text variant="body-sm" tone="secondary" numeric>
188
+ 미리보기 {preview}
189
+ </Text>
190
+ <Text variant="body-sm" weight="semibold" numeric>
191
+ 저장됨 {saved}
192
+ </Text>
193
+ </Inline>
194
+ </Stack>
195
+ )
196
+ }
197
+ ```
198
+
199
+ ### 크기와 상태
200
+
201
+ ColorField size sm / md / lg, invalid, disabled.
202
+
203
+ ```tsx
204
+ import { Field, Stack, ColorField } from '@iamfiro/design'
205
+
206
+ export default function Example() {
207
+ return (
208
+ <Stack gap={4} style={{ width: 280 }}>
209
+ <Field label="작게 (sm)">
210
+ <ColorField size="sm" defaultValue="#f08a2a" aria-label="경고 색" />
211
+ </Field>
212
+ <Field label="크게 (lg) · RGB 표시">
213
+ <ColorField size="lg" defaultValue="#4a6cf7" defaultFormat="rgb" aria-label="링크 색" />
214
+ </Field>
215
+ <Field label="오류" hint="배경과 대비가 너무 낮아요" invalid>
216
+ <ColorField invalid defaultValue="#f5f5f5" aria-label="글자 색" />
217
+ </Field>
218
+ <Field label="비활성">
219
+ <ColorField disabled defaultValue="#9a9a9a" aria-label="비활성 색" />
220
+ </Field>
221
+ </Stack>
222
+ )
223
+ }
224
+ ```
@@ -0,0 +1,168 @@
1
+ # Colors
2
+
3
+ > 파운데이션 · `@iamfiro/design` · 직접 만들지 말고 이 컴포넌트를 쓴다.
4
+
5
+ 모든 색은 tokens.css의 CSS 변수로만 써요. 배경은 흰색, 회색은 칩·트랙 같은 작은 채움에만, 강조색은 파랑 하나예요. 기본 액션은 거의 검정이고, 상태는 진한 색 대신 -soft 배경 + 색 글자로 보여줘요. 다크 테마는 [data-theme="dark"]에서 같은 이름에 다른 값을 넣어요.
6
+
7
+ ```tsx
8
+ import { Swatch } from '@iamfiro/design'
9
+ ```
10
+
11
+ ## API
12
+
13
+ ### Swatch
14
+
15
+ 토큰 문서용 색 칩. 토큰 이름과 실제 계산된 값을 함께 보여줘요.
16
+
17
+ | prop | 타입 | 기본값 | 설명 |
18
+ | --- | --- | --- | --- |
19
+ | `color` (필수) | `string` | | CSS 변수 이름('--accent') 또는 아무 CSS 색. |
20
+ | `name` | `string` | | 표시할 이름. 생략하면 color 값. |
21
+ | `showValue` | `boolean` | `true` | 이름 아래에 계산된 값(hex 등)을 표시. |
22
+
23
+ ## 예제
24
+
25
+ 예제를 감싼 `style={{ ... }}` div는 미리보기 배치용이다. 실제 화면 배치는 `Stack` · `Inline` · `Grid`로 한다.
26
+
27
+ ### 뉴트럴 램프
28
+
29
+ --n0(가장 밝음)부터 --n12(가장 진한 글자)까지. 컴포넌트에서는 직접 쓰기보다 아래의 의미 토큰을 거쳐 써요.
30
+
31
+ ```tsx
32
+ import { Swatch } from '@iamfiro/design'
33
+
34
+ const NEUTRALS = Array.from({ length: 13 }, (_, i) => `--n${i}`)
35
+
36
+ export default function Example() {
37
+ return (
38
+ <div style={{ width: '100%', display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(88px, 1fr))', gap: 16 }}>
39
+ {NEUTRALS.map((token) => (
40
+ <Swatch key={token} color={token} />
41
+ ))}
42
+ </div>
43
+ )
44
+ }
45
+ ```
46
+
47
+ ### 표면 · 글자 · 선
48
+
49
+ 역할로 이름 붙인 토큰. 회색 채움은 --surface-active(기본)와 --surface-hover(마우스 오버)만 써요.
50
+
51
+ ```tsx
52
+ import { Swatch, Text } from '@iamfiro/design'
53
+
54
+ const GROUPS = [
55
+ { title: '표면', tokens: ['--bg', '--surface', '--surface-raised', '--surface-sunken', '--surface-hover', '--surface-active', '--overlay'] },
56
+ { title: '글자', tokens: ['--text', '--text-2', '--text-3', '--text-inverse'] },
57
+ { title: '선', tokens: ['--line', '--line-strong', '--line-focus'] },
58
+ ]
59
+
60
+ export default function Example() {
61
+ return (
62
+ <div style={{ width: '100%', display: 'grid', gap: 32 }}>
63
+ {GROUPS.map((group) => (
64
+ <section key={group.title} style={{ display: 'grid', gap: 12 }}>
65
+ <Text as="h4" variant="overline" tone="tertiary">
66
+ {group.title}
67
+ </Text>
68
+ <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(120px, 1fr))', gap: 16 }}>
69
+ {group.tokens.map((token) => (
70
+ <Swatch key={token} color={token} />
71
+ ))}
72
+ </div>
73
+ </section>
74
+ ))}
75
+ </div>
76
+ )
77
+ }
78
+ ```
79
+
80
+ ### 브랜드 · 상태
81
+
82
+ 강조색과 상태색. 배경은 -soft, 글자는 진한 색으로 짝지어 써요. Badge 톤이 이 짝을 그대로 사용해요.
83
+
84
+ ```tsx
85
+ import { Badge, Swatch, Text, type Tone } from '@iamfiro/design'
86
+
87
+ const FAMILIES: Array<{ tone: Tone; label: string; tokens: string[] }> = [
88
+ { tone: 'accent', label: '강조', tokens: ['--accent', '--accent-strong', '--accent-soft', '--accent-text'] },
89
+ { tone: 'success', label: '성공', tokens: ['--success', '--success-soft'] },
90
+ { tone: 'warning', label: '경고', tokens: ['--warning', '--warning-soft'] },
91
+ { tone: 'danger', label: '위험', tokens: ['--danger', '--danger-soft'] },
92
+ { tone: 'info', label: '정보', tokens: ['--info', '--info-soft'] },
93
+ ]
94
+
95
+ export default function Example() {
96
+ return (
97
+ <div style={{ width: '100%', display: 'grid', gap: 28 }}>
98
+ {FAMILIES.map((family) => (
99
+ <section key={family.tone} style={{ display: 'grid', gridTemplateColumns: '96px 1fr', alignItems: 'start', gap: 16 }}>
100
+ <div style={{ display: 'grid', gap: 8, justifyItems: 'start' }}>
101
+ <Text variant="label-md">{family.label}</Text>
102
+ <Badge tone={family.tone} dot>
103
+ {family.tone}
104
+ </Badge>
105
+ </div>
106
+ <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(120px, 1fr))', gap: 16 }}>
107
+ {family.tokens.map((token) => (
108
+ <Swatch key={token} color={token} />
109
+ ))}
110
+ </div>
111
+ </section>
112
+ ))}
113
+ </div>
114
+ )
115
+ }
116
+ ```
117
+
118
+ ### 차트
119
+
120
+ --chart-1부터 순서대로 시리즈에 배정해요. 그리드 선은 --chart-grid로 아주 옅게, 축 글자는 --chart-axis로 써요. 한 수량을 나눈 조각(나눠진 Progress)은 진한 파랑부터 옅어지는 --chart-seq-1…5를 써요.
121
+
122
+ ```tsx
123
+ import { Swatch } from '@iamfiro/design'
124
+
125
+ const TOKENS = ['--chart-1', '--chart-2', '--chart-3', '--chart-4', '--chart-5', '--chart-6', '--chart-grid', '--chart-axis', '--chart-seq-1', '--chart-seq-2', '--chart-seq-3', '--chart-seq-4', '--chart-seq-5']
126
+
127
+ export default function Example() {
128
+ return (
129
+ <div style={{ width: '100%', display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(120px, 1fr))', gap: 16 }}>
130
+ {TOKENS.map((token) => (
131
+ <Swatch key={token} color={token} />
132
+ ))}
133
+ </div>
134
+ )
135
+ }
136
+ ```
137
+
138
+ ### 액션
139
+
140
+ primary는 거의 검정 단색, secondary는 흰 바탕 + 옅은 윤곽. 버튼이 이 토큰만 읽어요.
141
+
142
+ ```tsx
143
+ import { Button, Swatch, type ButtonVariant } from '@iamfiro/design'
144
+
145
+ const ACTIONS: Array<{ variant: ButtonVariant; label: string; tokens: string[] }> = [
146
+ { variant: 'primary', label: '변경사항 저장', tokens: ['--primary', '--primary-hover', '--primary-text'] },
147
+ { variant: 'secondary', label: '취소', tokens: ['--secondary', '--secondary-hover', '--secondary-border'] },
148
+ ]
149
+
150
+ export default function Example() {
151
+ return (
152
+ <div style={{ width: '100%', display: 'grid', gap: 28 }}>
153
+ {ACTIONS.map((action) => (
154
+ <section key={action.variant} style={{ display: 'grid', gridTemplateColumns: '120px 1fr', alignItems: 'center', gap: 16 }}>
155
+ <div>
156
+ <Button variant={action.variant}>{action.label}</Button>
157
+ </div>
158
+ <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(120px, 1fr))', gap: 16 }}>
159
+ {action.tokens.map((token) => (
160
+ <Swatch key={token} color={token} />
161
+ ))}
162
+ </div>
163
+ </section>
164
+ ))}
165
+ </div>
166
+ )
167
+ }
168
+ ```
@@ -0,0 +1,218 @@
1
+ # Combobox
2
+
3
+ > 선택 컨트롤 · `@iamfiro/design` · 직접 만들지 말고 이 컴포넌트를 쓴다.
4
+
5
+ 입력하면서 검색해 고르는 셀렉트. 이름과 keywords를 띄어쓰기·대소문자 상관없이 찾고, 일치한 부분은 굵게 보여줘요. multiple이면 고른 항목이 태그로 쌓이고, onCreate로 없는 항목을 바로 추가할 수 있어요. 선택지 형태(ListOption)는 Select 페이지를 참고하세요.
6
+
7
+ ```tsx
8
+ import { Combobox, type ListOption } from '@iamfiro/design'
9
+ ```
10
+
11
+ ## API
12
+
13
+ ### Combobox
14
+
15
+ | prop | 타입 | 기본값 | 설명 |
16
+ | --- | --- | --- | --- |
17
+ | `options` (필수) | `ListOption<V>[]` | | 선택지 목록. ListOption은 Select 페이지 참고. |
18
+ | `multiple` | `boolean` | `false` | 여러 개 선택. value 타입이 V[]로 바뀌어요. |
19
+ | `value` | `V \| null · V[] (multiple)` | | 선택된 값(제어). |
20
+ | `defaultValue` | `V \| null · V[] (multiple)` | | 처음 선택값(비제어). |
21
+ | `onValueChange` | `(value: V \| null) => void · (value: V[]) => void` | | 값이 바뀔 때. |
22
+ | `inputValue / onInputChange` | `string / (text) => void` | | 검색어를 밖에서 제어할 때(서버 검색 등). |
23
+ | `filter` | `(option, query) => boolean` | `defaultComboboxFilter` | 일치 규칙. 기본은 label + keywords, 대소문자·띄어쓰기 무시. |
24
+ | `onCreate` | `(query: string) => void` | | 있으면 일치하는 항목이 없을 때 추가 행을 보여줘요. |
25
+ | `createLabel` | `(query: string) => ReactNode` | `‘query’ 추가` | 추가 행 문구. |
26
+ | `emptyText` | `ReactNode` | `'결과가 없어요'` | 검색 결과가 없을 때 문구. |
27
+ | `highlight` | `boolean` | `true` | 일치한 부분을 굵게. |
28
+ | `renderOption` | `(option, state & { query }) => ReactNode` | | 목록 행을 직접 그릴 때. 검색어도 함께 받아요. |
29
+ | `placeholder` | `string` | `'검색해서 선택'` | 입력 전 문구. |
30
+ | `size` | `'sm' \| 'md' \| 'lg'` | `'md'` | 높이 36 / 44 / 52px. |
31
+ | `invalid` | `boolean` | | 오류 표시. |
32
+ | `disabled` | `boolean` | | 비활성. |
33
+ | `leading` | `ReactNode` | | 입력창 앞 아이콘. |
34
+ | `maxHeight` | `number` | `300` | 팝오버 최대 높이. |
35
+
36
+ ## 예제
37
+
38
+ 예제를 감싼 `style={{ ... }}` div는 미리보기 배치용이다. 실제 화면 배치는 `Stack` · `Inline` · `Grid`로 한다.
39
+
40
+ ### 기본
41
+
42
+ keywords에 넣은 단어(영문 이름 등)로도 검색돼요. ↑↓로 이동, Enter로 선택, Esc로 닫기. 한글 조합 중에는 키 입력을 기다려요.
43
+
44
+ ```tsx
45
+ import { useState } from 'react'
46
+ import { Avatar, Field, Combobox, type ListOption } from '@iamfiro/design'
47
+
48
+ const PEOPLE: ListOption[] = [
49
+ { value: 'minji', label: '김민지', description: '디자인', keywords: ['minji kim'] },
50
+ { value: 'dohyun', label: '이도현', description: '프론트엔드', keywords: ['dohyun lee'] },
51
+ { value: 'seoyeon', label: '최서연', description: '백엔드', keywords: ['seoyeon choi'] },
52
+ { value: 'woojin', label: '정우진', description: '프로덕트', keywords: ['woojin jung'] },
53
+ { value: 'jisu', label: '한지수', description: '데이터', keywords: ['jisu han'] },
54
+ { value: 'yuna', label: '박유나', description: '디자인', keywords: ['yuna park'] },
55
+ ].map((person) => ({ ...person, icon: <Avatar name={person.label} size={22} /> }))
56
+
57
+ export default function Example() {
58
+ const [owner, setOwner] = useState<string | null>('minji')
59
+ return (
60
+ <div style={{ width: 320 }}>
61
+ <Field label="담당자" htmlFor="owner">
62
+ <Combobox id="owner" options={PEOPLE} value={owner} onValueChange={setOwner} placeholder="이름 또는 영문으로 검색" />
63
+ </Field>
64
+ </div>
65
+ )
66
+ }
67
+ ```
68
+
69
+ ### 여러 개 선택
70
+
71
+ multiple이면 목록이 열린 채로 유지되고, 검색어가 비어 있을 때 Backspace는 마지막 태그를 지워요.
72
+
73
+ ```tsx
74
+ import { useState } from 'react'
75
+ import { Field, Combobox, type ListOption } from '@iamfiro/design'
76
+
77
+ const SKILLS: ListOption[] = [
78
+ { value: 'react', label: 'React', keywords: ['리액트'] },
79
+ { value: 'typescript', label: 'TypeScript', keywords: ['타입스크립트', 'ts'] },
80
+ { value: 'node', label: 'Node.js', keywords: ['노드'] },
81
+ { value: 'figma', label: 'Figma', keywords: ['피그마'] },
82
+ { value: 'python', label: 'Python', keywords: ['파이썬'] },
83
+ { value: 'sql', label: 'SQL', keywords: ['데이터베이스'] },
84
+ ]
85
+
86
+ export default function Example() {
87
+ const [skills, setSkills] = useState<string[]>(['react', 'typescript'])
88
+ return (
89
+ <div style={{ width: 360 }}>
90
+ <Field label="보유 기술" htmlFor="skills">
91
+ <Combobox id="skills" multiple options={SKILLS} value={skills} onValueChange={setSkills} placeholder="기술 검색" />
92
+ </Field>
93
+ </div>
94
+ )
95
+ }
96
+ ```
97
+
98
+ ### 새 항목 추가
99
+
100
+ 정확히 일치하는 항목이 없으면 맨 아래에 추가 행이 생겨요. onCreate에서 options에 넣고 선택까지 직접 해주세요. 문구는 createLabel로 바꿔요.
101
+
102
+ ```tsx
103
+ import { useState } from 'react'
104
+ import { Field, Combobox, type ListOption } from '@iamfiro/design'
105
+
106
+ export default function Example() {
107
+ const [labels, setLabels] = useState<ListOption[]>([
108
+ { value: 'bug', label: '버그' },
109
+ { value: 'feature', label: '기능 요청' },
110
+ { value: 'design', label: '디자인' },
111
+ { value: 'infra', label: '인프라' },
112
+ { value: 'docs', label: '문서' },
113
+ ])
114
+ const [picked, setPicked] = useState<string[]>(['bug'])
115
+
116
+ const createLabel = (label: string) => {
117
+ const value = `label-${Date.now()}`
118
+ setLabels((list) => [...list, { value, label }])
119
+ setPicked((list) => [...list, value])
120
+ }
121
+
122
+ return (
123
+ <div style={{ width: 360 }}>
124
+ <Field label="라벨" htmlFor="issue-labels">
125
+ <Combobox
126
+ id="issue-labels"
127
+ multiple
128
+ options={labels}
129
+ value={picked}
130
+ onValueChange={setPicked}
131
+ onCreate={createLabel}
132
+ createLabel={(query) => `새 라벨 ‘${query}’ 만들기`}
133
+ placeholder="라벨 검색 또는 추가"
134
+ />
135
+ </Field>
136
+ </div>
137
+ )
138
+ }
139
+ ```
140
+
141
+ ### 검색 방식 바꾸기
142
+
143
+ filter로 일치 규칙을 직접 정해요. 기본 규칙(defaultComboboxFilter)과 함께 쓰면 기존 검색도 그대로 유지돼요.
144
+
145
+ ```tsx
146
+ import { Field, Combobox, defaultComboboxFilter, type ListOption } from '@iamfiro/design'
147
+
148
+ const CITIES: ListOption[] = [
149
+ { value: 'seoul', label: '서울' },
150
+ { value: 'busan', label: '부산' },
151
+ { value: 'incheon', label: '인천' },
152
+ { value: 'daegu', label: '대구' },
153
+ { value: 'daejeon', label: '대전' },
154
+ { value: 'gwangju', label: '광주' },
155
+ { value: 'ulsan', label: '울산' },
156
+ { value: 'jeju', label: '제주' },
157
+ ]
158
+
159
+ const CHOSEONG = 'ㄱㄲㄴㄷㄸㄹㅁㅂㅃㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎ'
160
+
161
+ // '서울' → 'ㅅㅇ'
162
+ const toChoseong = (text: string) =>
163
+ [...text]
164
+ .map((ch) => {
165
+ const code = ch.charCodeAt(0) - 0xac00
166
+ return code >= 0 && code < 11172 ? CHOSEONG[Math.floor(code / 588)] : ch
167
+ })
168
+ .join('')
169
+
170
+ // 초성이 맞으면 통과('ㄷㄱ' → 대구), 아니면 기본 검색(이름 · keywords)으로
171
+ const matchChoseong = (option: ListOption, query: string) =>
172
+ toChoseong(option.label).includes(query) || defaultComboboxFilter(option, query)
173
+
174
+ export default function Example() {
175
+ return (
176
+ <div style={{ width: 300 }}>
177
+ <Field label="도시" hint="초성으로도 찾을 수 있어요. 예: ㄷㄱ" htmlFor="city">
178
+ <Combobox id="city" options={CITIES} filter={matchChoseong} emptyText="일치하는 도시가 없어요" placeholder="도시 검색" />
179
+ </Field>
180
+ </div>
181
+ )
182
+ }
183
+ ```
184
+
185
+ ### 크기와 상태
186
+
187
+ size, leading 아이콘, highlight 끄기, invalid, disabled.
188
+
189
+ ```tsx
190
+ import { Search } from 'lucide-react'
191
+ import { Field, Combobox, type ListOption } from '@iamfiro/design'
192
+
193
+ const TEAMS: ListOption[] = [
194
+ { value: 'design', label: '디자인팀' },
195
+ { value: 'frontend', label: '프론트엔드팀' },
196
+ { value: 'backend', label: '백엔드팀' },
197
+ { value: 'data', label: '데이터팀' },
198
+ ]
199
+
200
+ export default function Example() {
201
+ return (
202
+ <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 240px)', gap: 16 }}>
203
+ <Field label="작게 (sm) · 아이콘" htmlFor="team-sm">
204
+ <Combobox id="team-sm" size="sm" options={TEAMS} leading={<Search />} placeholder="팀 검색" />
205
+ </Field>
206
+ <Field label="강조 끄기 (highlight)" htmlFor="team-plain">
207
+ <Combobox id="team-plain" options={TEAMS} highlight={false} placeholder="팀 검색" />
208
+ </Field>
209
+ <Field label="오류" invalid hint="팀을 선택해 주세요." htmlFor="team-err">
210
+ <Combobox id="team-err" options={TEAMS} invalid placeholder="팀 검색" />
211
+ </Field>
212
+ <Field label="비활성" htmlFor="team-off">
213
+ <Combobox id="team-off" options={TEAMS} defaultValue="design" disabled />
214
+ </Field>
215
+ </div>
216
+ )
217
+ }
218
+ ```