@spatika/react 1.0.0 → 1.2.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 (369) hide show
  1. package/AGENTS.md +71 -0
  2. package/README.md +4 -3
  3. package/dist/composites/AccentRule.d.ts +6 -0
  4. package/dist/composites/AccentRule.d.ts.map +1 -0
  5. package/dist/composites/AccentRule.js +6 -0
  6. package/dist/composites/AvailabilityBadge.d.ts +9 -0
  7. package/dist/composites/AvailabilityBadge.d.ts.map +1 -0
  8. package/dist/composites/AvailabilityBadge.js +9 -0
  9. package/dist/composites/Card.d.ts +7 -1
  10. package/dist/composites/Card.d.ts.map +1 -1
  11. package/dist/composites/Card.js +10 -0
  12. package/dist/composites/CareerCard.d.ts +20 -0
  13. package/dist/composites/CareerCard.d.ts.map +1 -0
  14. package/dist/composites/CareerCard.js +17 -0
  15. package/dist/composites/ChartDataGrid.d.ts +33 -0
  16. package/dist/composites/ChartDataGrid.d.ts.map +1 -0
  17. package/dist/composites/ChartDataGrid.js +77 -0
  18. package/dist/composites/ContactLink.d.ts +15 -0
  19. package/dist/composites/ContactLink.d.ts.map +1 -0
  20. package/dist/composites/ContactLink.js +8 -0
  21. package/dist/composites/CoverHero.d.ts +1 -1
  22. package/dist/composites/CoverHero.d.ts.map +1 -1
  23. package/dist/composites/CoverHero.js +2 -2
  24. package/dist/composites/DisplayHeading.d.ts +9 -0
  25. package/dist/composites/DisplayHeading.d.ts.map +1 -0
  26. package/dist/composites/DisplayHeading.js +6 -0
  27. package/dist/composites/EntityMediaCard.d.ts +1 -1
  28. package/dist/composites/EntityMediaCard.d.ts.map +1 -1
  29. package/dist/composites/EntityMediaCard.js +12 -4
  30. package/dist/composites/EventCalendar.d.ts +35 -0
  31. package/dist/composites/EventCalendar.d.ts.map +1 -0
  32. package/dist/composites/EventCalendar.js +339 -0
  33. package/dist/composites/EventEditor.d.ts +22 -0
  34. package/dist/composites/EventEditor.d.ts.map +1 -0
  35. package/dist/composites/EventEditor.js +86 -0
  36. package/dist/composites/EventTimeline.d.ts +24 -0
  37. package/dist/composites/EventTimeline.d.ts.map +1 -0
  38. package/dist/composites/EventTimeline.js +184 -0
  39. package/dist/composites/FloatChip.d.ts +15 -0
  40. package/dist/composites/FloatChip.d.ts.map +1 -0
  41. package/dist/composites/FloatChip.js +7 -0
  42. package/dist/composites/GradientText.d.ts +11 -0
  43. package/dist/composites/GradientText.d.ts.map +1 -0
  44. package/dist/composites/GradientText.js +6 -0
  45. package/dist/composites/IconTile.d.ts +10 -0
  46. package/dist/composites/IconTile.d.ts.map +1 -0
  47. package/dist/composites/IconTile.js +7 -0
  48. package/dist/composites/MapChart.d.ts +24 -0
  49. package/dist/composites/MapChart.d.ts.map +1 -0
  50. package/dist/composites/MapChart.js +58 -0
  51. package/dist/composites/MetaChip.d.ts +9 -0
  52. package/dist/composites/MetaChip.d.ts.map +1 -0
  53. package/dist/composites/MetaChip.js +6 -0
  54. package/dist/composites/PresenceDot.d.ts +10 -0
  55. package/dist/composites/PresenceDot.d.ts.map +1 -0
  56. package/dist/composites/PresenceDot.js +10 -0
  57. package/dist/composites/ProfileHero.d.ts +6 -4
  58. package/dist/composites/ProfileHero.d.ts.map +1 -1
  59. package/dist/composites/ProfileHero.js +8 -8
  60. package/dist/composites/ProjectCard.d.ts +12 -0
  61. package/dist/composites/ProjectCard.d.ts.map +1 -0
  62. package/dist/composites/ProjectCard.js +9 -0
  63. package/dist/composites/ScatterWebGL.d.ts +22 -0
  64. package/dist/composites/ScatterWebGL.d.ts.map +1 -0
  65. package/dist/composites/ScatterWebGL.js +45 -0
  66. package/dist/composites/SectionHeading.d.ts +16 -0
  67. package/dist/composites/SectionHeading.d.ts.map +1 -0
  68. package/dist/composites/SectionHeading.js +12 -0
  69. package/dist/composites/SiteFooter.d.ts +18 -0
  70. package/dist/composites/SiteFooter.d.ts.map +1 -0
  71. package/dist/composites/SiteFooter.js +15 -0
  72. package/dist/composites/SiteNav.d.ts +25 -0
  73. package/dist/composites/SiteNav.d.ts.map +1 -0
  74. package/dist/composites/SiteNav.js +44 -0
  75. package/dist/composites/StatCard.d.ts +7 -1
  76. package/dist/composites/StatCard.d.ts.map +1 -1
  77. package/dist/composites/StatCard.js +5 -2
  78. package/dist/composites/StatusDot.d.ts +1 -1
  79. package/dist/composites/Tag.d.ts +11 -0
  80. package/dist/composites/Tag.d.ts.map +1 -0
  81. package/dist/composites/Tag.js +33 -0
  82. package/dist/composites/Wordmark.d.ts +19 -0
  83. package/dist/composites/Wordmark.d.ts.map +1 -0
  84. package/dist/composites/Wordmark.js +15 -0
  85. package/dist/composites/cartesian-charts.d.ts +138 -0
  86. package/dist/composites/cartesian-charts.d.ts.map +1 -0
  87. package/dist/composites/cartesian-charts.js +401 -0
  88. package/dist/composites/chart-composition.d.ts +139 -0
  89. package/dist/composites/chart-composition.d.ts.map +1 -0
  90. package/dist/composites/chart-composition.js +486 -0
  91. package/dist/composites/chart-ui.d.ts +83 -0
  92. package/dist/composites/chart-ui.d.ts.map +1 -0
  93. package/dist/composites/chart-ui.js +108 -0
  94. package/dist/composites/charts-3d.d.ts +37 -0
  95. package/dist/composites/charts-3d.d.ts.map +1 -0
  96. package/dist/composites/charts-3d.js +121 -0
  97. package/dist/composites/flow-charts.d.ts +89 -0
  98. package/dist/composites/flow-charts.d.ts.map +1 -0
  99. package/dist/composites/flow-charts.js +186 -0
  100. package/dist/composites/radial-charts.d.ts +109 -0
  101. package/dist/composites/radial-charts.d.ts.map +1 -0
  102. package/dist/composites/radial-charts.js +176 -0
  103. package/dist/composites/scheduler-ui.d.ts +43 -0
  104. package/dist/composites/scheduler-ui.d.ts.map +1 -0
  105. package/dist/composites/scheduler-ui.js +71 -0
  106. package/dist/index.d.ts +83 -7
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +74 -7
  109. package/dist/lib/chart-export.d.ts +10 -0
  110. package/dist/lib/chart-export.d.ts.map +1 -0
  111. package/dist/lib/chart-export.js +102 -0
  112. package/dist/lib/charts.d.ts +235 -0
  113. package/dist/lib/charts.d.ts.map +1 -0
  114. package/dist/lib/charts.js +744 -0
  115. package/dist/lib/geo.d.ts +39 -0
  116. package/dist/lib/geo.d.ts.map +1 -0
  117. package/dist/lib/geo.js +101 -0
  118. package/dist/lib/iso.d.ts +21 -0
  119. package/dist/lib/iso.d.ts.map +1 -0
  120. package/dist/lib/iso.js +56 -0
  121. package/dist/lib/rrule.d.ts +20 -0
  122. package/dist/lib/rrule.d.ts.map +1 -0
  123. package/dist/lib/rrule.js +236 -0
  124. package/dist/lib/scheduler.d.ts +152 -0
  125. package/dist/lib/scheduler.d.ts.map +1 -0
  126. package/dist/lib/scheduler.js +501 -0
  127. package/dist/lib/webgl-scatter.d.ts +44 -0
  128. package/dist/lib/webgl-scatter.d.ts.map +1 -0
  129. package/dist/lib/webgl-scatter.js +185 -0
  130. package/dist/primitives/Accordion.d.ts +44 -20
  131. package/dist/primitives/Accordion.d.ts.map +1 -1
  132. package/dist/primitives/Accordion.js +82 -22
  133. package/dist/primitives/AppBar.d.ts +13 -0
  134. package/dist/primitives/AppBar.d.ts.map +1 -0
  135. package/dist/primitives/AppBar.js +27 -0
  136. package/dist/primitives/Autocomplete.d.ts +28 -0
  137. package/dist/primitives/Autocomplete.d.ts.map +1 -0
  138. package/dist/primitives/Autocomplete.js +118 -0
  139. package/dist/primitives/Avatar.d.ts +13 -1
  140. package/dist/primitives/Avatar.d.ts.map +1 -1
  141. package/dist/primitives/Avatar.js +17 -2
  142. package/dist/primitives/Backdrop.d.ts +17 -0
  143. package/dist/primitives/Backdrop.d.ts.map +1 -0
  144. package/dist/primitives/Backdrop.js +17 -0
  145. package/dist/primitives/BottomNavigation.d.ts +23 -0
  146. package/dist/primitives/BottomNavigation.d.ts.map +1 -0
  147. package/dist/primitives/BottomNavigation.js +30 -0
  148. package/dist/primitives/Button.d.ts +4 -4
  149. package/dist/primitives/Button.d.ts.map +1 -1
  150. package/dist/primitives/Button.js +2 -0
  151. package/dist/primitives/ButtonBase.d.ts +14 -0
  152. package/dist/primitives/ButtonBase.d.ts.map +1 -0
  153. package/dist/primitives/ButtonBase.js +13 -0
  154. package/dist/primitives/ButtonGroup.d.ts +25 -0
  155. package/dist/primitives/ButtonGroup.d.ts.map +1 -0
  156. package/dist/primitives/ButtonGroup.js +44 -0
  157. package/dist/primitives/CircularProgress.d.ts +16 -0
  158. package/dist/primitives/CircularProgress.d.ts.map +1 -0
  159. package/dist/primitives/CircularProgress.js +17 -0
  160. package/dist/primitives/ClickAwayListener.d.ts +16 -0
  161. package/dist/primitives/ClickAwayListener.d.ts.map +1 -0
  162. package/dist/primitives/ClickAwayListener.js +33 -0
  163. package/dist/primitives/Collapse.d.ts +19 -0
  164. package/dist/primitives/Collapse.d.ts.map +1 -0
  165. package/dist/primitives/Collapse.js +14 -0
  166. package/dist/primitives/Container.d.ts +13 -0
  167. package/dist/primitives/Container.d.ts.map +1 -0
  168. package/dist/primitives/Container.js +26 -0
  169. package/dist/primitives/Fab.d.ts +22 -0
  170. package/dist/primitives/Fab.d.ts.map +1 -0
  171. package/dist/primitives/Fab.js +42 -0
  172. package/dist/primitives/FormControl.d.ts +27 -0
  173. package/dist/primitives/FormControl.d.ts.map +1 -0
  174. package/dist/primitives/FormControl.js +24 -0
  175. package/dist/primitives/FormControlLabel.d.ts +18 -0
  176. package/dist/primitives/FormControlLabel.d.ts.map +1 -0
  177. package/dist/primitives/FormControlLabel.js +19 -0
  178. package/dist/primitives/Grid.d.ts +32 -0
  179. package/dist/primitives/Grid.d.ts.map +1 -0
  180. package/dist/primitives/Grid.js +50 -0
  181. package/dist/primitives/IconButton.d.ts +22 -0
  182. package/dist/primitives/IconButton.d.ts.map +1 -0
  183. package/dist/primitives/IconButton.js +39 -0
  184. package/dist/primitives/ImageList.d.ts +31 -0
  185. package/dist/primitives/ImageList.d.ts.map +1 -0
  186. package/dist/primitives/ImageList.js +33 -0
  187. package/dist/primitives/InputAdornment.d.ts +28 -0
  188. package/dist/primitives/InputAdornment.d.ts.map +1 -0
  189. package/dist/primitives/InputAdornment.js +13 -0
  190. package/dist/primitives/Link.d.ts +17 -0
  191. package/dist/primitives/Link.d.ts.map +1 -0
  192. package/dist/primitives/Link.js +29 -0
  193. package/dist/primitives/List.d.ts +41 -0
  194. package/dist/primitives/List.d.ts.map +1 -0
  195. package/dist/primitives/List.js +22 -0
  196. package/dist/primitives/Masonry.d.ts +14 -0
  197. package/dist/primitives/Masonry.d.ts.map +1 -0
  198. package/dist/primitives/Masonry.js +15 -0
  199. package/dist/primitives/Menu.d.ts +28 -0
  200. package/dist/primitives/Menu.d.ts.map +1 -0
  201. package/dist/primitives/Menu.js +54 -0
  202. package/dist/primitives/MobileStepper.d.ts +15 -0
  203. package/dist/primitives/MobileStepper.d.ts.map +1 -0
  204. package/dist/primitives/MobileStepper.js +8 -0
  205. package/dist/primitives/Modal.d.ts +18 -0
  206. package/dist/primitives/Modal.d.ts.map +1 -0
  207. package/dist/primitives/Modal.js +29 -0
  208. package/dist/primitives/NoSsr.d.ts +15 -0
  209. package/dist/primitives/NoSsr.d.ts.map +1 -0
  210. package/dist/primitives/NoSsr.js +19 -0
  211. package/dist/primitives/Paper.d.ts +22 -0
  212. package/dist/primitives/Paper.d.ts.map +1 -0
  213. package/dist/primitives/Paper.js +33 -0
  214. package/dist/primitives/Progress.d.ts +6 -2
  215. package/dist/primitives/Progress.d.ts.map +1 -1
  216. package/dist/primitives/Progress.js +8 -3
  217. package/dist/primitives/Snackbar.d.ts +23 -0
  218. package/dist/primitives/Snackbar.d.ts.map +1 -0
  219. package/dist/primitives/Snackbar.js +33 -0
  220. package/dist/primitives/SpeedDial.d.ts +26 -0
  221. package/dist/primitives/SpeedDial.d.ts.map +1 -0
  222. package/dist/primitives/SpeedDial.js +26 -0
  223. package/dist/primitives/Stack.d.ts +15 -0
  224. package/dist/primitives/Stack.d.ts.map +1 -0
  225. package/dist/primitives/Stack.js +45 -0
  226. package/dist/primitives/StarRating.d.ts +19 -1
  227. package/dist/primitives/StarRating.d.ts.map +1 -1
  228. package/dist/primitives/StarRating.js +36 -6
  229. package/dist/primitives/Stepper.d.ts +36 -0
  230. package/dist/primitives/Stepper.d.ts.map +1 -0
  231. package/dist/primitives/Stepper.js +53 -0
  232. package/dist/primitives/TablePagination.d.ts +16 -0
  233. package/dist/primitives/TablePagination.d.ts.map +1 -0
  234. package/dist/primitives/TablePagination.js +12 -0
  235. package/dist/primitives/TextField.d.ts +24 -0
  236. package/dist/primitives/TextField.d.ts.map +1 -0
  237. package/dist/primitives/TextField.js +19 -0
  238. package/dist/primitives/TextareaAutosize.d.ts +11 -0
  239. package/dist/primitives/TextareaAutosize.d.ts.map +1 -0
  240. package/dist/primitives/TextareaAutosize.js +26 -0
  241. package/dist/primitives/ToggleButton.d.ts +28 -0
  242. package/dist/primitives/ToggleButton.d.ts.map +1 -0
  243. package/dist/primitives/ToggleButton.js +56 -0
  244. package/dist/primitives/TransferList.d.ts +21 -0
  245. package/dist/primitives/TransferList.d.ts.map +1 -0
  246. package/dist/primitives/TransferList.js +40 -0
  247. package/dist/primitives/Typography.d.ts +23 -0
  248. package/dist/primitives/Typography.d.ts.map +1 -0
  249. package/dist/primitives/Typography.js +69 -0
  250. package/dist/primitives/transitions.d.ts +29 -0
  251. package/dist/primitives/transitions.d.ts.map +1 -0
  252. package/dist/primitives/transitions.js +52 -0
  253. package/package.json +30 -5
  254. package/skills/spatika-ui/SKILL.md +96 -0
  255. package/src/composites/AccentRule.tsx +12 -0
  256. package/src/composites/AvailabilityBadge.tsx +32 -0
  257. package/src/composites/Card.tsx +51 -1
  258. package/src/composites/CareerCard.tsx +111 -0
  259. package/src/composites/ChartDataGrid.test.tsx +57 -0
  260. package/src/composites/ChartDataGrid.tsx +196 -0
  261. package/src/composites/ContactLink.tsx +66 -0
  262. package/src/composites/CoverHero.test.tsx +38 -0
  263. package/src/composites/CoverHero.tsx +29 -22
  264. package/src/composites/DisplayHeading.tsx +27 -0
  265. package/src/composites/EntityMediaCard.test.tsx +58 -0
  266. package/src/composites/EntityMediaCard.tsx +31 -13
  267. package/src/composites/EventCalendar.tsx +928 -0
  268. package/src/composites/EventEditor.tsx +268 -0
  269. package/src/composites/EventTimeline.tsx +357 -0
  270. package/src/composites/FloatChip.tsx +63 -0
  271. package/src/composites/GradientText.tsx +31 -0
  272. package/src/composites/IconTile.tsx +33 -0
  273. package/src/composites/MapChart.test.tsx +39 -0
  274. package/src/composites/MapChart.tsx +130 -0
  275. package/src/composites/MetaChip.tsx +24 -0
  276. package/src/composites/PresenceDot.tsx +42 -0
  277. package/src/composites/ProfileHero.test.tsx +33 -0
  278. package/src/composites/ProfileHero.tsx +96 -79
  279. package/src/composites/ProjectCard.tsx +65 -0
  280. package/src/composites/ScatterWebGL.test.tsx +25 -0
  281. package/src/composites/ScatterWebGL.tsx +79 -0
  282. package/src/composites/SectionHeading.tsx +61 -0
  283. package/src/composites/SiteFooter.test.tsx +37 -0
  284. package/src/composites/SiteFooter.tsx +79 -0
  285. package/src/composites/SiteNav.test.tsx +46 -0
  286. package/src/composites/SiteNav.tsx +150 -0
  287. package/src/composites/StatCard.test.tsx +30 -0
  288. package/src/composites/StatCard.tsx +36 -1
  289. package/src/composites/Tag.tsx +50 -0
  290. package/src/composites/Wordmark.test.tsx +23 -0
  291. package/src/composites/Wordmark.tsx +46 -0
  292. package/src/composites/cartesian-charts.test.tsx +52 -0
  293. package/src/composites/cartesian-charts.tsx +1287 -0
  294. package/src/composites/chart-composition.test.tsx +53 -0
  295. package/src/composites/chart-composition.tsx +898 -0
  296. package/src/composites/chart-ui.tsx +328 -0
  297. package/src/composites/charts-3d.test.tsx +25 -0
  298. package/src/composites/charts-3d.tsx +318 -0
  299. package/src/composites/charts.test.tsx +254 -0
  300. package/src/composites/chrome.test.tsx +29 -0
  301. package/src/composites/flow-charts.test.tsx +79 -0
  302. package/src/composites/flow-charts.tsx +607 -0
  303. package/src/composites/marketing.test.tsx +192 -0
  304. package/src/composites/radial-charts.test.tsx +74 -0
  305. package/src/composites/radial-charts.tsx +617 -0
  306. package/src/composites/scheduler-ui.tsx +304 -0
  307. package/src/composites/scheduler.test.tsx +194 -0
  308. package/src/index.test.ts +22 -0
  309. package/src/index.ts +300 -5
  310. package/src/lib/chart-export.test.ts +20 -0
  311. package/src/lib/chart-export.ts +99 -0
  312. package/src/lib/charts-platform.test.ts +93 -0
  313. package/src/lib/charts.test.ts +132 -0
  314. package/src/lib/charts.ts +1021 -0
  315. package/src/lib/geo.test.ts +42 -0
  316. package/src/lib/geo.ts +138 -0
  317. package/src/lib/iso.test.ts +22 -0
  318. package/src/lib/iso.ts +102 -0
  319. package/src/lib/rrule.test.ts +53 -0
  320. package/src/lib/rrule.ts +281 -0
  321. package/src/lib/scheduler.test.ts +186 -0
  322. package/src/lib/scheduler.ts +688 -0
  323. package/src/lib/tokens.test.ts +2 -2
  324. package/src/lib/webgl-scatter.test.ts +36 -0
  325. package/src/lib/webgl-scatter.ts +230 -0
  326. package/src/primitives/Accordion.tsx +218 -63
  327. package/src/primitives/AppBar.tsx +39 -0
  328. package/src/primitives/Autocomplete.tsx +236 -0
  329. package/src/primitives/Avatar.tsx +52 -1
  330. package/src/primitives/Backdrop.tsx +48 -0
  331. package/src/primitives/BottomNavigation.tsx +102 -0
  332. package/src/primitives/Button.tsx +3 -0
  333. package/src/primitives/ButtonBase.tsx +34 -0
  334. package/src/primitives/ButtonGroup.tsx +90 -0
  335. package/src/primitives/CircularProgress.tsx +104 -0
  336. package/src/primitives/ClickAwayListener.tsx +46 -0
  337. package/src/primitives/Collapse.tsx +39 -0
  338. package/src/primitives/Container.tsx +40 -0
  339. package/src/primitives/Fab.tsx +62 -0
  340. package/src/primitives/FormControl.tsx +90 -0
  341. package/src/primitives/FormControlLabel.tsx +51 -0
  342. package/src/primitives/Grid.tsx +101 -0
  343. package/src/primitives/IconButton.tsx +59 -0
  344. package/src/primitives/ImageList.test.tsx +48 -0
  345. package/src/primitives/ImageList.tsx +112 -0
  346. package/src/primitives/InputAdornment.tsx +86 -0
  347. package/src/primitives/Link.tsx +48 -0
  348. package/src/primitives/List.tsx +121 -0
  349. package/src/primitives/Masonry.tsx +32 -0
  350. package/src/primitives/Menu.tsx +112 -0
  351. package/src/primitives/MobileStepper.tsx +64 -0
  352. package/src/primitives/Modal.tsx +70 -0
  353. package/src/primitives/NoSsr.tsx +28 -0
  354. package/src/primitives/Paper.tsx +55 -0
  355. package/src/primitives/Progress.tsx +25 -7
  356. package/src/primitives/Snackbar.tsx +83 -0
  357. package/src/primitives/SpeedDial.tsx +110 -0
  358. package/src/primitives/Stack.tsx +88 -0
  359. package/src/primitives/StarRating.tsx +87 -28
  360. package/src/primitives/Stepper.tsx +184 -0
  361. package/src/primitives/TablePagination.tsx +58 -0
  362. package/src/primitives/TextField.tsx +105 -0
  363. package/src/primitives/TextareaAutosize.tsx +49 -0
  364. package/src/primitives/ToggleButton.tsx +148 -0
  365. package/src/primitives/TransferList.tsx +110 -0
  366. package/src/primitives/Typography.tsx +90 -0
  367. package/src/primitives/mui-more.test.tsx +76 -0
  368. package/src/primitives/mui.test.tsx +134 -0
  369. package/src/primitives/transitions.tsx +120 -0
