@neynar/ui 0.1.1

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 (364) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -0
  3. package/dist/components/ui/accordion.d.ts +229 -0
  4. package/dist/components/ui/accordion.d.ts.map +1 -0
  5. package/dist/components/ui/alert-dialog.d.ts +247 -0
  6. package/dist/components/ui/alert-dialog.d.ts.map +1 -0
  7. package/dist/components/ui/alert.d.ts +187 -0
  8. package/dist/components/ui/alert.d.ts.map +1 -0
  9. package/dist/components/ui/aspect-ratio.d.ts +94 -0
  10. package/dist/components/ui/aspect-ratio.d.ts.map +1 -0
  11. package/dist/components/ui/avatar.d.ts +244 -0
  12. package/dist/components/ui/avatar.d.ts.map +1 -0
  13. package/dist/components/ui/badge.d.ts +163 -0
  14. package/dist/components/ui/badge.d.ts.map +1 -0
  15. package/dist/components/ui/breadcrumb.d.ts +281 -0
  16. package/dist/components/ui/breadcrumb.d.ts.map +1 -0
  17. package/dist/components/ui/button.d.ts +129 -0
  18. package/dist/components/ui/button.d.ts.map +1 -0
  19. package/dist/components/ui/calendar.d.ts +169 -0
  20. package/dist/components/ui/calendar.d.ts.map +1 -0
  21. package/dist/components/ui/card.d.ts +365 -0
  22. package/dist/components/ui/card.d.ts.map +1 -0
  23. package/dist/components/ui/carousel.d.ts +369 -0
  24. package/dist/components/ui/carousel.d.ts.map +1 -0
  25. package/dist/components/ui/chart.d.ts +442 -0
  26. package/dist/components/ui/chart.d.ts.map +1 -0
  27. package/dist/components/ui/checkbox.d.ts +88 -0
  28. package/dist/components/ui/checkbox.d.ts.map +1 -0
  29. package/dist/components/ui/collapsible.d.ts +182 -0
  30. package/dist/components/ui/collapsible.d.ts.map +1 -0
  31. package/dist/components/ui/combobox.d.ts +270 -0
  32. package/dist/components/ui/combobox.d.ts.map +1 -0
  33. package/dist/components/ui/command.d.ts +355 -0
  34. package/dist/components/ui/command.d.ts.map +1 -0
  35. package/dist/components/ui/container.d.ts +102 -0
  36. package/dist/components/ui/container.d.ts.map +1 -0
  37. package/dist/components/ui/context-menu.d.ts +339 -0
  38. package/dist/components/ui/context-menu.d.ts.map +1 -0
  39. package/dist/components/ui/date-picker.d.ts +145 -0
  40. package/dist/components/ui/date-picker.d.ts.map +1 -0
  41. package/dist/components/ui/dialog.d.ts +322 -0
  42. package/dist/components/ui/dialog.d.ts.map +1 -0
  43. package/dist/components/ui/drawer.d.ts +154 -0
  44. package/dist/components/ui/drawer.d.ts.map +1 -0
  45. package/dist/components/ui/dropdown-menu.d.ts +349 -0
  46. package/dist/components/ui/dropdown-menu.d.ts.map +1 -0
  47. package/dist/components/ui/empty-state.d.ts +133 -0
  48. package/dist/components/ui/empty-state.d.ts.map +1 -0
  49. package/dist/components/ui/hover-card.d.ts +109 -0
  50. package/dist/components/ui/hover-card.d.ts.map +1 -0
  51. package/dist/components/ui/input.d.ts +89 -0
  52. package/dist/components/ui/input.d.ts.map +1 -0
  53. package/dist/components/ui/label.d.ts +93 -0
  54. package/dist/components/ui/label.d.ts.map +1 -0
  55. package/dist/components/ui/menubar.d.ts +306 -0
  56. package/dist/components/ui/menubar.d.ts.map +1 -0
  57. package/dist/components/ui/navigation-menu.d.ts +318 -0
  58. package/dist/components/ui/navigation-menu.d.ts.map +1 -0
  59. package/dist/components/ui/pagination.d.ts +343 -0
  60. package/dist/components/ui/pagination.d.ts.map +1 -0
  61. package/dist/components/ui/popover.d.ts +178 -0
  62. package/dist/components/ui/popover.d.ts.map +1 -0
  63. package/dist/components/ui/progress.d.ts +64 -0
  64. package/dist/components/ui/progress.d.ts.map +1 -0
  65. package/dist/components/ui/radio-group.d.ts +144 -0
  66. package/dist/components/ui/radio-group.d.ts.map +1 -0
  67. package/dist/components/ui/resizable.d.ts +164 -0
  68. package/dist/components/ui/resizable.d.ts.map +1 -0
  69. package/dist/components/ui/scroll-area.d.ts +82 -0
  70. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  71. package/dist/components/ui/select.d.ts +316 -0
  72. package/dist/components/ui/select.d.ts.map +1 -0
  73. package/dist/components/ui/separator.d.ts +80 -0
  74. package/dist/components/ui/separator.d.ts.map +1 -0
  75. package/dist/components/ui/sheet.d.ts +346 -0
  76. package/dist/components/ui/sheet.d.ts.map +1 -0
  77. package/dist/components/ui/sidebar.d.ts +1561 -0
  78. package/dist/components/ui/sidebar.d.ts.map +1 -0
  79. package/dist/components/ui/skeleton.d.ts +66 -0
  80. package/dist/components/ui/skeleton.d.ts.map +1 -0
  81. package/dist/components/ui/slider.d.ts +95 -0
  82. package/dist/components/ui/slider.d.ts.map +1 -0
  83. package/dist/components/ui/sonner.d.ts +101 -0
  84. package/dist/components/ui/sonner.d.ts.map +1 -0
  85. package/dist/components/ui/stack.d.ts +192 -0
  86. package/dist/components/ui/stack.d.ts.map +1 -0
  87. package/dist/components/ui/stories/accordion.stories.d.ts +71 -0
  88. package/dist/components/ui/stories/accordion.stories.d.ts.map +1 -0
  89. package/dist/components/ui/stories/alert-dialog.stories.d.ts +39 -0
  90. package/dist/components/ui/stories/alert-dialog.stories.d.ts.map +1 -0
  91. package/dist/components/ui/stories/alert.stories.d.ts +48 -0
  92. package/dist/components/ui/stories/alert.stories.d.ts.map +1 -0
  93. package/dist/components/ui/stories/aspect-ratio.stories.d.ts +53 -0
  94. package/dist/components/ui/stories/aspect-ratio.stories.d.ts.map +1 -0
  95. package/dist/components/ui/stories/avatar.stories.d.ts +49 -0
  96. package/dist/components/ui/stories/avatar.stories.d.ts.map +1 -0
  97. package/dist/components/ui/stories/badge.stories.d.ts +64 -0
  98. package/dist/components/ui/stories/badge.stories.d.ts.map +1 -0
  99. package/dist/components/ui/stories/breadcrumb.stories.d.ts +27 -0
  100. package/dist/components/ui/stories/breadcrumb.stories.d.ts.map +1 -0
  101. package/dist/components/ui/stories/button.stories.d.ts +92 -0
  102. package/dist/components/ui/stories/button.stories.d.ts.map +1 -0
  103. package/dist/components/ui/stories/calendar.stories.d.ts +94 -0
  104. package/dist/components/ui/stories/calendar.stories.d.ts.map +1 -0
  105. package/dist/components/ui/stories/card.stories.d.ts +29 -0
  106. package/dist/components/ui/stories/card.stories.d.ts.map +1 -0
  107. package/dist/components/ui/stories/carousel.stories.d.ts +42 -0
  108. package/dist/components/ui/stories/carousel.stories.d.ts.map +1 -0
  109. package/dist/components/ui/stories/chart.stories.d.ts +51 -0
  110. package/dist/components/ui/stories/chart.stories.d.ts.map +1 -0
  111. package/dist/components/ui/stories/checkbox.stories.d.ts +72 -0
  112. package/dist/components/ui/stories/checkbox.stories.d.ts.map +1 -0
  113. package/dist/components/ui/stories/cn.stories.d.ts +19 -0
  114. package/dist/components/ui/stories/cn.stories.d.ts.map +1 -0
  115. package/dist/components/ui/stories/collapsible.stories.d.ts +51 -0
  116. package/dist/components/ui/stories/collapsible.stories.d.ts.map +1 -0
  117. package/dist/components/ui/stories/colors.stories.d.ts +31 -0
  118. package/dist/components/ui/stories/colors.stories.d.ts.map +1 -0
  119. package/dist/components/ui/stories/combobox.stories.d.ts +89 -0
  120. package/dist/components/ui/stories/combobox.stories.d.ts.map +1 -0
  121. package/dist/components/ui/stories/command.stories.d.ts +69 -0
  122. package/dist/components/ui/stories/command.stories.d.ts.map +1 -0
  123. package/dist/components/ui/stories/container.stories.d.ts +42 -0
  124. package/dist/components/ui/stories/container.stories.d.ts.map +1 -0
  125. package/dist/components/ui/stories/context-menu.stories.d.ts +32 -0
  126. package/dist/components/ui/stories/context-menu.stories.d.ts.map +1 -0
  127. package/dist/components/ui/stories/date-picker.stories.d.ts +67 -0
  128. package/dist/components/ui/stories/date-picker.stories.d.ts.map +1 -0
  129. package/dist/components/ui/stories/dialog.stories.d.ts +48 -0
  130. package/dist/components/ui/stories/dialog.stories.d.ts.map +1 -0
  131. package/dist/components/ui/stories/drawer.stories.d.ts +33 -0
  132. package/dist/components/ui/stories/drawer.stories.d.ts.map +1 -0
  133. package/dist/components/ui/stories/dropdown-menu.stories.d.ts +31 -0
  134. package/dist/components/ui/stories/dropdown-menu.stories.d.ts.map +1 -0
  135. package/dist/components/ui/stories/empty-state.stories.d.ts +74 -0
  136. package/dist/components/ui/stories/empty-state.stories.d.ts.map +1 -0
  137. package/dist/components/ui/stories/hover-card.stories.d.ts +35 -0
  138. package/dist/components/ui/stories/hover-card.stories.d.ts.map +1 -0
  139. package/dist/components/ui/stories/input.stories.d.ts +69 -0
  140. package/dist/components/ui/stories/input.stories.d.ts.map +1 -0
  141. package/dist/components/ui/stories/label.stories.d.ts +47 -0
  142. package/dist/components/ui/stories/label.stories.d.ts.map +1 -0
  143. package/dist/components/ui/stories/menubar.stories.d.ts +39 -0
  144. package/dist/components/ui/stories/menubar.stories.d.ts.map +1 -0
  145. package/dist/components/ui/stories/navigation-menu.stories.d.ts +44 -0
  146. package/dist/components/ui/stories/navigation-menu.stories.d.ts.map +1 -0
  147. package/dist/components/ui/stories/pagination.stories.d.ts +33 -0
  148. package/dist/components/ui/stories/pagination.stories.d.ts.map +1 -0
  149. package/dist/components/ui/stories/popover.stories.d.ts +36 -0
  150. package/dist/components/ui/stories/popover.stories.d.ts.map +1 -0
  151. package/dist/components/ui/stories/progress.stories.d.ts +38 -0
  152. package/dist/components/ui/stories/progress.stories.d.ts.map +1 -0
  153. package/dist/components/ui/stories/radio-group.stories.d.ts +76 -0
  154. package/dist/components/ui/stories/radio-group.stories.d.ts.map +1 -0
  155. package/dist/components/ui/stories/resizable.stories.d.ts +49 -0
  156. package/dist/components/ui/stories/resizable.stories.d.ts.map +1 -0
  157. package/dist/components/ui/stories/scroll-area.stories.d.ts +35 -0
  158. package/dist/components/ui/stories/scroll-area.stories.d.ts.map +1 -0
  159. package/dist/components/ui/stories/select.stories.d.ts +51 -0
  160. package/dist/components/ui/stories/select.stories.d.ts.map +1 -0
  161. package/dist/components/ui/stories/separator.stories.d.ts +58 -0
  162. package/dist/components/ui/stories/separator.stories.d.ts.map +1 -0
  163. package/dist/components/ui/stories/sheet.stories.d.ts +43 -0
  164. package/dist/components/ui/stories/sheet.stories.d.ts.map +1 -0
  165. package/dist/components/ui/stories/sidebar.stories.d.ts +60 -0
  166. package/dist/components/ui/stories/sidebar.stories.d.ts.map +1 -0
  167. package/dist/components/ui/stories/skeleton.stories.d.ts +42 -0
  168. package/dist/components/ui/stories/skeleton.stories.d.ts.map +1 -0
  169. package/dist/components/ui/stories/slider.stories.d.ts +99 -0
  170. package/dist/components/ui/stories/slider.stories.d.ts.map +1 -0
  171. package/dist/components/ui/stories/sonner.stories.d.ts +9 -0
  172. package/dist/components/ui/stories/sonner.stories.d.ts.map +1 -0
  173. package/dist/components/ui/stories/stack.stories.d.ts +39 -0
  174. package/dist/components/ui/stories/stack.stories.d.ts.map +1 -0
  175. package/dist/components/ui/stories/switch.stories.d.ts +71 -0
  176. package/dist/components/ui/stories/switch.stories.d.ts.map +1 -0
  177. package/dist/components/ui/stories/table.stories.d.ts +40 -0
  178. package/dist/components/ui/stories/table.stories.d.ts.map +1 -0
  179. package/dist/components/ui/stories/tabs.stories.d.ts +62 -0
  180. package/dist/components/ui/stories/tabs.stories.d.ts.map +1 -0
  181. package/dist/components/ui/stories/text-field.stories.d.ts +78 -0
  182. package/dist/components/ui/stories/text-field.stories.d.ts.map +1 -0
  183. package/dist/components/ui/stories/textarea.stories.d.ts +57 -0
  184. package/dist/components/ui/stories/textarea.stories.d.ts.map +1 -0
  185. package/dist/components/ui/stories/theme-toggle.stories.d.ts +71 -0
  186. package/dist/components/ui/stories/theme-toggle.stories.d.ts.map +1 -0
  187. package/dist/components/ui/stories/theme.stories.d.ts +51 -0
  188. package/dist/components/ui/stories/theme.stories.d.ts.map +1 -0
  189. package/dist/components/ui/stories/toggle-group.stories.d.ts +71 -0
  190. package/dist/components/ui/stories/toggle-group.stories.d.ts.map +1 -0
  191. package/dist/components/ui/stories/toggle.stories.d.ts +78 -0
  192. package/dist/components/ui/stories/toggle.stories.d.ts.map +1 -0
  193. package/dist/components/ui/stories/tooltip.stories.d.ts +37 -0
  194. package/dist/components/ui/stories/tooltip.stories.d.ts.map +1 -0
  195. package/dist/components/ui/stories/typography.stories.d.ts +137 -0
  196. package/dist/components/ui/stories/typography.stories.d.ts.map +1 -0
  197. package/dist/components/ui/stories/use-mobile.stories.d.ts +20 -0
  198. package/dist/components/ui/stories/use-mobile.stories.d.ts.map +1 -0
  199. package/dist/components/ui/stories/use-theme.stories.d.ts +23 -0
  200. package/dist/components/ui/stories/use-theme.stories.d.ts.map +1 -0
  201. package/dist/components/ui/switch.d.ts +84 -0
  202. package/dist/components/ui/switch.d.ts.map +1 -0
  203. package/dist/components/ui/table.d.ts +321 -0
  204. package/dist/components/ui/table.d.ts.map +1 -0
  205. package/dist/components/ui/tabs.d.ts +260 -0
  206. package/dist/components/ui/tabs.d.ts.map +1 -0
  207. package/dist/components/ui/text-field.d.ts +157 -0
  208. package/dist/components/ui/text-field.d.ts.map +1 -0
  209. package/dist/components/ui/textarea.d.ts +84 -0
  210. package/dist/components/ui/textarea.d.ts.map +1 -0
  211. package/dist/components/ui/theme-toggle.d.ts +105 -0
  212. package/dist/components/ui/theme-toggle.d.ts.map +1 -0
  213. package/dist/components/ui/theme.d.ts +110 -0
  214. package/dist/components/ui/theme.d.ts.map +1 -0
  215. package/dist/components/ui/toggle-group.d.ts +133 -0
  216. package/dist/components/ui/toggle-group.d.ts.map +1 -0
  217. package/dist/components/ui/toggle.d.ts +84 -0
  218. package/dist/components/ui/toggle.d.ts.map +1 -0
  219. package/dist/components/ui/tooltip.d.ts +202 -0
  220. package/dist/components/ui/tooltip.d.ts.map +1 -0
  221. package/dist/components/ui/typography.d.ts +287 -0
  222. package/dist/components/ui/typography.d.ts.map +1 -0
  223. package/dist/hooks/use-mobile.d.ts +74 -0
  224. package/dist/hooks/use-mobile.d.ts.map +1 -0
  225. package/dist/hooks/use-theme.d.ts +142 -0
  226. package/dist/hooks/use-theme.d.ts.map +1 -0
  227. package/dist/index.d.ts +57 -0
  228. package/dist/index.d.ts.map +1 -0
  229. package/dist/index.js +27498 -0
  230. package/dist/index.js.map +1 -0
  231. package/dist/lib/utils.d.ts +43 -0
  232. package/dist/lib/utils.d.ts.map +1 -0
  233. package/dist/tsconfig.tsbuildinfo +1 -0
  234. package/docs/llm/colors.md +273 -0
  235. package/docs/llm/components/buttons.md +68 -0
  236. package/docs/llm/components/cards.md +53 -0
  237. package/docs/llm/components/display.md +134 -0
  238. package/docs/llm/components/feedback.md +96 -0
  239. package/docs/llm/components/forms.md +90 -0
  240. package/docs/llm/components/layout.md +59 -0
  241. package/docs/llm/components/menus.md +70 -0
  242. package/docs/llm/components/navigation.md +80 -0
  243. package/docs/llm/components/overlays.md +83 -0
  244. package/docs/llm/components/tables.md +73 -0
  245. package/docs/llm/components/typography.md +199 -0
  246. package/docs/llm/components/utilities.md +114 -0
  247. package/docs/llm/guide.md +165 -0
  248. package/llms.txt +122 -0
  249. package/package.json +104 -0
  250. package/src/components/ui/accordion.tsx +285 -0
  251. package/src/components/ui/alert-dialog.tsx +387 -0
  252. package/src/components/ui/alert.tsx +243 -0
  253. package/src/components/ui/aspect-ratio.tsx +99 -0
  254. package/src/components/ui/avatar.tsx +288 -0
  255. package/src/components/ui/badge.tsx +205 -0
  256. package/src/components/ui/breadcrumb.tsx +378 -0
  257. package/src/components/ui/button.tsx +195 -0
  258. package/src/components/ui/calendar.tsx +371 -0
  259. package/src/components/ui/card.tsx +447 -0
  260. package/src/components/ui/carousel.tsx +624 -0
  261. package/src/components/ui/chart.tsx +802 -0
  262. package/src/components/ui/checkbox.tsx +113 -0
  263. package/src/components/ui/collapsible.tsx +207 -0
  264. package/src/components/ui/combobox.tsx +373 -0
  265. package/src/components/ui/command.tsx +518 -0
  266. package/src/components/ui/container.tsx +114 -0
  267. package/src/components/ui/context-menu.tsx +563 -0
  268. package/src/components/ui/date-picker.tsx +213 -0
  269. package/src/components/ui/dialog.tsx +447 -0
  270. package/src/components/ui/drawer.tsx +273 -0
  271. package/src/components/ui/dropdown-menu.tsx +578 -0
  272. package/src/components/ui/empty-state.tsx +145 -0
  273. package/src/components/ui/hover-card.tsx +144 -0
  274. package/src/components/ui/input.tsx +106 -0
  275. package/src/components/ui/label.tsx +110 -0
  276. package/src/components/ui/menubar.tsx +553 -0
  277. package/src/components/ui/navigation-menu.tsx +471 -0
  278. package/src/components/ui/pagination.tsx +456 -0
  279. package/src/components/ui/popover.tsx +216 -0
  280. package/src/components/ui/progress.tsx +88 -0
  281. package/src/components/ui/radio-group.tsx +183 -0
  282. package/src/components/ui/resizable.tsx +209 -0
  283. package/src/components/ui/scroll-area.tsx +132 -0
  284. package/src/components/ui/select.tsx +485 -0
  285. package/src/components/ui/separator.tsx +101 -0
  286. package/src/components/ui/sheet.tsx +495 -0
  287. package/src/components/ui/sidebar.tsx +2211 -0
  288. package/src/components/ui/skeleton.tsx +76 -0
  289. package/src/components/ui/slider.tsx +147 -0
  290. package/src/components/ui/sonner.tsx +120 -0
  291. package/src/components/ui/stack.tsx +180 -0
  292. package/src/components/ui/stories/accordion.stories.tsx +429 -0
  293. package/src/components/ui/stories/alert-dialog.stories.tsx +519 -0
  294. package/src/components/ui/stories/alert.stories.tsx +228 -0
  295. package/src/components/ui/stories/aspect-ratio.stories.tsx +200 -0
  296. package/src/components/ui/stories/avatar.stories.tsx +317 -0
  297. package/src/components/ui/stories/badge.stories.tsx +260 -0
  298. package/src/components/ui/stories/breadcrumb.stories.tsx +482 -0
  299. package/src/components/ui/stories/button.stories.tsx +266 -0
  300. package/src/components/ui/stories/calendar.stories.tsx +375 -0
  301. package/src/components/ui/stories/card.stories.tsx +308 -0
  302. package/src/components/ui/stories/carousel.stories.tsx +328 -0
  303. package/src/components/ui/stories/chart.stories.tsx +430 -0
  304. package/src/components/ui/stories/checkbox.stories.tsx +297 -0
  305. package/src/components/ui/stories/cn.stories.tsx +433 -0
  306. package/src/components/ui/stories/collapsible.stories.tsx +256 -0
  307. package/src/components/ui/stories/colors.stories.tsx +502 -0
  308. package/src/components/ui/stories/combobox.stories.tsx +301 -0
  309. package/src/components/ui/stories/command.stories.tsx +632 -0
  310. package/src/components/ui/stories/container.stories.tsx +250 -0
  311. package/src/components/ui/stories/context-menu.stories.tsx +446 -0
  312. package/src/components/ui/stories/date-picker.stories.tsx +378 -0
  313. package/src/components/ui/stories/dialog.stories.tsx +535 -0
  314. package/src/components/ui/stories/drawer.stories.tsx +364 -0
  315. package/src/components/ui/stories/dropdown-menu.stories.tsx +374 -0
  316. package/src/components/ui/stories/empty-state.stories.tsx +244 -0
  317. package/src/components/ui/stories/hover-card.stories.tsx +355 -0
  318. package/src/components/ui/stories/input.stories.tsx +289 -0
  319. package/src/components/ui/stories/label.stories.tsx +294 -0
  320. package/src/components/ui/stories/menubar.stories.tsx +764 -0
  321. package/src/components/ui/stories/navigation-menu.stories.tsx +539 -0
  322. package/src/components/ui/stories/pagination.stories.tsx +604 -0
  323. package/src/components/ui/stories/popover.stories.tsx +392 -0
  324. package/src/components/ui/stories/progress.stories.tsx +218 -0
  325. package/src/components/ui/stories/radio-group.stories.tsx +400 -0
  326. package/src/components/ui/stories/resizable.stories.tsx +417 -0
  327. package/src/components/ui/stories/scroll-area.stories.tsx +180 -0
  328. package/src/components/ui/stories/select.stories.tsx +389 -0
  329. package/src/components/ui/stories/separator.stories.tsx +192 -0
  330. package/src/components/ui/stories/sheet.stories.tsx +468 -0
  331. package/src/components/ui/stories/sidebar.stories.tsx +731 -0
  332. package/src/components/ui/stories/skeleton.stories.tsx +216 -0
  333. package/src/components/ui/stories/slider.stories.tsx +321 -0
  334. package/src/components/ui/stories/sonner.stories.tsx +373 -0
  335. package/src/components/ui/stories/stack.stories.tsx +222 -0
  336. package/src/components/ui/stories/switch.stories.tsx +202 -0
  337. package/src/components/ui/stories/table.stories.tsx +541 -0
  338. package/src/components/ui/stories/tabs.stories.tsx +544 -0
  339. package/src/components/ui/stories/text-field.stories.tsx +280 -0
  340. package/src/components/ui/stories/textarea.stories.tsx +245 -0
  341. package/src/components/ui/stories/theme-toggle.stories.tsx +275 -0
  342. package/src/components/ui/stories/theme.stories.tsx +412 -0
  343. package/src/components/ui/stories/toggle-group.stories.tsx +337 -0
  344. package/src/components/ui/stories/toggle.stories.tsx +325 -0
  345. package/src/components/ui/stories/tooltip.stories.tsx +444 -0
  346. package/src/components/ui/stories/typography.stories.tsx +1586 -0
  347. package/src/components/ui/stories/use-mobile.stories.tsx +420 -0
  348. package/src/components/ui/stories/use-theme.stories.tsx +531 -0
  349. package/src/components/ui/switch.tsx +106 -0
  350. package/src/components/ui/table.tsx +424 -0
  351. package/src/components/ui/tabs.tsx +316 -0
  352. package/src/components/ui/text-field.tsx +206 -0
  353. package/src/components/ui/textarea.tsx +98 -0
  354. package/src/components/ui/theme-toggle.tsx +185 -0
  355. package/src/components/ui/theme.tsx +148 -0
  356. package/src/components/ui/toggle-group.tsx +196 -0
  357. package/src/components/ui/toggle.tsx +115 -0
  358. package/src/components/ui/tooltip.tsx +253 -0
  359. package/src/components/ui/typography.tsx +468 -0
  360. package/src/hooks/use-mobile.ts +91 -0
  361. package/src/hooks/use-theme.ts +319 -0
  362. package/src/index.ts +77 -0
  363. package/src/lib/utils.ts +57 -0
  364. package/src/styles/globals.css +160 -0
