@recursica/adapter-mui-v7 1.0.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 (389) hide show
  1. package/.storybook/commonArgTypes.ts +148 -0
  2. package/ARCHITECTURE.md +18 -0
  3. package/CHANGELOG.md +582 -0
  4. package/LICENSE +21 -0
  5. package/OVERSTYLING.md +59 -0
  6. package/README.md +70 -0
  7. package/SETUP.md +92 -0
  8. package/USAGE.md +57 -0
  9. package/dist/adapter-mui-v7.cjs +292 -0
  10. package/dist/adapter-mui-v7.cjs.map +1 -0
  11. package/dist/adapter-mui-v7.css +1 -0
  12. package/dist/adapter-mui-v7.js +40757 -0
  13. package/dist/adapter-mui-v7.js.map +1 -0
  14. package/dist/index.d.ts +2350 -0
  15. package/dist/vite.svg +1 -0
  16. package/docs/PHILOSOPHY.md +39 -0
  17. package/llms.txt +76 -0
  18. package/package.json +151 -0
  19. package/recursica_brand.json +2677 -0
  20. package/recursica_tokens.json +799 -0
  21. package/recursica_ui-kit.json +14981 -0
  22. package/recursica_variables_scoped.css +30489 -0
  23. package/src/GlobalExemptions.modules.css +7 -0
  24. package/src/Introduction.stories.tsx +184 -0
  25. package/src/OverStyling.tsx +87 -0
  26. package/src/Version.tsx +37 -0
  27. package/src/components/Accordion/ACCORDION_IMPLEMENTATION_NOTES.md +107 -0
  28. package/src/components/Accordion/Accordion.module.css +362 -0
  29. package/src/components/Accordion/Accordion.stories.tsx +198 -0
  30. package/src/components/Accordion/Accordion.test.tsx +1 -0
  31. package/src/components/Accordion/Accordion.tsx +285 -0
  32. package/src/components/Accordion/USAGE.md +43 -0
  33. package/src/components/Accordion/index.ts +1 -0
  34. package/src/components/AssistiveElement/ASSISTIVEELEMENT_IMPLEMENTATION_NOTES.md +59 -0
  35. package/src/components/AssistiveElement/AssistiveElement.module.css +121 -0
  36. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +68 -0
  37. package/src/components/AssistiveElement/AssistiveElement.test.tsx +1 -0
  38. package/src/components/AssistiveElement/AssistiveElement.tsx +94 -0
  39. package/src/components/AssistiveElement/USAGE.md +36 -0
  40. package/src/components/AssistiveElement/index.ts +1 -0
  41. package/src/components/AutoComplete/AutoComplete.module.css +456 -0
  42. package/src/components/AutoComplete/AutoComplete.stories.tsx +336 -0
  43. package/src/components/AutoComplete/AutoComplete.test.tsx +1 -0
  44. package/src/components/AutoComplete/AutoComplete.tsx +266 -0
  45. package/src/components/AutoComplete/IMPLEMENTATION_NOTES.md +37 -0
  46. package/src/components/AutoComplete/USAGE.md +68 -0
  47. package/src/components/AutoComplete/index.ts +1 -0
  48. package/src/components/Avatar/AVATAR_IMPLEMENTATION_NOTES.md +36 -0
  49. package/src/components/Avatar/Avatar.module.css +336 -0
  50. package/src/components/Avatar/Avatar.stories.tsx +92 -0
  51. package/src/components/Avatar/Avatar.test.tsx +1 -0
  52. package/src/components/Avatar/Avatar.tsx +88 -0
  53. package/src/components/Avatar/USAGE.md +38 -0
  54. package/src/components/Avatar/index.ts +1 -0
  55. package/src/components/Badge/Badge.module.css +115 -0
  56. package/src/components/Badge/Badge.stories.tsx +78 -0
  57. package/src/components/Badge/Badge.test.tsx +1 -0
  58. package/src/components/Badge/Badge.tsx +61 -0
  59. package/src/components/Badge/USAGE.md +40 -0
  60. package/src/components/Badge/index.ts +1 -0
  61. package/src/components/Breadcrumb/BREADCRUMB_IMPLEMENTATION_NOTES.md +51 -0
  62. package/src/components/Breadcrumb/Breadcrumb.module.css +51 -0
  63. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +114 -0
  64. package/src/components/Breadcrumb/Breadcrumb.test.tsx +1 -0
  65. package/src/components/Breadcrumb/Breadcrumb.tsx +70 -0
  66. package/src/components/Breadcrumb/USAGE.md +42 -0
  67. package/src/components/Breadcrumb/index.ts +1 -0
  68. package/src/components/Button/BUTTON_IMPLEMENTATION_NOTES.md +123 -0
  69. package/src/components/Button/Button.module.css +413 -0
  70. package/src/components/Button/Button.stories.tsx +196 -0
  71. package/src/components/Button/Button.styleIsolation.dom.test.tsx +98 -0
  72. package/src/components/Button/Button.tsx +156 -0
  73. package/src/components/Button/USAGE.md +46 -0
  74. package/src/components/Button/index.ts +1 -0
  75. package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +15 -0
  76. package/src/components/Card/Card.module.css +155 -0
  77. package/src/components/Card/Card.stories.tsx +131 -0
  78. package/src/components/Card/Card.test.tsx +1 -0
  79. package/src/components/Card/Card.tsx +202 -0
  80. package/src/components/Card/USAGE.md +57 -0
  81. package/src/components/Card/index.ts +1 -0
  82. package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +14 -0
  83. package/src/components/Checkbox/Checkbox.module.css +286 -0
  84. package/src/components/Checkbox/Checkbox.stories.tsx +97 -0
  85. package/src/components/Checkbox/Checkbox.test.tsx +1 -0
  86. package/src/components/Checkbox/Checkbox.tsx +259 -0
  87. package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
  88. package/src/components/Checkbox/CheckboxGroup.tsx +148 -0
  89. package/src/components/Checkbox/USAGE.md +36 -0
  90. package/src/components/Checkbox/index.ts +6 -0
  91. package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +102 -0
  92. package/src/components/Chip/Chip.module.css +283 -0
  93. package/src/components/Chip/Chip.stories.tsx +154 -0
  94. package/src/components/Chip/Chip.test.tsx +1 -0
  95. package/src/components/Chip/Chip.tsx +168 -0
  96. package/src/components/Chip/USAGE.md +55 -0
  97. package/src/components/Chip/index.ts +1 -0
  98. package/src/components/Container/Container.stories.tsx +118 -0
  99. package/src/components/Container/Container.test.tsx +1 -0
  100. package/src/components/Container/Container.tsx +51 -0
  101. package/src/components/Container/IMPLEMENTATION_NOTES.md +5 -0
  102. package/src/components/Container/USAGE.md +48 -0
  103. package/src/components/Container/index.ts +1 -0
  104. package/src/components/DatePicker/DATEPICKER_IMPLEMENTATION_NOTES.md +29 -0
  105. package/src/components/DatePicker/DatePicker.icons.tsx +35 -0
  106. package/src/components/DatePicker/DatePicker.module.css +464 -0
  107. package/src/components/DatePicker/DatePicker.stories.tsx +163 -0
  108. package/src/components/DatePicker/DatePicker.test.tsx +1 -0
  109. package/src/components/DatePicker/DatePicker.tsx +229 -0
  110. package/src/components/DatePicker/USAGE.md +49 -0
  111. package/src/components/DatePicker/index.ts +1 -0
  112. package/src/components/Dropdown/BareDropdown.tsx +168 -0
  113. package/src/components/Dropdown/DROPDOWN_IMPLEMENTATION_NOTES.md +45 -0
  114. package/src/components/Dropdown/Dropdown.icons.tsx +33 -0
  115. package/src/components/Dropdown/Dropdown.module.css +535 -0
  116. package/src/components/Dropdown/Dropdown.stories.tsx +252 -0
  117. package/src/components/Dropdown/Dropdown.test.tsx +1 -0
  118. package/src/components/Dropdown/Dropdown.tsx +319 -0
  119. package/src/components/Dropdown/USAGE.md +68 -0
  120. package/src/components/Dropdown/index.ts +1 -0
  121. package/src/components/FileInput/FILEINPUT_IMPLEMENTATION_NOTES.md +153 -0
  122. package/src/components/FileInput/FileInput.module.css +268 -0
  123. package/src/components/FileInput/FileInput.stories.tsx +313 -0
  124. package/src/components/FileInput/FileInput.test.tsx +1 -0
  125. package/src/components/FileInput/FileInput.tsx +415 -0
  126. package/src/components/FileInput/USAGE.md +145 -0
  127. package/src/components/FileInput/index.ts +1 -0
  128. package/src/components/FileUpload/FILEUPLOAD_IMPLEMENTATION_NOTES.md +249 -0
  129. package/src/components/FileUpload/FileUpload.module.css +200 -0
  130. package/src/components/FileUpload/FileUpload.stories.tsx +362 -0
  131. package/src/components/FileUpload/FileUpload.test.tsx +1 -0
  132. package/src/components/FileUpload/FileUpload.tsx +352 -0
  133. package/src/components/FileUpload/USAGE.md +199 -0
  134. package/src/components/FileUpload/index.ts +1 -0
  135. package/src/components/Flex/Flex.stories.tsx +128 -0
  136. package/src/components/Flex/Flex.test.tsx +1 -0
  137. package/src/components/Flex/Flex.tsx +89 -0
  138. package/src/components/Flex/USAGE.md +41 -0
  139. package/src/components/Flex/index.ts +1 -0
  140. package/src/components/FormControlLayout/FormControlLayout.module.css +92 -0
  141. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +118 -0
  142. package/src/components/FormControlLayout/FormControlLayout.test.tsx +1 -0
  143. package/src/components/FormControlLayout/FormControlLayout.tsx +72 -0
  144. package/src/components/FormControlLayout/USAGE.md +40 -0
  145. package/src/components/FormControlLayout/index.ts +1 -0
  146. package/src/components/FormControlWrapper/FORMCONTROLWRAPPER_IMPLEMENTATION_NOTES.md +35 -0
  147. package/src/components/FormControlWrapper/FormControlWrapper.module.css +87 -0
  148. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +129 -0
  149. package/src/components/FormControlWrapper/FormControlWrapper.test.tsx +1 -0
  150. package/src/components/FormControlWrapper/FormControlWrapper.tsx +149 -0
  151. package/src/components/FormControlWrapper/USAGE.md +40 -0
  152. package/src/components/FormControlWrapper/index.ts +1 -0
  153. package/src/components/Grid/Grid.module.css +72 -0
  154. package/src/components/Grid/Grid.stories.tsx +161 -0
  155. package/src/components/Grid/Grid.test.tsx +1 -0
  156. package/src/components/Grid/Grid.tsx +155 -0
  157. package/src/components/Grid/IMPLEMENTATION_NOTES.md +24 -0
  158. package/src/components/Grid/USAGE.md +53 -0
  159. package/src/components/Grid/index.ts +1 -0
  160. package/src/components/Group/Group.stories.tsx +120 -0
  161. package/src/components/Group/Group.test.tsx +1 -0
  162. package/src/components/Group/Group.tsx +116 -0
  163. package/src/components/Group/USAGE.md +41 -0
  164. package/src/components/Group/index.ts +1 -0
  165. package/src/components/Heading/Heading.stories.tsx +50 -0
  166. package/src/components/Heading/Heading.test.tsx +1 -0
  167. package/src/components/Heading/Heading.tsx +28 -0
  168. package/src/components/Heading/USAGE.md +36 -0
  169. package/src/components/Heading/index.ts +1 -0
  170. package/src/components/HoverCard/HoverCard.module.css +107 -0
  171. package/src/components/HoverCard/HoverCard.stories.tsx +172 -0
  172. package/src/components/HoverCard/HoverCard.test.tsx +1 -0
  173. package/src/components/HoverCard/HoverCard.tsx +145 -0
  174. package/src/components/HoverCard/USAGE.md +45 -0
  175. package/src/components/HoverCard/index.ts +1 -0
  176. package/src/components/Label/LABEL_IMPLEMENTATION_NOTES.md +27 -0
  177. package/src/components/Label/Label.module.css +169 -0
  178. package/src/components/Label/Label.stories.tsx +131 -0
  179. package/src/components/Label/Label.test.tsx +1 -0
  180. package/src/components/Label/Label.tsx +96 -0
  181. package/src/components/Label/USAGE.md +36 -0
  182. package/src/components/Label/index.ts +1 -0
  183. package/src/components/Layer/USAGE.md +50 -0
  184. package/src/components/Link/LINK_IMPLEMENTATION_NOTES.md +9 -0
  185. package/src/components/Link/Link.module.css +105 -0
  186. package/src/components/Link/Link.stories.tsx +58 -0
  187. package/src/components/Link/Link.test.tsx +1 -0
  188. package/src/components/Link/Link.tsx +45 -0
  189. package/src/components/Link/USAGE.md +40 -0
  190. package/src/components/Link/index.ts +1 -0
  191. package/src/components/Loader/LOADER_IMPLEMENTATION_NOTES.md +25 -0
  192. package/src/components/Loader/Loader.animate.dom.test.tsx +72 -0
  193. package/src/components/Loader/Loader.module.css +175 -0
  194. package/src/components/Loader/Loader.stories.tsx +123 -0
  195. package/src/components/Loader/Loader.test.tsx +1 -0
  196. package/src/components/Loader/Loader.tsx +72 -0
  197. package/src/components/Loader/USAGE.md +42 -0
  198. package/src/components/Loader/index.ts +1 -0
  199. package/src/components/Menu/IMPLEMENTATION_NOTES.md +5 -0
  200. package/src/components/Menu/Menu.module.css +283 -0
  201. package/src/components/Menu/Menu.stories.tsx +405 -0
  202. package/src/components/Menu/Menu.test.tsx +1 -0
  203. package/src/components/Menu/Menu.tsx +103 -0
  204. package/src/components/Menu/USAGE.md +53 -0
  205. package/src/components/Menu/index.ts +1 -0
  206. package/src/components/Modal/MODAL_IMPLEMENTATION_NOTES.md +31 -0
  207. package/src/components/Modal/Modal.module.css +302 -0
  208. package/src/components/Modal/Modal.stories.tsx +105 -0
  209. package/src/components/Modal/Modal.test.tsx +1 -0
  210. package/src/components/Modal/Modal.tsx +231 -0
  211. package/src/components/Modal/USAGE.md +40 -0
  212. package/src/components/Modal/index.ts +1 -0
  213. package/src/components/NumberInput/NUMBER_INPUT_IMPLEMENTATION_NOTES.md +93 -0
  214. package/src/components/NumberInput/NumberInput.module.css +303 -0
  215. package/src/components/NumberInput/NumberInput.stories.tsx +96 -0
  216. package/src/components/NumberInput/NumberInput.test.tsx +1 -0
  217. package/src/components/NumberInput/NumberInput.tsx +273 -0
  218. package/src/components/NumberInput/USAGE.md +36 -0
  219. package/src/components/NumberInput/index.ts +1 -0
  220. package/src/components/Pagination/IMPLEMENTATION_NOTES.md +40 -0
  221. package/src/components/Pagination/Pagination.icons.tsx +66 -0
  222. package/src/components/Pagination/Pagination.module.css +197 -0
  223. package/src/components/Pagination/Pagination.stories.tsx +48 -0
  224. package/src/components/Pagination/Pagination.test.tsx +1 -0
  225. package/src/components/Pagination/Pagination.tsx +123 -0
  226. package/src/components/Pagination/USAGE.md +36 -0
  227. package/src/components/Pagination/index.ts +1 -0
  228. package/src/components/Panel/PANEL_IMPLEMENTATION_NOTES.md +133 -0
  229. package/src/components/Panel/Panel.module.css +231 -0
  230. package/src/components/Panel/Panel.stories.tsx +227 -0
  231. package/src/components/Panel/Panel.test.tsx +1 -0
  232. package/src/components/Panel/Panel.tsx +186 -0
  233. package/src/components/Panel/USAGE.md +46 -0
  234. package/src/components/Panel/index.ts +1 -0
  235. package/src/components/Popover/IMPLEMENTATION_NOTES.md +22 -0
  236. package/src/components/Popover/Popover.module.css +118 -0
  237. package/src/components/Popover/Popover.stories.tsx +133 -0
  238. package/src/components/Popover/Popover.test.tsx +1 -0
  239. package/src/components/Popover/Popover.tsx +267 -0
  240. package/src/components/Popover/USAGE.md +69 -0
  241. package/src/components/Popover/index.ts +1 -0
  242. package/src/components/Radio/RADIO_IMPLEMENTATION_NOTES.md +12 -0
  243. package/src/components/Radio/Radio.module.css +247 -0
  244. package/src/components/Radio/Radio.stories.tsx +93 -0
  245. package/src/components/Radio/Radio.test.tsx +1 -0
  246. package/src/components/Radio/Radio.tsx +223 -0
  247. package/src/components/Radio/RadioGroup.stories.tsx +117 -0
  248. package/src/components/Radio/RadioGroup.tsx +122 -0
  249. package/src/components/Radio/USAGE.md +36 -0
  250. package/src/components/Radio/index.ts +2 -0
  251. package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
  252. package/src/components/ReadOnlyField/ReadOnlyField.module.css +54 -0
  253. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +163 -0
  254. package/src/components/ReadOnlyField/ReadOnlyField.test.tsx +1 -0
  255. package/src/components/ReadOnlyField/ReadOnlyField.tsx +108 -0
  256. package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
  257. package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
  258. package/src/components/ReadOnlyField/USAGE.md +36 -0
  259. package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
  260. package/src/components/ReadOnlyField/index.ts +2 -0
  261. package/src/components/RecursicaThemeProvider/USAGE.md +60 -0
  262. package/src/components/SegmentedControl/IMPLEMENTATION_NOTES.md +14 -0
  263. package/src/components/SegmentedControl/SegmentedControl.module.css +201 -0
  264. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +106 -0
  265. package/src/components/SegmentedControl/SegmentedControl.test.tsx +1 -0
  266. package/src/components/SegmentedControl/SegmentedControl.tsx +149 -0
  267. package/src/components/SegmentedControl/USAGE.md +49 -0
  268. package/src/components/SegmentedControl/index.ts +1 -0
  269. package/src/components/Slider/IMPLEMENTATION_NOTES.md +55 -0
  270. package/src/components/Slider/Slider.module.css +635 -0
  271. package/src/components/Slider/Slider.stories.tsx +282 -0
  272. package/src/components/Slider/Slider.test.tsx +1 -0
  273. package/src/components/Slider/Slider.tsx +435 -0
  274. package/src/components/Slider/USAGE.md +56 -0
  275. package/src/components/Slider/index.ts +1 -0
  276. package/src/components/Stack/Stack.stories.tsx +108 -0
  277. package/src/components/Stack/Stack.test.tsx +1 -0
  278. package/src/components/Stack/Stack.tsx +43 -0
  279. package/src/components/Stack/USAGE.md +41 -0
  280. package/src/components/Stack/index.ts +1 -0
  281. package/src/components/Stepper/IMPLEMENTATION_NOTES.md +120 -0
  282. package/src/components/Stepper/Stepper.module.css +474 -0
  283. package/src/components/Stepper/Stepper.stories.tsx +157 -0
  284. package/src/components/Stepper/Stepper.test.tsx +1 -0
  285. package/src/components/Stepper/Stepper.tsx +240 -0
  286. package/src/components/Stepper/USAGE.md +45 -0
  287. package/src/components/Stepper/index.ts +1 -0
  288. package/src/components/Switch/SWITCH_IMPLEMENTATION_NOTES.md +147 -0
  289. package/src/components/Switch/Switch.module.css +346 -0
  290. package/src/components/Switch/Switch.stories.tsx +114 -0
  291. package/src/components/Switch/Switch.test.tsx +1 -0
  292. package/src/components/Switch/Switch.tsx +294 -0
  293. package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
  294. package/src/components/Switch/SwitchGroup.tsx +156 -0
  295. package/src/components/Switch/USAGE.md +36 -0
  296. package/src/components/Switch/index.ts +2 -0
  297. package/src/components/Table/TABLE_IMPLEMENTATION_NOTES.md +75 -0
  298. package/src/components/Table/Table.module.css +462 -0
  299. package/src/components/Table/Table.stories.tsx +154 -0
  300. package/src/components/Table/Table.test.tsx +1 -0
  301. package/src/components/Table/Table.tsx +250 -0
  302. package/src/components/Table/USAGE.md +90 -0
  303. package/src/components/Table/index.ts +1 -0
  304. package/src/components/Tabs/IMPLEMENTATION_NOTES.md +76 -0
  305. package/src/components/Tabs/Tabs.module.css +801 -0
  306. package/src/components/Tabs/Tabs.stories.tsx +174 -0
  307. package/src/components/Tabs/Tabs.test.tsx +1 -0
  308. package/src/components/Tabs/Tabs.tsx +103 -0
  309. package/src/components/Tabs/USAGE.md +61 -0
  310. package/src/components/Tabs/index.ts +1 -0
  311. package/src/components/Text/TEXT_IMPLEMENTATION_NOTES.md +10 -0
  312. package/src/components/Text/Text.stories.tsx +75 -0
  313. package/src/components/Text/Text.test.tsx +1 -0
  314. package/src/components/Text/Text.tsx +19 -0
  315. package/src/components/Text/USAGE.md +40 -0
  316. package/src/components/Text/index.ts +1 -0
  317. package/src/components/TextArea/TEXTAREA_IMPLEMENTATION_NOTES.md +42 -0
  318. package/src/components/TextArea/TextArea.module.css +203 -0
  319. package/src/components/TextArea/TextArea.stories.tsx +94 -0
  320. package/src/components/TextArea/TextArea.test.tsx +1 -0
  321. package/src/components/TextArea/TextArea.tsx +162 -0
  322. package/src/components/TextArea/USAGE.md +38 -0
  323. package/src/components/TextArea/index.ts +1 -0
  324. package/src/components/TextField/TextField.module.css +271 -0
  325. package/src/components/TextField/TextField.stories.tsx +162 -0
  326. package/src/components/TextField/TextField.test.tsx +1 -0
  327. package/src/components/TextField/TextField.tsx +182 -0
  328. package/src/components/TextField/USAGE.md +38 -0
  329. package/src/components/TextField/index.ts +1 -0
  330. package/src/components/TimePicker/TIMEPICKER_IMPLEMENTATION_NOTES.md +89 -0
  331. package/src/components/TimePicker/TimePicker.module.css +262 -0
  332. package/src/components/TimePicker/TimePicker.stories.tsx +155 -0
  333. package/src/components/TimePicker/TimePicker.test.tsx +1 -0
  334. package/src/components/TimePicker/TimePicker.tsx +277 -0
  335. package/src/components/TimePicker/USAGE.md +61 -0
  336. package/src/components/TimePicker/index.ts +1 -0
  337. package/src/components/Timeline/IMPLEMENTATION_NOTES.md +42 -0
  338. package/src/components/Timeline/Timeline.module.css +363 -0
  339. package/src/components/Timeline/Timeline.stories.tsx +128 -0
  340. package/src/components/Timeline/Timeline.test.tsx +1 -0
  341. package/src/components/Timeline/Timeline.tsx +90 -0
  342. package/src/components/Timeline/TimelineItem.tsx +95 -0
  343. package/src/components/Timeline/USAGE.md +41 -0
  344. package/src/components/Timeline/index.ts +2 -0
  345. package/src/components/Toast/TOAST_IMPLEMENTATION_NOTES.md +37 -0
  346. package/src/components/Toast/Toast.module.css +193 -0
  347. package/src/components/Toast/Toast.stories.tsx +67 -0
  348. package/src/components/Toast/Toast.test.tsx +1 -0
  349. package/src/components/Toast/Toast.tsx +121 -0
  350. package/src/components/Toast/USAGE.md +42 -0
  351. package/src/components/Toast/index.ts +1 -0
  352. package/src/components/Tooltip/Tooltip.module.css +83 -0
  353. package/src/components/Tooltip/Tooltip.stories.tsx +165 -0
  354. package/src/components/Tooltip/Tooltip.test.tsx +1 -0
  355. package/src/components/Tooltip/Tooltip.tsx +78 -0
  356. package/src/components/Tooltip/USAGE.md +40 -0
  357. package/src/components/Tooltip/index.ts +1 -0
  358. package/src/components/TransferList/TRANSFERLIST_IMPLEMENTATION_NOTES.md +140 -0
  359. package/src/components/TransferList/TransferList.module.css +174 -0
  360. package/src/components/TransferList/TransferList.stories.tsx +121 -0
  361. package/src/components/TransferList/TransferList.test.tsx +1 -0
  362. package/src/components/TransferList/TransferList.tsx +419 -0
  363. package/src/components/TransferList/USAGE.md +77 -0
  364. package/src/components/TransferList/index.ts +1 -0
  365. package/src/components/Tree/IMPLEMENTATION_NOTES.md +53 -0
  366. package/src/components/Tree/Tree.module.css +272 -0
  367. package/src/components/Tree/Tree.stories.tsx +104 -0
  368. package/src/components/Tree/Tree.test.tsx +1 -0
  369. package/src/components/Tree/Tree.tsx +298 -0
  370. package/src/components/Tree/USAGE.md +99 -0
  371. package/src/components/Tree/index.ts +1 -0
  372. package/src/components/Typography/TYPOGRAPHY_IMPLEMENTATION_NOTES.md +17 -0
  373. package/src/components/Typography/Typography.module.css +13 -0
  374. package/src/components/Typography/Typography.test.tsx +1 -0
  375. package/src/components/Typography/Typography.tsx +43 -0
  376. package/src/components/Typography/USAGE.md +40 -0
  377. package/src/components/Typography/index.ts +1 -0
  378. package/src/components/index.ts +50 -0
  379. package/src/env.d.ts +7 -0
  380. package/src/index.ts +194 -0
  381. package/src/types/index.ts +9 -0
  382. package/src/types/scss-modules.d.ts +9 -0
  383. package/src/utils/ColorSchemeWrapper.tsx +23 -0
  384. package/src/utils/RequireAccessibleLabel.ts +1 -0
  385. package/src/utils/copyToClipboard.ts +36 -0
  386. package/src/utils/filterStylingProps.test.ts +85 -0
  387. package/src/utils/filterStylingProps.ts +143 -0
  388. package/src/utils/index.ts +1 -0
  389. package/src/utils/renderRichOption.tsx +51 -0