@@ -0,0 +1,86 @@
1
+ import * as React from "react";
2
+ import { cn } from "../lib/cn";
3
+ import { Input } from "./Input";
4
+
5
+ export type InputAdornmentProps = React.ComponentPropsWithoutRef<"span"> & {
6
+ position?: "start" | "end";
7
+ };
8
+
9
+ function InputAdornment({
10
+ position = "start",
11
+ className,
12
+ ...props
13
+ }: InputAdornmentProps) {
14
+ return (
15
+ <span
16
+ data-slot="input-adornment"
17
+ data-position={position}
18
+ className={cn(
19
+ "inline-flex shrink-0 items-center text-sm font-medium text-muted-foreground",
20
+ position === "start" ? "pl-1 pr-1.5" : "pl-1.5 pr-1",
21
+ className,
22
+ )}
23
+ {...props}
24
+ />
25
+ );
26
+ }
27
+ InputAdornment.displayName = "InputAdornment";
28
+
29
+ export type OutlinedInputProps = React.ComponentPropsWithoutRef<"input"> & {
30
+ startAdornment?: React.ReactNode;
31
+ endAdornment?: React.ReactNode;
32
+ error?: boolean;
33
+ fullWidth?: boolean;
34
+ };
35
+
36
+ const OutlinedInput = React.forwardRef<HTMLInputElement, OutlinedInputProps>(
37
+ ({ startAdornment, endAdornment, error, fullWidth, className, ...props }, ref) => (
38
+ <div
39
+ data-slot="outlined-input"
40
+ className={cn(
41
+ "flex h-9 items-center rounded-md border border-input bg-input-background px-2",
42
+ "focus-within:border-ring focus-within:ring-ring/50 focus-within:ring-[3px]",
43
+ error && "border-destructive",
44
+ fullWidth && "w-full",
45
+ className,
46
+ )}
47
+ >
48
+ {startAdornment}
49
+ <Input
50
+ ref={ref}
51
+ aria-invalid={error || undefined}
52
+ className="h-full flex-1 border-0 bg-transparent px-1 shadow-none focus-visible:ring-0"
53
+ {...props}
54
+ />
55
+ {endAdornment}
56
+ </div>
57
+ ),
58
+ );
59
+ OutlinedInput.displayName = "OutlinedInput";
60
+
61
+ const FilledInput = React.forwardRef<HTMLInputElement, OutlinedInputProps>(
62
+ ({ startAdornment, endAdornment, error, fullWidth, className, ...props }, ref) => (
63
+ <div
64
+ data-slot="filled-input"
65
+ className={cn(
66
+ "flex h-9 items-center rounded-md border-b border-transparent bg-muted/50 px-2",
67
+ "focus-within:border-primary focus-within:bg-muted/70",
68
+ error && "border-destructive",
69
+ fullWidth && "w-full",
70
+ className,
71
+ )}
72
+ >
73
+ {startAdornment}
74
+ <Input
75
+ ref={ref}
76
+ aria-invalid={error || undefined}
77
+ className="h-full flex-1 border-0 bg-transparent px-1 shadow-none focus-visible:ring-0"
78
+ {...props}
79
+ />
80
+ {endAdornment}
81
+ </div>
82
+ ),
83
+ );
84
+ FilledInput.displayName = "FilledInput";
85
+
86
+ export { InputAdornment, OutlinedInput, FilledInput };
@@ -0,0 +1,48 @@
1
+ import * as React from "react";
2
+ import { cva, type VariantProps } from "class-variance-authority";
3
+ import { Slot } from "../lib/slot";
4
+ import { cn } from "../lib/cn";
5
+
6
+ const linkVariants = cva(
7
+ "inline font-medium underline-offset-4 outline-none transition-colors focus-visible:ring-ring/50 focus-visible:ring-[3px] rounded-sm",
8
+ {
9
+ variants: {
10
+ color: {
11
+ primary: "text-primary hover:text-primary/80",
12
+ inherit: "text-inherit hover:text-primary",
13
+ muted: "text-muted-foreground hover:text-foreground",
14
+ },
15
+ underline: {
16
+ always: "underline",
17
+ hover: "hover:underline",
18
+ none: "no-underline",
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ color: "primary",
23
+ underline: "hover",
24
+ },
25
+ },
26
+ );
27
+
28
+ export type LinkProps = Omit<React.ComponentPropsWithoutRef<"a">, "color"> &
29
+ VariantProps<typeof linkVariants> & {
30
+ asChild?: boolean;
31
+ };
32
+
33
+ const Link = React.forwardRef<HTMLAnchorElement, LinkProps>(
34
+ ({ className, color, underline, asChild = false, ...props }, ref) => {
35
+ const Comp = asChild ? Slot : "a";
36
+ return (
37
+ <Comp
38
+ ref={ref}
39
+ data-slot="link"
40
+ className={cn(linkVariants({ color, underline }), className)}
41
+ {...props}
42
+ />
43
+ );
44
+ },
45
+ );
46
+ Link.displayName = "Link";
47
+
48
+ export { Link, linkVariants };
@@ -0,0 +1,121 @@
1
+ import * as React from "react";
2
+ import { cn } from "../lib/cn";
3
+
4
+ export type ListProps = React.ComponentPropsWithoutRef<"ul"> & {
5
+ dense?: boolean;
6
+ disablePadding?: boolean;
7
+ };
8
+
9
+ const List = React.forwardRef<HTMLUListElement, ListProps>(
10
+ ({ className, dense, disablePadding, ...props }, ref) => (
11
+ <ul
12
+ ref={ref}
13
+ data-slot="list"
14
+ data-dense={dense ? "" : undefined}
15
+ className={cn(
16
+ "m-0 list-none",
17
+ disablePadding ? "p-0" : dense ? "py-1" : "py-2",
18
+ className,
19
+ )}
20
+ {...props}
21
+ />
22
+ ),
23
+ );
24
+ List.displayName = "List";
25
+
26
+ export type ListItemProps = React.ComponentPropsWithoutRef<"li"> & {
27
+ disablePadding?: boolean;
28
+ disableGutters?: boolean;
29
+ };
30
+
31
+ const ListItem = React.forwardRef<HTMLLIElement, ListItemProps>(
32
+ ({ className, disablePadding, disableGutters, ...props }, ref) => (
33
+ <li
34
+ ref={ref}
35
+ data-slot="list-item"
36
+ className={cn(
37
+ "flex items-center gap-3",
38
+ disablePadding ? "p-0" : disableGutters ? "py-2" : "px-4 py-2.5",
39
+ className,
40
+ )}
41
+ {...props}
42
+ />
43
+ ),
44
+ );
45
+ ListItem.displayName = "ListItem";
46
+
47
+ export type ListItemButtonProps = React.ComponentPropsWithoutRef<"button"> & {
48
+ selected?: boolean;
49
+ };
50
+
51
+ const ListItemButton = React.forwardRef<HTMLButtonElement, ListItemButtonProps>(
52
+ ({ className, selected, ...props }, ref) => (
53
+ <button
54
+ ref={ref}
55
+ type="button"
56
+ data-slot="list-item-button"
57
+ data-selected={selected ? "" : undefined}
58
+ className={cn(
59
+ "flex w-full items-center gap-3 px-4 py-2.5 text-left text-sm font-medium outline-none transition-colors",
60
+ "hover:bg-muted/40 focus-visible:ring-ring/50 focus-visible:ring-[3px]",
61
+ selected && "bg-primary/10 text-primary",
62
+ className,
63
+ )}
64
+ {...props}
65
+ />
66
+ ),
67
+ );
68
+ ListItemButton.displayName = "ListItemButton";
69
+
70
+ function ListItemIcon({ className, ...props }: React.ComponentPropsWithoutRef<"span">) {
71
+ return (
72
+ <span
73
+ data-slot="list-item-icon"
74
+ className={cn(
75
+ "inline-flex size-8 shrink-0 items-center justify-center text-muted-foreground [&_svg]:size-4",
76
+ className,
77
+ )}
78
+ {...props}
79
+ />
80
+ );
81
+ }
82
+ ListItemIcon.displayName = "ListItemIcon";
83
+
84
+ export type ListItemTextProps = React.ComponentPropsWithoutRef<"div"> & {
85
+ primary?: React.ReactNode;
86
+ secondary?: React.ReactNode;
87
+ };
88
+
89
+ function ListItemText({
90
+ className,
91
+ primary,
92
+ secondary,
93
+ children,
94
+ ...props
95
+ }: ListItemTextProps) {
96
+ return (
97
+ <div data-slot="list-item-text" className={cn("min-w-0 flex-1", className)} {...props}>
98
+ <div className="truncate text-sm font-semibold">{primary ?? children}</div>
99
+ {secondary ? (
100
+ <div className="truncate text-xs font-medium text-muted-foreground">{secondary}</div>
101
+ ) : null}
102
+ </div>
103
+ );
104
+ }
105
+ ListItemText.displayName = "ListItemText";
106
+
107
+ function ListSubheader({ className, ...props }: React.ComponentPropsWithoutRef<"li">) {
108
+ return (
109
+ <li
110
+ data-slot="list-subheader"
111
+ className={cn(
112
+ "px-4 py-2 text-[10px] font-black uppercase tracking-widest text-muted-foreground",
113
+ className,
114
+ )}
115
+ {...props}
116
+ />
117
+ );
118
+ }
119
+ ListSubheader.displayName = "ListSubheader";
120
+
121
+ export { List, ListItem, ListItemButton, ListItemIcon, ListItemText, ListSubheader };
@@ -0,0 +1,32 @@
1
+ import * as React from "react";
2
+ import { cn } from "../lib/cn";
3
+
4
+ export type MasonryProps = React.ComponentPropsWithoutRef<"div"> & {
5
+ columns?: number;
6
+ spacing?: number;
7
+ };
8
+
9
+ /**
10
+ * CSS multi-column masonry. Children should be block-level items.
11
+ */
12
+ function Masonry({ columns = 3, spacing = 16, className, style, children, ...props }: MasonryProps) {
13
+ return (
14
+ <div
15
+ data-slot="masonry"
16
+ className={cn(className)}
17
+ style={{
18
+ columnCount: columns,
19
+ columnGap: spacing,
20
+ ...style,
21
+ }}
22
+ {...props}
23
+ >
24
+ {React.Children.map(children, (child) => (
25
+ <div className="mb-4 break-inside-avoid">{child}</div>
26
+ ))}
27
+ </div>
28
+ );
29
+ }
30
+ Masonry.displayName = "Masonry";
31
+
32
+ export { Masonry };
@@ -0,0 +1,112 @@
1
+ import * as React from "react";
2
+ import { composeRefs } from "../lib/compose-refs";
3
+ import { Portal } from "../lib/portal";
4
+ import { useControllableState } from "../lib/use-controllable-state";
5
+ import { useDismissable } from "../lib/use-dismissable";
6
+ import { useFloatingPosition } from "../lib/use-floating-position";
7
+ import { cn } from "../lib/cn";
8
+ import { OVERLAY_Z_INDEX } from "../lib/overlay-stack";
9
+
10
+ export type MenuProps = {
11
+ open?: boolean;
12
+ defaultOpen?: boolean;
13
+ onOpenChange?: (open: boolean) => void;
14
+ /** Anchor element — typically the button that opened the menu. */
15
+ anchorEl?: HTMLElement | null;
16
+ children?: React.ReactNode;
17
+ };
18
+
19
+ function Menu({
20
+ open: openProp,
21
+ defaultOpen,
22
+ onOpenChange,
23
+ anchorEl,
24
+ children,
25
+ }: MenuProps) {
26
+ const [open = false, setOpen] = useControllableState({
27
+ prop: openProp,
28
+ defaultProp: defaultOpen ?? false,
29
+ onChange: onOpenChange,
30
+ });
31
+ const triggerRef = React.useRef<HTMLElement | null>(null);
32
+ const contentRef = React.useRef<HTMLDivElement | null>(null);
33
+
34
+ React.useEffect(() => {
35
+ triggerRef.current = anchorEl ?? null;
36
+ }, [anchorEl]);
37
+
38
+ const position = useFloatingPosition({
39
+ open,
40
+ triggerRef,
41
+ contentRef,
42
+ side: "bottom",
43
+ align: "start",
44
+ sideOffset: 4,
45
+ });
46
+
47
+ useDismissable({
48
+ enabled: open,
49
+ onDismiss: () => setOpen(false),
50
+ refs: [triggerRef, contentRef],
51
+ });
52
+
53
+ if (!open) return null;
54
+
55
+ return (
56
+ <Portal>
57
+ <div
58
+ ref={contentRef}
59
+ role="menu"
60
+ data-slot="menu"
61
+ className="glass-menu z-[10000] min-w-40 overflow-hidden rounded-xl border border-border/50 p-1 shadow-xl outline-none"
62
+ style={{
63
+ position: "fixed",
64
+ top: position?.top ?? 0,
65
+ left: position?.left ?? 0,
66
+ zIndex: OVERLAY_Z_INDEX.menu,
67
+ opacity: position ? 1 : 0,
68
+ }}
69
+ >
70
+ {children}
71
+ </div>
72
+ </Portal>
73
+ );
74
+ }
75
+ Menu.displayName = "Menu";
76
+
77
+ function MenuList({ className, ...props }: React.ComponentPropsWithoutRef<"div">) {
78
+ return <div role="menu" data-slot="menu-list" className={cn("flex flex-col p-1", className)} {...props} />;
79
+ }
80
+ MenuList.displayName = "MenuList";
81
+
82
+ export type MenuItemProps = React.ComponentPropsWithoutRef<"button"> & {
83
+ selected?: boolean;
84
+ dense?: boolean;
85
+ };
86
+
87
+ function MenuItem({ className, selected, dense, ...props }: MenuItemProps) {
88
+ return (
89
+ <button
90
+ type="button"
91
+ role="menuitem"
92
+ data-slot="menu-item"
93
+ data-selected={selected ? "" : undefined}
94
+ className={cn(
95
+ "flex w-full items-center gap-2 rounded-lg px-3 text-left text-sm font-medium outline-none",
96
+ dense ? "py-1.5" : "py-2",
97
+ selected ? "bg-primary/10 text-primary" : "hover:bg-muted/50",
98
+ "disabled:pointer-events-none disabled:opacity-40",
99
+ className,
100
+ )}
101
+ {...props}
102
+ />
103
+ );
104
+ }
105
+ MenuItem.displayName = "MenuItem";
106
+
107
+ const MenuAnchor = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithoutRef<"button">>(
108
+ (props, ref) => <button ref={ref} type="button" data-slot="menu-anchor" {...props} />,
109
+ );
110
+ MenuAnchor.displayName = "MenuAnchor";
111
+
112
+ export { Menu, MenuList, MenuItem, MenuAnchor };
@@ -0,0 +1,64 @@
1
+ import * as React from "react";
2
+ import { cn } from "../lib/cn";
3
+ import { LinearProgress } from "./Progress";
4
+
5
+ export type MobileStepperProps = React.ComponentPropsWithoutRef<"div"> & {
6
+ steps: number;
7
+ activeStep?: number;
8
+ position?: "static" | "bottom" | "top";
9
+ variant?: "dots" | "text" | "progress";
10
+ nextButton?: React.ReactNode;
11
+ backButton?: React.ReactNode;
12
+ };
13
+
14
+ function MobileStepper({
15
+ steps,
16
+ activeStep = 0,
17
+ position = "static",
18
+ variant = "dots",
19
+ nextButton,
20
+ backButton,
21
+ className,
22
+ ...props
23
+ }: MobileStepperProps) {
24
+ return (
25
+ <div
26
+ data-slot="mobile-stepper"
27
+ data-position={position}
28
+ className={cn(
29
+ "flex w-full items-center gap-3 rounded-xl border border-border/40 bg-card/40 px-3 py-2",
30
+ position === "bottom" && "sticky bottom-0",
31
+ position === "top" && "sticky top-0",
32
+ className,
33
+ )}
34
+ {...props}
35
+ >
36
+ {backButton}
37
+ <div className="min-w-0 flex-1">
38
+ {variant === "text" ? (
39
+ <p className="text-center text-xs font-bold text-muted-foreground">
40
+ {activeStep + 1} / {steps}
41
+ </p>
42
+ ) : variant === "progress" ? (
43
+ <LinearProgress value={((activeStep + 1) / steps) * 100} />
44
+ ) : (
45
+ <div className="flex items-center justify-center gap-1.5">
46
+ {Array.from({ length: steps }, (_, i) => (
47
+ <span
48
+ key={i}
49
+ className={cn(
50
+ "size-1.5 rounded-full",
51
+ i === activeStep ? "bg-primary" : "bg-border",
52
+ )}
53
+ />
54
+ ))}
55
+ </div>
56
+ )}
57
+ </div>
58
+ {nextButton}
59
+ </div>
60
+ );
61
+ }
62
+ MobileStepper.displayName = "MobileStepper";
63
+
64
+ export { MobileStepper };
@@ -0,0 +1,70 @@
1
+ import * as React from "react";
2
+ import { Portal } from "../lib/portal";
3
+ import { useFocusTrap } from "../lib/use-focus-trap";
4
+ import { cn } from "../lib/cn";
5
+ import { OVERLAY_Z_INDEX, fixedLayerStyle } from "../lib/overlay-stack";
6
+ import { Backdrop } from "./Backdrop";
7
+
8
+ export type ModalProps = Omit<React.ComponentPropsWithoutRef<"div">, "children"> & {
9
+ open?: boolean;
10
+ onClose?: () => void;
11
+ children?: React.ReactNode;
12
+ keepMounted?: boolean;
13
+ disableEscapeKeyDown?: boolean;
14
+ hideBackdrop?: boolean;
15
+ };
16
+
17
+ /**
18
+ * Low-level modal. Prefer Dialog for titled confirmations.
19
+ */
20
+ function Modal({
21
+ open = false,
22
+ onClose,
23
+ children,
24
+ keepMounted,
25
+ disableEscapeKeyDown,
26
+ hideBackdrop,
27
+ className,
28
+ style,
29
+ ...props
30
+ }: ModalProps) {
31
+ const contentRef = React.useRef<HTMLDivElement | null>(null);
32
+ useFocusTrap(contentRef, open);
33
+
34
+ React.useEffect(() => {
35
+ if (!open || disableEscapeKeyDown || !onClose) return;
36
+ const onKey = (event: KeyboardEvent) => {
37
+ if (event.key === "Escape") onClose();
38
+ };
39
+ document.addEventListener("keydown", onKey);
40
+ return () => document.removeEventListener("keydown", onKey);
41
+ }, [open, disableEscapeKeyDown, onClose]);
42
+
43
+ if (!open && !keepMounted) return null;
44
+
45
+ return (
46
+ <Portal>
47
+ <div
48
+ data-slot="modal"
49
+ hidden={!open}
50
+ className={cn("fixed inset-0 flex items-center justify-center p-4", className)}
51
+ style={fixedLayerStyle(OVERLAY_Z_INDEX.modal, style)}
52
+ {...props}
53
+ >
54
+ {hideBackdrop ? null : (
55
+ <Backdrop open={open} contained className="absolute inset-0" onClick={onClose} />
56
+ )}
57
+ <div
58
+ ref={contentRef}
59
+ role="presentation"
60
+ className="relative z-10 outline-none"
61
+ >
62
+ {children}
63
+ </div>
64
+ </div>
65
+ </Portal>
66
+ );
67
+ }
68
+ Modal.displayName = "Modal";
69
+
70
+ export { Modal };
@@ -0,0 +1,28 @@
1
+ import * as React from "react";
2
+
3
+ export type NoSsrProps = {
4
+ children: React.ReactNode;
5
+ fallback?: React.ReactNode;
6
+ defer?: boolean;
7
+ };
8
+
9
+ /**
10
+ * Renders children only after mount — useful for browser-only APIs.
11
+ */
12
+ function NoSsr({ children, fallback = null, defer = false }: NoSsrProps) {
13
+ const [mounted, setMounted] = React.useState(false);
14
+
15
+ React.useEffect(() => {
16
+ if (!defer) {
17
+ setMounted(true);
18
+ return;
19
+ }
20
+ const id = window.requestAnimationFrame(() => setMounted(true));
21
+ return () => window.cancelAnimationFrame(id);
22
+ }, [defer]);
23
+
24
+ return <>{mounted ? children : fallback}</>;
25
+ }
26
+ NoSsr.displayName = "NoSsr";
27
+
28
+ export { NoSsr };
@@ -0,0 +1,55 @@
1
+ import * as React from "react";
2
+ import { cva, type VariantProps } from "class-variance-authority";
3
+ import { cn } from "../lib/cn";
4
+
5
+ const paperVariants = cva("text-card-foreground", {
6
+ variants: {
7
+ variant: {
8
+ elevation: "bg-card/70 shadow-sm",
9
+ outlined: "border border-border/50 bg-card/40",
10
+ glass: "glass",
11
+ },
12
+ square: {
13
+ true: "rounded-none",
14
+ false: "rounded-[var(--radius-card)]",
15
+ },
16
+ },
17
+ defaultVariants: {
18
+ variant: "elevation",
19
+ square: false,
20
+ },
21
+ });
22
+
23
+ export type PaperProps = React.ComponentPropsWithoutRef<"div"> &
24
+ VariantProps<typeof paperVariants> & {
25
+ /** 0–3. Ignored when variant is outlined. */
26
+ elevation?: 0 | 1 | 2 | 3;
27
+ };
28
+
29
+ const elevationClass: Record<NonNullable<PaperProps["elevation"]>, string> = {
30
+ 0: "shadow-none",
31
+ 1: "shadow-sm",
32
+ 2: "shadow-md",
33
+ 3: "shadow-lg",
34
+ };
35
+
36
+ /**
37
+ * Surface primitive. Prefer Card / GlassCard for structured content.
38
+ */
39
+ const Paper = React.forwardRef<HTMLDivElement, PaperProps>(
40
+ ({ className, variant, square, elevation = 1, ...props }, ref) => (
41
+ <div
42
+ ref={ref}
43
+ data-slot="paper"
44
+ className={cn(
45
+ paperVariants({ variant, square }),
46
+ variant !== "outlined" && elevationClass[elevation],
47
+ className,
48
+ )}
49
+ {...props}
50
+ />
51
+ ),
52
+ );
53
+ Paper.displayName = "Paper";
54
+
55
+ export { Paper, paperVariants };
@@ -4,28 +4,46 @@ import { cn } from "../lib/cn";
4
4
  type ProgressProps = React.ComponentPropsWithoutRef<"div"> & {
5
5
  value?: number | null;
6
6
  max?: number;
7
+ variant?: "determinate" | "indeterminate";
7
8
  };
8
9
 
9
- function Progress({ className, value, max = 100, ...props }: ProgressProps) {
10
+ function Progress({
11
+ className,
12
+ value,
13
+ max = 100,
14
+ variant = "determinate",
15
+ ...props
16
+ }: ProgressProps) {
10
17
  const pct = Math.min(100, Math.max(0, ((value || 0) / max) * 100));
18
+ const indeterminate = variant === "indeterminate";
11
19
 
12
20
  return (
13
21
  <div
14
22
  data-slot="progress"
15
23
  role="progressbar"
16
- aria-valuemin={0}
17
- aria-valuemax={max}
18
- aria-valuenow={value ?? undefined}
24
+ aria-valuemin={indeterminate ? undefined : 0}
25
+ aria-valuemax={indeterminate ? undefined : max}
26
+ aria-valuenow={indeterminate ? undefined : (value ?? undefined)}
27
+ aria-label={indeterminate ? "Loading" : undefined}
19
28
  className={cn("bg-primary/20 relative h-2 w-full overflow-hidden rounded-full", className)}
20
29
  {...props}
21
30
  >
22
31
  <div
23
32
  data-slot="progress-indicator"
24
- className="bg-primary h-full w-full flex-1 transition-all"
25
- style={{ transform: `translateX(-${100 - pct}%)` }}
33
+ className={cn(
34
+ "bg-primary h-full",
35
+ indeterminate
36
+ ? "absolute inset-y-0 left-0 w-1/3 animate-progress-indeterminate"
37
+ : "w-full flex-1 transition-transform duration-300",
38
+ )}
39
+ style={indeterminate ? undefined : { transform: `translateX(-${100 - pct}%)` }}
26
40
  />
27
41
  </div>
28
42
  );
29
43
  }
30
44
 
31
- export { Progress };
45
+ /** MUI-compatible alias. */
46
+ const LinearProgress = Progress;
47
+
48
+ export { Progress, LinearProgress };
49
+ export type { ProgressProps };