@@ -0,0 +1,91 @@
1
+ import * as React from "react"
2
+
3
+ const MOBILE_BREAKPOINT = 768
4
+
5
+ /**
6
+ * Hook for detecting mobile viewport width based on Tailwind CSS breakpoints
7
+ *
8
+ * A React hook that monitors viewport width and returns true when the width
9
+ * is less than 768px (Tailwind's `md` breakpoint). This hook provides a
10
+ * consistent way to conditionally render mobile and desktop layouts, following
11
+ * the same responsive patterns used throughout the shadcn/ui ecosystem.
12
+ *
13
+ * The hook uses `window.matchMedia` for efficient viewport monitoring and
14
+ * properly handles server-side rendering by returning `false` initially,
15
+ * then updating on the client side.
16
+ *
17
+ * @returns `true` if viewport width is less than 768px, `false` otherwise
18
+ *
19
+ * @example
20
+ * Basic responsive layout switching
21
+ * ```tsx
22
+ * function ResponsiveComponent() {
23
+ * const isMobile = useIsMobile();
24
+ *
25
+ * return (
26
+ * <div>
27
+ * {isMobile ? (
28
+ * <MobileLayout />
29
+ * ) : (
30
+ * <DesktopLayout />
31
+ * )}
32
+ * </div>
33
+ * );
34
+ * }
35
+ * ```
36
+ *
37
+ * @example
38
+ * Conditional navigation rendering
39
+ * ```tsx
40
+ * function Navigation() {
41
+ * const isMobile = useIsMobile();
42
+ *
43
+ * if (isMobile) {
44
+ * return <Sheet><MobileNavContent /></Sheet>;
45
+ * }
46
+ *
47
+ * return <NavigationMenu><DesktopNavContent /></NavigationMenu>;
48
+ * }
49
+ * ```
50
+ *
51
+ * @example
52
+ * Responsive component behavior within forms
53
+ * ```tsx
54
+ * function SearchDialog() {
55
+ * const isMobile = useIsMobile();
56
+ *
57
+ * if (isMobile) {
58
+ * return <Drawer><SearchForm /></Drawer>;
59
+ * }
60
+ *
61
+ * return <Dialog><SearchForm /></Dialog>;
62
+ * }
63
+ * ```
64
+ *
65
+ * @remarks
66
+ * - Uses the standard 768px breakpoint matching Tailwind's `md` breakpoint
67
+ * - Similar pattern to `isMobile` property in shadcn/ui's `useSidebar` hook
68
+ * - Handles viewport resize events automatically
69
+ * - SSR-safe implementation prevents hydration mismatches
70
+ * - Respects user's browser zoom settings
71
+ *
72
+ * @see {@link https://tailwindcss.com/docs/responsive-design} Tailwind CSS responsive design
73
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia} MDN matchMedia documentation
74
+ *
75
+ * @since 1.0.0
76
+ */
77
+ export function useIsMobile() {
78
+ const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
79
+
80
+ React.useEffect(() => {
81
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
82
+ const onChange = () => {
83
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
84
+ }
85
+ mql.addEventListener("change", onChange)
86
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
87
+ return () => mql.removeEventListener("change", onChange)
88
+ }, [])
89
+
90
+ return !!isMobile
91
+ }
@@ -0,0 +1,319 @@
1
+ "use client"
2
+
3
+ import { useEffect, useState } from "react"
4
+
5
+ /**
6
+ * Theme preference options for the theme system
7
+ *
8
+ * Controls how the application determines the active theme:
9
+ * - `"system"` - Automatically follows the user's OS preference
10
+ * - `"light"` - Forces light theme regardless of system preference
11
+ * - `"dark"` - Forces dark theme regardless of system preference
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * const { preference, setPreference } = useTheme();
16
+ *
17
+ * // Switch to dark mode
18
+ * setPreference("dark");
19
+ *
20
+ * // Follow system preference
21
+ * setPreference("system");
22
+ * ```
23
+ *
24
+ * @since 1.0.0
25
+ */
26
+ export type ThemePreference = "system" | "light" | "dark"
27
+
28
+ /**
29
+ * Internal theme state structure stored in cookies
30
+ *
31
+ * Maintains both the user's preference and the actual mode value
32
+ * to handle system theme changes efficiently.
33
+ *
34
+ * @internal
35
+ */
36
+ type ThemeState = {
37
+ /** User's selected theme preference */
38
+ preference: ThemePreference
39
+ /** Actual mode applied to the DOM */
40
+ mode: "light" | "dark"
41
+ }
42
+
43
+ /**
44
+ * Cookie configuration for theme persistence
45
+ *
46
+ * Uses secure defaults for cross-site compatibility and long-term storage.
47
+ *
48
+ * @internal
49
+ */
50
+ const COOKIE_NAME = "theme"
51
+ const COOKIE_OPTIONS = {
52
+ path: "/",
53
+ maxAge: 60 * 60 * 24 * 365, // 1 year
54
+ sameSite: "lax" as const,
55
+ }
56
+
57
+ /**
58
+ * Retrieves the stored theme preference from browser cookies
59
+ *
60
+ * Safely parses the cookie value and handles malformed data gracefully.
61
+ * Returns null if no valid theme data is found or if running server-side.
62
+ *
63
+ * @returns The stored theme state or null if unavailable
64
+ * @internal
65
+ */
66
+ function getThemeFromCookie(): ThemeState | null {
67
+ if (typeof document === "undefined") return null
68
+ const match = document.cookie.match(new RegExp(`(?:^|; )${COOKIE_NAME}=([^;]*)`))
69
+ if (!match) return null
70
+
71
+ try {
72
+ const decoded = decodeURIComponent(match[1] || "")
73
+ return JSON.parse(decoded)
74
+ } catch {
75
+ return null
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Persists the current theme state to browser cookies
81
+ *
82
+ * Stores the complete theme state as a JSON string with appropriate
83
+ * cookie settings for security and longevity. Safe for server-side rendering.
84
+ *
85
+ * @param state - The theme state to persist
86
+ * @internal
87
+ */
88
+ function setThemeCookie(state: ThemeState) {
89
+ if (typeof document === "undefined") return
90
+
91
+ const value = JSON.stringify(state)
92
+ let cookieString = `${COOKIE_NAME}=${encodeURIComponent(value)}`
93
+
94
+ cookieString += `; path=${COOKIE_OPTIONS.path}`
95
+ cookieString += `; max-age=${COOKIE_OPTIONS.maxAge}`
96
+ cookieString += `; samesite=${COOKIE_OPTIONS.sameSite}`
97
+
98
+ document.cookie = cookieString
99
+ }
100
+
101
+ /**
102
+ * Detects the user's system theme preference
103
+ *
104
+ * Uses the CSS media query `prefers-color-scheme` to determine if the user
105
+ * has configured their OS to prefer dark or light themes. Falls back to
106
+ * light theme for server-side rendering or unsupported browsers.
107
+ *
108
+ * @returns The system's preferred theme
109
+ * @internal
110
+ */
111
+ function getSystemTheme(): "light" | "dark" {
112
+ if (typeof window === "undefined") return "light"
113
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light"
114
+ }
115
+
116
+ /**
117
+ * Applies the specified theme to the document
118
+ *
119
+ * Updates the document's class list and color-scheme CSS property to reflect
120
+ * the chosen theme. This triggers CSS-based theme switching throughout the
121
+ * application and ensures native elements respect the theme choice.
122
+ *
123
+ * @param theme - The theme to apply ("light" or "dark")
124
+ * @internal
125
+ */
126
+ function applyTheme(theme: "light" | "dark") {
127
+ if (typeof document === "undefined") return
128
+
129
+ // For light theme, remove dark class (light is default)
130
+ // For dark theme, add dark class
131
+ if (theme === "dark") {
132
+ document.documentElement.classList.add("dark")
133
+ } else {
134
+ document.documentElement.classList.remove("dark")
135
+ }
136
+
137
+ // Set color-scheme for native elements
138
+ document.documentElement.style.colorScheme = theme
139
+ }
140
+
141
+ /**
142
+ * Hook for managing application theme with automatic system preference detection
143
+ *
144
+ * A complete theme management solution that handles persistence, system preference
145
+ * detection, and DOM manipulation without requiring any context providers. Designed
146
+ * for applications that need simple light/dark mode switching with optional system
147
+ * preference following.
148
+ *
149
+ * This hook works in conjunction with the {@link Theme} component to provide a complete
150
+ * theming solution with FOUC prevention and perfect synchronization across multiple
151
+ * instances.
152
+ *
153
+ * Features:
154
+ * - **Perfect synchronization**: Multiple hook instances stay in sync via custom events
155
+ * - **Automatic persistence**: Theme preference saved to cookies across sessions
156
+ * - **System preference detection**: Automatically follows OS dark/light mode when set to "system"
157
+ * - **Live system updates**: Responds to system theme changes in real-time
158
+ * - **SSR compatible**: Works safely during server-side rendering
159
+ * - **Type safe**: Full TypeScript support with proper type definitions
160
+ * - **No provider required**: Self-contained hook that works out of the box
161
+ *
162
+ * @example Basic theme switching
163
+ * ```tsx
164
+ * function ThemeToggle() {
165
+ * const { preference, mode, setPreference } = useTheme();
166
+ *
167
+ * const toggleTheme = () => {
168
+ * setPreference(mode === "dark" ? "light" : "dark");
169
+ * };
170
+ *
171
+ * return (
172
+ * <button onClick={toggleTheme}>
173
+ * Switch to {mode === "dark" ? "light" : "dark"} mode
174
+ * </button>
175
+ * );
176
+ * }
177
+ * ```
178
+ *
179
+ * @example Theme selector dropdown
180
+ * ```tsx
181
+ * function ThemeSelector() {
182
+ * const { preference, setPreference } = useTheme();
183
+ *
184
+ * return (
185
+ * <select value={preference} onChange={(e) => setPreference(e.target.value as ThemePreference)}>
186
+ * <option value="system">Follow system</option>
187
+ * <option value="light">Light mode</option>
188
+ * <option value="dark">Dark mode</option>
189
+ * </select>
190
+ * );
191
+ * }
192
+ * ```
193
+ *
194
+ * @example Multiple synchronized toggles
195
+ * ```tsx
196
+ * function App() {
197
+ * return (
198
+ * <>
199
+ * <Header>
200
+ * <ThemeToggle />
201
+ * </Header>
202
+ * <Sidebar>
203
+ * <ThemeToggle />
204
+ * </Sidebar>
205
+ * </>
206
+ * );
207
+ * }
208
+ * ```
209
+ *
210
+ * @example Conditional rendering based on theme
211
+ * ```tsx
212
+ * function ThemedIcon() {
213
+ * const { mode } = useTheme();
214
+ *
215
+ * return mode === "dark" ? <MoonIcon /> : <SunIcon />;
216
+ * }
217
+ * ```
218
+ *
219
+ * @returns Object containing current theme state and setter function
220
+ * @returns returns.preference - The user's selected theme preference
221
+ * @returns returns.mode - The actual theme currently applied (always "light" or "dark")
222
+ * @returns returns.setPreference - Function to change the theme preference
223
+ *
224
+ * @remarks
225
+ * **Synchronization Architecture:**
226
+ * - All theme changes are broadcasted via custom 'theme-change' events
227
+ * - Single setState per change across ALL hook instances (no duplicates)
228
+ * - Event-driven updates ensure perfect synchronization
229
+ * - Cookie serves as the single source of truth for persistence
230
+ *
231
+ * **Implementation Details:**
232
+ * - Theme state is automatically persisted to cookies with 1-year expiration
233
+ * - System preference changes are detected via `matchMedia` API
234
+ * - DOM updates are applied immediately when theme changes
235
+ * - Hook is safe to use during SSR (falls back to light theme)
236
+ * - Custom events handle cross-instance synchronization
237
+ *
238
+ * **Performance:**
239
+ * - Single setState per theme change (no duplicate updates)
240
+ * - Efficient event-driven architecture
241
+ * - No context overhead: direct hook usage without providers
242
+ * - Automatic cleanup: removes event listeners on component unmount
243
+ *
244
+ * **Browser Support:**
245
+ * - Modern browsers with `matchMedia` support for system detection
246
+ * - CustomEvent support for synchronization (IE11+ with polyfill)
247
+ * - Graceful degradation for older browsers (defaults to light theme)
248
+ * - Cookie support required for persistence across sessions
249
+ *
250
+ * @see {@link ThemePreference} - Available theme preference options
251
+ * @see {@link Theme} - Component for FOUC prevention
252
+ * @see {@link ThemeToggle} - UI component for theme switching
253
+ * @since 1.0.0
254
+ */
255
+ export function useTheme() {
256
+ // Initialize state from cookie or default to system
257
+ const [state, setState] = useState<ThemeState>(() => {
258
+ const saved = getThemeFromCookie()
259
+ if (saved) return saved
260
+
261
+ const mode = getSystemTheme()
262
+ return { preference: "system", mode }
263
+ })
264
+
265
+ // Set theme preference - dispatch event, let event handler update state
266
+ const setPreference = (newPreference: ThemePreference) => {
267
+ const mode = newPreference === "system" ? getSystemTheme() : newPreference
268
+ const newState = { preference: newPreference, mode }
269
+
270
+ // Update cookie and DOM immediately
271
+ setThemeCookie(newState)
272
+ applyTheme(mode)
273
+
274
+ // Broadcast change - ALL instances (including this one) will update state from this event
275
+ window.dispatchEvent(new CustomEvent('theme-change', {
276
+ detail: newState
277
+ }))
278
+ }
279
+
280
+ // Single event handler for ALL state updates (including from this instance)
281
+ useEffect(() => {
282
+ const handleThemeChange = (event: CustomEvent) => {
283
+ setState(event.detail) // Single setState for all instances
284
+ }
285
+
286
+ window.addEventListener('theme-change', handleThemeChange as EventListener)
287
+ return () => window.removeEventListener('theme-change', handleThemeChange as EventListener)
288
+ }, [])
289
+
290
+ // Listen for system theme changes when in system mode
291
+ useEffect(() => {
292
+ if (state.preference !== "system") return
293
+
294
+ const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
295
+ const handleChange = () => {
296
+ const mode = getSystemTheme()
297
+ const newState = { preference: state.preference, mode }
298
+
299
+ // Same pattern: update cookie/DOM, then broadcast
300
+ setThemeCookie(newState)
301
+ applyTheme(mode)
302
+ window.dispatchEvent(new CustomEvent('theme-change', { detail: newState }))
303
+ }
304
+
305
+ mediaQuery.addEventListener("change", handleChange)
306
+ return () => mediaQuery.removeEventListener("change", handleChange)
307
+ }, [state.preference])
308
+
309
+ // Apply theme on mount (only for initial hydration)
310
+ useEffect(() => {
311
+ applyTheme(state.mode)
312
+ }, [state.mode])
313
+
314
+ return {
315
+ preference: state.preference,
316
+ mode: state.mode,
317
+ setPreference,
318
+ }
319
+ }
package/src/index.ts ADDED
@@ -0,0 +1,77 @@
1
+ // Form & Input Components
2
+ export * from "./components/ui/button";
3
+ export * from "./components/ui/text-field";
4
+ export * from "./components/ui/select";
5
+ export * from "./components/ui/combobox";
6
+ export * from "./components/ui/input";
7
+ export * from "./components/ui/textarea";
8
+ export * from "./components/ui/checkbox";
9
+ export * from "./components/ui/switch";
10
+ export * from "./components/ui/radio-group";
11
+ export * from "./components/ui/date-picker";
12
+ export * from "./components/ui/calendar";
13
+ export * from "./components/ui/label";
14
+
15
+ // Layout & Structure
16
+ export * from "./components/ui/container";
17
+ export * from "./components/ui/stack";
18
+ export * from "./components/ui/card";
19
+ export * from "./components/ui/separator";
20
+ export * from "./components/ui/aspect-ratio";
21
+ export * from "./components/ui/accordion";
22
+ export * from "./components/ui/collapsible";
23
+ export * from "./components/ui/resizable";
24
+ export * from "./components/ui/scroll-area";
25
+
26
+ // Navigation & Menus
27
+ export * from "./components/ui/navigation-menu";
28
+ export * from "./components/ui/tabs";
29
+ export * from "./components/ui/breadcrumb";
30
+ export * from "./components/ui/pagination";
31
+ export * from "./components/ui/sidebar";
32
+ export * from "./components/ui/dropdown-menu";
33
+ export * from "./components/ui/context-menu";
34
+ export * from "./components/ui/menubar";
35
+
36
+ // Overlays & Dialogs
37
+ export * from "./components/ui/dialog";
38
+ export * from "./components/ui/alert-dialog";
39
+ export * from "./components/ui/popover";
40
+ export * from "./components/ui/tooltip";
41
+ export * from "./components/ui/sheet";
42
+ export * from "./components/ui/hover-card";
43
+ export * from "./components/ui/drawer";
44
+
45
+ // Typography
46
+ export * from "./components/ui/typography";
47
+
48
+ // Data Display
49
+ export * from "./components/ui/table";
50
+ export * from "./components/ui/badge";
51
+ export * from "./components/ui/avatar";
52
+ export * from "./components/ui/alert";
53
+ export * from "./components/ui/progress";
54
+ export * from "./components/ui/skeleton";
55
+ export * from "./components/ui/empty-state";
56
+ export * from "./components/ui/sonner";
57
+
58
+ // Interactive Controls
59
+ export * from "./components/ui/toggle";
60
+ export * from "./components/ui/toggle-group";
61
+ export * from "./components/ui/slider";
62
+ export * from "./components/ui/command";
63
+
64
+ // Charts & Visualization
65
+ export * from "./components/ui/chart";
66
+ export * from "./components/ui/carousel";
67
+
68
+ // Theme & Utilities
69
+ export * from "./components/ui/theme";
70
+ export * from "./components/ui/theme-toggle";
71
+
72
+ // Utilities
73
+ export * from "./lib/utils";
74
+
75
+ // Hooks
76
+ export * from "./hooks/use-mobile";
77
+ export * from "./hooks/use-theme";
@@ -0,0 +1,57 @@
1
+ import { clsx, type ClassValue } from "clsx";
2
+ import { extendTailwindMerge } from "tailwind-merge";
3
+
4
+ /**
5
+ * Custom tailwind-merge instance with support for custom classes
6
+ */
7
+ const twMerge = extendTailwindMerge({
8
+ extend: {
9
+ classGroups: {
10
+ 'font-size': ['text-microcopy'],
11
+ },
12
+ },
13
+ });
14
+
15
+ /**
16
+ * cn - Combines class names with Tailwind CSS conflict resolution
17
+ *
18
+ * This utility function combines multiple class names into a single string,
19
+ * automatically resolving Tailwind CSS class conflicts. It uses clsx for
20
+ * conditional class handling and tailwind-merge to ensure later classes
21
+ * override earlier ones when they conflict.
22
+ *
23
+ * @param inputs - Class names to combine. Can be strings, objects, arrays,
24
+ * undefined, null, or boolean values
25
+ * @returns A single string of combined and merged class names
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * // Basic usage
30
+ * cn("px-2 py-1", "bg-blue-500", "text-white")
31
+ * // Returns: "px-2 py-1 bg-blue-500 text-white"
32
+ * ```
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * // With conditional classes
37
+ * cn(
38
+ * "base-class",
39
+ * isActive && "active-class",
40
+ * isDisabled && "disabled-class"
41
+ * )
42
+ * ```
43
+ *
44
+ * @example
45
+ * ```tsx
46
+ * // Overriding Tailwind classes
47
+ * cn("px-4", "px-2") // Returns: "px-2" (later class wins)
48
+ * cn("text-red-500", "text-blue-500") // Returns: "text-blue-500"
49
+ * ```
50
+ *
51
+ * @see {@link https://github.com/lukeed/clsx} - clsx documentation
52
+ * @see {@link https://github.com/dcastil/tailwind-merge} - tailwind-merge documentation
53
+ * @since 1.0.0
54
+ */
55
+ export function cn(...inputs: ClassValue[]) {
56
+ return twMerge(clsx(inputs));
57
+ }