@@ -0,0 +1,45 @@
1
+ import { forwardRef } from "react";
2
+ import { Link as MUILink, type LinkProps as MUILinkProps } from "@mui/material";
3
+ import {
4
+ filterStylingProps,
5
+ type RecursicaOverStyled,
6
+ } from "../../utils/filterStylingProps";
7
+ import styles from "./Link.module.css";
8
+
9
+ import { type RecursicaLinkProps } from "@recursica/adapter-common";
10
+
11
+ export type LinkProps = RecursicaOverStyled<
12
+ Omit<MUILinkProps, "underline"> & RecursicaLinkProps
13
+ >;
14
+
15
+ export const Link = forwardRef<HTMLAnchorElement, LinkProps>(function Link(
16
+ { icon, children, overStyled = false, ...rest },
17
+ ref,
18
+ ) {
19
+ const sanitizedProps = filterStylingProps(rest, overStyled);
20
+ const restRecord = sanitizedProps as Record<string, unknown>;
21
+
22
+ const classNameProp = restRecord.className as string | undefined;
23
+ const finalClass = classNameProp
24
+ ? `${styles.root} ${classNameProp}`
25
+ : styles.root;
26
+
27
+ return (
28
+ <MUILink
29
+ ref={ref}
30
+ className={finalClass}
31
+ underline="none"
32
+ {...(icon ? { "data-has-icon": "" } : {})}
33
+ {...sanitizedProps}
34
+ >
35
+ {icon && (
36
+ <span className={styles.iconWrapper} aria-hidden>
37
+ {icon}
38
+ </span>
39
+ )}
40
+ <span className={styles.labelText}>{children}</span>
41
+ </MUILink>
42
+ );
43
+ });
44
+
45
+ Link.displayName = "Link";
@@ -0,0 +1,40 @@
1
+ # Link - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Link` component in your projects using `@recursica/adapter-mui-v7`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Link } from "@recursica/adapter-mui-v7";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Link } from "@recursica/adapter-mui-v7";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Link href="/dashboard" variant="inline">
24
+ Go to Dashboard
25
+ </Link>
26
+ );
27
+ }
28
+ ```
29
+
30
+ ---
31
+
32
+ ## 3. Design System Integration
33
+
34
+ All Recursica components in the `@recursica/adapter-mui-v7` package adhere strictly to design system spacing, scaling, and behavior patterns.
35
+
36
+ > [!IMPORTANT]
37
+ >
38
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
39
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
40
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
@@ -0,0 +1 @@
1
+ export * from "./Link";
@@ -0,0 +1,25 @@
1
+ # Loader Implementation Notes
2
+
3
+ ## Architecture & Integration
4
+
5
+ The `Loader` component for the MUI adapter has been completely hand-coded from scratch using pure CSS and basic HTML `<span>` elements. It explicitly **does not** use MUI's native `<CircularProgress>` component.
6
+
7
+ This was a deliberate architectural decision to ensure 100% feature and visual parity with the `mantine-adapter`.
8
+
9
+ ### Key Decisions:
10
+
11
+ - **Bypassing Native Components:** MUI's native loaders (like `<CircularProgress>`) are built using complex animated SVGs and only support a circular "oval" shape. Since the Recursica design system mandates `oval`, `bars`, and `dots` variants, relying on MUI's primitives would have forced a fragmented architecture where `oval` used MUI but `bars` and `dots` were hand-coded.
12
+ - **Parity with Mantine:** To guarantee identical animation timing, easing curves, and DOM structures across frameworks, the CSS keyframes and layout strategies used internally by Mantine's `<Loader>` were extracted and directly replicated in this adapter's `Loader.module.css`.
13
+
14
+ ### Token Mapping:
15
+
16
+ Sizes are bound through `data-size` attributes (`sm`, `md`, `lg` parsing to target `<div data-size="small">`, etc.).
17
+
18
+ - **Oval Variant:** Uses a CSS spinning `::after` pseudo-element. To avoid CSS border inheritance bugs when computing tokenized border-widths, a custom `--loader-thickness` CSS variable is used to bridge the token into the spinning element.
19
+ - **Bars & Dots Variants:** Render three internal `<span />` elements sequentially, styled via `Loader.module.css` to handle individual keyframe delays for bouncing or fading animations.
20
+
21
+ ### Color Contrast Rules:
22
+
23
+ Loaders are hardcoded to map to their explicitly defined design tokens (e.g., `--recursica_ui-kit_components_loader_properties_indicator-color`). By default, they do **not** inherit `currentColor`.
24
+
25
+ When injected into components like the `Button` (where contrast issues may arise against solid backgrounds), it is the responsibility of the parent component (e.g., `Button.module.css`) to use contextual CSS overrides to force `--loader-color: currentColor !important` if necessary.
@@ -0,0 +1,72 @@
1
+ import React from "react";
2
+ import { describe, it, expect } from "vitest";
3
+ import { createRoot, type Root } from "react-dom/client";
4
+ import { flushSync } from "react-dom";
5
+ import { Loader } from "./Loader";
6
+
7
+ function mount(node: React.ReactElement): {
8
+ container: HTMLElement;
9
+ root: Root;
10
+ } {
11
+ const container = document.createElement("div");
12
+ document.body.appendChild(container);
13
+ const root = createRoot(container);
14
+ flushSync(() => root.render(node));
15
+ return { container, root };
16
+ }
17
+
18
+ function unmount({ container, root }: { container: HTMLElement; root: Root }) {
19
+ root.unmount();
20
+ container.remove();
21
+ }
22
+
23
+ /**
24
+ * `animate={false}` must deterministically freeze every variant — including
25
+ * the bars'/dots' individually-animated child spans, which the freeze rule
26
+ * can only reach via a descendant selector, not the `data-variant`-scoped
27
+ * rules the size/thickness CSS uses.
28
+ */
29
+ describe("Loader animate prop", () => {
30
+ it.each(["oval", "bars", "dots"] as const)(
31
+ "freezes every animated element for variant=%s when animate is false, and animates by default",
32
+ (variant) => {
33
+ const animated = mount(<Loader variant={variant} />);
34
+ const frozen = mount(<Loader variant={variant} animate={false} />);
35
+
36
+ try {
37
+ const animatedRoot =
38
+ animated.container.querySelector("[data-variant]")!;
39
+ const frozenRoot = frozen.container.querySelector("[data-variant]")!;
40
+
41
+ const animatedTargets = [
42
+ animatedRoot,
43
+ ...Array.from(animatedRoot.querySelectorAll("*")),
44
+ ];
45
+ const frozenTargets = [
46
+ frozenRoot,
47
+ ...Array.from(frozenRoot.querySelectorAll("*")),
48
+ ];
49
+
50
+ // At least one element (or the root's own ::after, for oval) actually
51
+ // animates by default — otherwise this test would trivially pass.
52
+ const hasAnimation = (el: Element, pseudo?: string) =>
53
+ getComputedStyle(el, pseudo).animationName !== "none";
54
+ const animatedHasMotion =
55
+ animatedTargets.some((el) => hasAnimation(el)) ||
56
+ hasAnimation(animatedRoot, "::after");
57
+ expect(animatedHasMotion).toBe(true);
58
+
59
+ // Frozen: nothing animates, root included, pseudo-element included.
60
+ for (const el of frozenTargets) {
61
+ expect(getComputedStyle(el).animationName).toBe("none");
62
+ }
63
+ expect(getComputedStyle(frozenRoot, "::after").animationName).toBe(
64
+ "none",
65
+ );
66
+ } finally {
67
+ unmount(animated);
68
+ unmount(frozen);
69
+ }
70
+ },
71
+ );
72
+ });
@@ -0,0 +1,175 @@
1
+ .root {
2
+ /* Default inheritance mapped from component variables if not explicitly overridden by variants */
3
+ --loader-color: var(
4
+ --recursica_ui-kit_components_loader_properties_indicator-color
5
+ );
6
+ box-sizing: border-box;
7
+ }
8
+ .root * {
9
+ box-sizing: border-box;
10
+ }
11
+
12
+ /* `animate={false}` — freezes every variant's animation (the oval's own
13
+ * spinning ::after, and the bars'/dots' individually-animated child spans)
14
+ * so the loader renders deterministically, e.g. for a visual-regression
15
+ * snapshot that would otherwise diff differently every run. */
16
+ .root[data-animate="false"],
17
+ .root[data-animate="false"] *,
18
+ .root[data-animate="false"]::after {
19
+ animation: none !important;
20
+ }
21
+
22
+ /* data-size mapping */
23
+
24
+ /* SMALL */
25
+ .root[data-size="small"] {
26
+ --loader-size: var(
27
+ --recursica_ui-kit_components_loader_variants_sizes_small_properties_size
28
+ );
29
+ }
30
+ .root[data-size="small"][data-variant="oval"] {
31
+ --loader-thickness: var(
32
+ --recursica_ui-kit_components_loader_variants_sizes_small_properties_thickness-size
33
+ );
34
+ }
35
+ .root[data-size="small"]:not([data-variant="oval"]) span {
36
+ border-radius: var(
37
+ --recursica_ui-kit_components_loader_variants_sizes_small_properties_border-radius
38
+ );
39
+ }
40
+
41
+ /* DEFAULT */
42
+ .root[data-size="default"] {
43
+ --loader-size: var(
44
+ --recursica_ui-kit_components_loader_variants_sizes_default_properties_size
45
+ );
46
+ }
47
+ .root[data-size="default"][data-variant="oval"] {
48
+ --loader-thickness: var(
49
+ --recursica_ui-kit_components_loader_variants_sizes_default_properties_thickness-size
50
+ );
51
+ }
52
+ .root[data-size="default"]:not([data-variant="oval"]) span {
53
+ border-radius: var(
54
+ --recursica_ui-kit_components_loader_variants_sizes_default_properties_border-radius
55
+ );
56
+ }
57
+
58
+ /* LARGE */
59
+ .root[data-size="large"] {
60
+ --loader-size: var(
61
+ --recursica_ui-kit_components_loader_variants_sizes_large_properties_size
62
+ );
63
+ }
64
+ .root[data-size="large"][data-variant="oval"] {
65
+ --loader-thickness: var(
66
+ --recursica_ui-kit_components_loader_variants_sizes_large_properties_thickness-size
67
+ );
68
+ }
69
+ .root[data-size="large"]:not([data-variant="oval"]) span {
70
+ border-radius: var(
71
+ --recursica_ui-kit_components_loader_variants_sizes_large_properties_border-radius
72
+ );
73
+ }
74
+
75
+ /* ----- Oval loader ----- */
76
+ @keyframes oval-spin {
77
+ 0% {
78
+ transform: rotate(0deg);
79
+ }
80
+ 100% {
81
+ transform: rotate(360deg);
82
+ }
83
+ }
84
+
85
+ .root[data-variant="oval"] {
86
+ display: inline-block;
87
+ width: var(--loader-size);
88
+ height: var(--loader-size);
89
+ }
90
+ .root[data-variant="oval"]::after {
91
+ content: "";
92
+ display: block;
93
+ width: var(--loader-size);
94
+ height: var(--loader-size);
95
+ border-radius: 10000px;
96
+ border-width: var(--loader-thickness);
97
+ border-style: solid;
98
+ border-color: var(--loader-color) var(--loader-color) var(--loader-color)
99
+ transparent;
100
+ animation: oval-spin 1.2s linear infinite;
101
+ }
102
+
103
+ /* ----- Bars loader ----- */
104
+ @keyframes bars-bounce {
105
+ 0% {
106
+ transform: scale(0.6);
107
+ opacity: 0;
108
+ }
109
+ 50%,
110
+ 100% {
111
+ transform: scale(1);
112
+ opacity: 1;
113
+ }
114
+ }
115
+
116
+ .root[data-variant="bars"] {
117
+ position: relative;
118
+ width: var(--loader-size);
119
+ height: var(--loader-size);
120
+ display: flex;
121
+ align-items: center;
122
+ justify-content: center;
123
+ gap: calc(var(--loader-size) / 5);
124
+ }
125
+
126
+ .root[data-variant="bars"] span {
127
+ flex: 1;
128
+ height: 100%;
129
+ background: var(--loader-color);
130
+ animation: bars-bounce 1.2s cubic-bezier(0, 0.5, 0.5, 1) infinite;
131
+ }
132
+
133
+ .root[data-variant="bars"] span:nth-of-type(1) {
134
+ animation-delay: -240ms;
135
+ }
136
+ .root[data-variant="bars"] span:nth-of-type(2) {
137
+ animation-delay: -120ms;
138
+ }
139
+ .root[data-variant="bars"] span:nth-of-type(3) {
140
+ animation-delay: 0;
141
+ }
142
+
143
+ /* ----- Dots loader ----- */
144
+ @keyframes dots-pulse {
145
+ 0%,
146
+ 100% {
147
+ transform: scale(1);
148
+ opacity: 1;
149
+ }
150
+ 50% {
151
+ transform: scale(0.6);
152
+ opacity: 0.5;
153
+ }
154
+ }
155
+
156
+ .root[data-variant="dots"] {
157
+ display: flex;
158
+ justify-content: center;
159
+ align-items: center;
160
+ gap: calc(var(--loader-size) / 10);
161
+ position: relative;
162
+ width: var(--loader-size);
163
+ height: var(--loader-size);
164
+ }
165
+
166
+ .root[data-variant="dots"] span {
167
+ width: calc(var(--loader-size) / 3 - var(--loader-size) / 15);
168
+ height: calc(var(--loader-size) / 3 - var(--loader-size) / 15);
169
+ background: var(--loader-color);
170
+ animation: dots-pulse 0.8s infinite linear;
171
+ }
172
+
173
+ .root[data-variant="dots"] span:nth-child(2) {
174
+ animation-delay: 0.4s;
175
+ }
@@ -0,0 +1,123 @@
1
+ import React from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import { Loader } from "./Loader";
4
+ import { Layer } from "@recursica/adapter-common";
5
+
6
+ type LoaderStoryArgs = React.ComponentProps<typeof Loader> & {
7
+ layer?: 0 | 1 | 2 | 3;
8
+ };
9
+
10
+ const meta: Meta<LoaderStoryArgs> = {
11
+ title: "UI-Kit/Loader",
12
+ component: Loader as React.ComponentType<LoaderStoryArgs>,
13
+ tags: ["autodocs"],
14
+ parameters: {
15
+ docs: {
16
+ description: {
17
+ component:
18
+ "The Loader bridges the Recursica UI-Kit `loader` variables to the generic primitive, rendering deterministic sizes and variants visually mapped strictly from the explicit design boundary tokens.",
19
+ },
20
+ },
21
+ },
22
+ argTypes: {
23
+ variant: {
24
+ control: "select",
25
+ options: ["oval", "bars", "dots"],
26
+ description: "The structural layout variant of the loading indicator",
27
+ },
28
+ size: {
29
+ control: "select",
30
+ options: ["sm", "md", "lg", "small", "default", "large"],
31
+ description:
32
+ "Scales the dimensional and thickness layout constrained to the explicit UI variables",
33
+ },
34
+ color: {
35
+ control: "color",
36
+ description:
37
+ "Optional inline dynamic color override spanning the token defaults",
38
+ },
39
+ layer: {
40
+ control: { type: "range", min: 0, max: 3, step: 1 },
41
+ description:
42
+ "Applies a wrapping context to observe rendering logic externally",
43
+ },
44
+ animate: {
45
+ control: "boolean",
46
+ description:
47
+ "Freezes the CSS animation when false — deterministic, for visual regression",
48
+ },
49
+ },
50
+ };
51
+
52
+ export default meta;
53
+
54
+ type Story = StoryObj<LoaderStoryArgs>;
55
+
56
+ /**
57
+ * Animated — excluded from visual regression (`adapter-tester.config.json`),
58
+ * since a moving animation diffs differently every run. See the `Static*`
59
+ * stories below for the deterministic, visual-regression-covered equivalents.
60
+ */
61
+ export const Default: Story = {
62
+ args: {
63
+ variant: "oval",
64
+ size: "default",
65
+ layer: 0,
66
+ },
67
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
68
+ render: ({ withLayer, layer, ...args }: any) => (
69
+ <Layer layer={layer ?? 0} style={{ padding: "24px" }}>
70
+ <Loader {...args} />
71
+ </Layer>
72
+ ),
73
+ };
74
+
75
+ /** `animate: false` freezes the spin — deterministic for visual regression. */
76
+ export const StaticOvalDefault: Story = {
77
+ args: {
78
+ variant: "oval",
79
+ size: "default",
80
+ animate: false,
81
+ },
82
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
83
+ render: ({ withLayer, layer, ...args }: any) => <Loader {...args} />,
84
+ };
85
+
86
+ /** `animate: false` freezes the bars — deterministic for visual regression. */
87
+ export const StaticBarsLarge: Story = {
88
+ args: {
89
+ variant: "bars",
90
+ size: "large",
91
+ animate: false,
92
+ },
93
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
94
+ render: ({ withLayer, layer, ...args }: any) => <Loader {...args} />,
95
+ };
96
+
97
+ /** `animate: false` freezes the dots — deterministic for visual regression. */
98
+ export const StaticDotsSmall: Story = {
99
+ args: {
100
+ variant: "dots",
101
+ size: "sm",
102
+ animate: false,
103
+ },
104
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
105
+ render: ({ withLayer, layer, ...args }: any) => <Loader {...args} />,
106
+ };
107
+
108
+ /**
109
+ * Animated — excluded from visual regression, same as `Default`; this one
110
+ * additionally demonstrates rendering inside a `layer={2}` context.
111
+ */
112
+ export const LayerTwoOval: Story = {
113
+ args: {
114
+ variant: "oval",
115
+ size: "default",
116
+ },
117
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
118
+ render: ({ withLayer, layer, ...args }: any) => (
119
+ <Layer layer={2} style={{ padding: "24px" }}>
120
+ <Loader {...args} />
121
+ </Layer>
122
+ ),
123
+ };
@@ -0,0 +1 @@
1
+ // Placeholder for future Loader component tests. Add tests here if/when needed.
@@ -0,0 +1,72 @@
1
+ import React, { forwardRef } from "react";
2
+ import {
3
+ filterStylingProps,
4
+ type RecursicaOverStyled,
5
+ } from "../../utils/filterStylingProps";
6
+ import styles from "./Loader.module.css";
7
+
8
+ import { type RecursicaLoaderProps } from "@recursica/adapter-common";
9
+
10
+ export type LoaderProps = RecursicaOverStyled<
11
+ React.HTMLAttributes<HTMLSpanElement> & RecursicaLoaderProps
12
+ >;
13
+
14
+ export const Loader = forwardRef<HTMLSpanElement, LoaderProps>(function Loader(
15
+ {
16
+ variant = "oval",
17
+ size = "default",
18
+ animate = true,
19
+ overStyled = false,
20
+ ...rest
21
+ },
22
+ ref,
23
+ ) {
24
+ const mapSize = {
25
+ sm: "small",
26
+ md: "default",
27
+ lg: "large",
28
+ small: "small",
29
+ default: "default",
30
+ large: "large",
31
+ } as const;
32
+
33
+ const resolvedSize = mapSize[size] || "default";
34
+
35
+ // Strip all visual override injections unless developer has specifically opted into overStyling.
36
+ // External layout props like margins are safely preserved.
37
+ const sanitizedProps = filterStylingProps(rest, overStyled);
38
+
39
+ const classNameProp = (sanitizedProps as Record<string, unknown>)
40
+ .className as string | undefined;
41
+ const finalClass = classNameProp
42
+ ? `${styles.root} ${classNameProp}`
43
+ : styles.root;
44
+
45
+ const renderChildren = () => {
46
+ if (variant === "bars" || variant === "dots") {
47
+ return (
48
+ <>
49
+ <span />
50
+ <span />
51
+ <span />
52
+ </>
53
+ );
54
+ }
55
+ return null; // Oval is handled purely via CSS ::after
56
+ };
57
+
58
+ return (
59
+ <span
60
+ ref={ref}
61
+ data-variant={variant}
62
+ data-size={resolvedSize}
63
+ data-animate={animate}
64
+ {...sanitizedProps}
65
+ className={finalClass}
66
+ >
67
+ {renderChildren()}
68
+ </span>
69
+ );
70
+ });
71
+
72
+ Loader.displayName = "Loader";
@@ -0,0 +1,42 @@
1
+ # Loader - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Loader` component in your projects using `@recursica/adapter-mui-v7`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Loader } from "@recursica/adapter-mui-v7";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Loader } from "@recursica/adapter-mui-v7";
20
+
21
+ export default function Demo() {
22
+ return <Loader size="md" />;
23
+ }
24
+ ```
25
+
26
+ ---
27
+
28
+ ## 3. Design System Integration
29
+
30
+ All Recursica components in the `@recursica/adapter-mui-v7` package adhere strictly to design system spacing, scaling, and behavior patterns.
31
+
32
+ > [!IMPORTANT]
33
+ >
34
+ > - **Anti-override protection**: Rogues style injections (like inline `style` or arbitrary `className`) are automatically blocked by our prop layer unless `overStyled={true}` is explicitly provided.
35
+ > - **No Direct Layers**: Do not pass a `layer` prop to this component. To place it on a specific visual layer, wrap it in a `<Layer layer={0|1|2|3}>` component natively.
36
+ > - **Variables and Theming**: Styling is entirely determined by local CSS variables defined in `recursica_variables_scoped.css` and mapped in the component's CSS module.
37
+
38
+ ---
39
+
40
+ ## 4. Key Integration Features & Constraints
41
+
42
+ Loader colors are determined by their own design tokens by default and do not automatically inherit `currentColor` from a parent component, which can occasionally affect contrast when a loader is placed on a colored background.
@@ -0,0 +1 @@
1
+ export * from "./Loader";
@@ -0,0 +1,5 @@
1
+ # Menu Implementation Notes
2
+
3
+ - **Compositional API Dropped:** Mantine uses `<Menu.Target>`, `<Menu.Dropdown>`, `<Menu.Item>`, etc., and manages state natively via React context within `<Menu>`. MUI's API is fully monolithic.
4
+ - **Monolithic API Adopted:** Following architectural review, we have abandoned the fabricated context wrappers for `adapter-mui-v7`. We now natively export `Menu`, `MenuItem`, and `MenuDivider` wrapping their `@mui/material` counterparts. Developers are expected to manage `anchorEl` state themselves, just like native MUI. Storybook tests have been updated to simulate this open state so visual regressions still cover the dropdown menu visually.
5
+ - **`maxHeight` Override:** `<Menu maxHeight={...}>` overrides the token-driven dropdown max-height with an explicit pixel (or other CSS length) value — the one deliberate exception to "no inline design tokens in TSX" (see `COMPONENT_DEV_GUIDE.md`). Implemented by merging `maxHeight` into `slotProps.paper.style`, alongside any caller-supplied `slotProps`, rather than a CSS module change; the CSS module's token-driven `max-height` stays untouched when the prop isn't passed.