@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,123 @@
1
+ # Button Component Implementation Notes
2
+
3
+ **Implementation Philosophy:**
4
+ The Button component serves as a foundational building block in Recursica. This implementation wraps the `@mui/material/Button` component but **disables its native visual heuristics entirely.**
5
+
6
+ We explicitly pass `disableRipple` and `disableElevation` to block MUI's dynamic behaviors. Furthermore, we intentionally **do not** map our `variant` or `size` properties to MUI's native `variant` or `size` props because doing so would trigger MUI's internal CSS engines to inject styles that clash with our strict design tokens.
7
+
8
+ **Styling Strategy:**
9
+
10
+ - We utilize `filterStylingProps` to prevent rogue injections of `sx`, `style`, or `className` properties that would violate the design system.
11
+ - All styling is controlled directly via CSS Modules, mapping DOM attributes like `data-variant` and `data-size` to pure CSS selectors.
12
+ - Hover states are managed with a standard `::after` pseudo-element overlay hack rather than relying on native hover psuedo-selectors modifying background-color directly. This allows a clean `opacity` overlay based on the provided design tokens, which guarantees identical visual feedback behavior across all underlying themes without overriding background hues manually.
13
+ - The polymorphic `component` prop natively supported by MUI is safely forwarded to allow correct semantics (e.g. rendering as an `<a>` tag or using a router `Link`).
14
+
15
+ **Accessibility:**
16
+
17
+ - We inject a development-time warning explicitly requiring `aria-label` when the component detects an icon-only configuration.
18
+
19
+ ---
20
+
21
+ ## Loader color contrast — fixed (source-of-truth audit, 2026-08-30)
22
+
23
+ **Superseded:** the entry below originally documented an explicit decision _not_ to fix this.
24
+ Re-verified during the mantine-vs-mui source-of-truth audit: mantine's own loader ring was
25
+ measured (via computed styles) rendering `#c21b43` (the Loader's standalone `indicator-color`
26
+ token) against a label text color of `rgb(249, 249, 249)` — a real, confirmed contrast mismatch,
27
+ not a false report. Fixed in both adapters; see mantine-adapter's own `IMPLEMENTATION_NOTES.md`
28
+ for the equivalent fix there.
29
+
30
+ **Original problem:** `Loader.module.css`'s `.root` unconditionally sets
31
+ `--loader-color: var(--recursica_..._loader_properties_indicator-color)` on its own root
32
+ element, regardless of context — so nesting a `<Loader>` inside a Button's loading state always
33
+ used the Loader's own standalone token, never the button's actual per-variant text color.
34
+
35
+ **Fix:** `Button.module.css` now exposes `--button-color` per variant (solid/outline/text),
36
+ set to that variant's own `colors_text-color` token. The Button-owned `<Loader>` instance passed
37
+ to MUI's `loadingIndicator` prop is now given `overStyled` + `style={{ "--loader-color":
38
+ "var(--button-color)" }}` — an inline style on the Loader's own root, which (being inline) beats
39
+ the stylesheet default and inherits whatever `--button-color` resolves to at that point in the
40
+ DOM. `overStyled` is required to let `style` through `filterStylingProps`; this is a fully
41
+ internal composition (no prop threading to callers), so it doesn't widen Loader's public API.
42
+
43
+ **Also fixed alongside this:** the loading state previously rendered the label text at full
44
+ opacity _and_ injected a second, redundant Loader into `startIcon` (on top of MUI's own native
45
+ `loadingIndicator`/`loadingWrapper` slot) — so loading buttons showed both the label and two
46
+ overlapping loaders instead of just one centered loader. Removed the `startIcon` loader override
47
+ (startIcon now only ever shows the real `icon` prop, exactly as in the non-loading case) and
48
+ added `.root[data-loading="true"] .labelText, .root[data-loading="true"] .iconWrapper { opacity:
49
+ 0; }` so the label/icon stay in the DOM/layout (matching mantine's own `opacity: 0` approach,
50
+ not `display: none`) while only MUI's native centered `loadingIndicator` is visible. Verified
51
+ live against mantine's `ui-kit-button--loading` story — now pixel-equivalent.
52
+
53
+ ---
54
+
55
+ ## Loader color contrast (original entry, see "fixed" above)
56
+
57
+ **Decision:** When a Button is in a loading state, the `Recursica Loader` component is injected via the `loadingIndicator` prop. The `Loader` component strictly defines its own colors and styles per variant, meaning it does not automatically inherit the text color (`currentColor`) from the Button.
58
+
59
+ **Constraint:** This can lead to contrast issues (e.g., a blue dots loader inside a solid blue button). Design has explicitly decided not to address this at the moment. As such, developers using the `loading` prop must be aware that the loader's color is fixed by its internal tokens, not by the button's context.
60
+
61
+ ---
62
+
63
+ ## Loading state enforces disabled state
64
+
65
+ **Decision:** When `loading={true}` is passed to the Button, the component explicitly forces `disabled={true}` natively on the underlying element.
66
+
67
+ **Implementation:** This ensures that loading buttons automatically inherit the brand theme disabled opacities (via the `:disabled` CSS pseudo-class) rather than relying solely on MUI's internal loading opacity adjustments.
68
+
69
+ ---
70
+
71
+ ## `className` overwrite bug (Matt Massey, 2026-08-08)
72
+
73
+ **Bug:** with `overStyled` and a custom `className` (e.g. Tree embedding a `Button` for its expand chevron), the component's own `styles.root` class silently disappeared from the rendered `<button>` — every `[data-variant]`/`[data-size]` CSS rule stopped applying, and MUI's own default styling (including its default blue "primary" color) showed through instead.
74
+
75
+ **Root cause:** `className={finalClass}` (`` `${styles.root} ${classNameProp}` ``) was set explicitly on `<MuiButton>`, but `{...sanitizedProps}` was spread _after_ it — and `sanitizedProps` still contained the original, unmodified `className` key, since it had only been _read_ to compute `finalClass`, never deleted. The later spread silently overwrote the merged class with just the caller's own class. Same bug class as `Dropdown.tsx`/`BareDropdown.tsx` had.
76
+
77
+ **Fix:** delete `className` from the sanitized props record right after reading it, before it reaches the JSX spread. mantine-adapter's `Button.tsx` had the identical mistake — masked there by a separate `classNames={{root: ...}}` object prop unaffected by the bug, but fixed there too for correctness.
78
+
79
+ ---
80
+
81
+ ## `.MuiButton-startIcon`/`.MuiButton-endIcon` selectors never matched anything (Matt Massey, 2026-08-10)
82
+
83
+ **Bug:** icon-only buttons rendered with the icon visibly off-center — shifted left, with extra empty space on the right. Not a regression from any recent change; `Button.module.css` itself was untouched, and the same unwrapped selectors already existed at `HEAD`. It had just gone unnoticed until the Tree work put an icon-only Button (the chevron) under closer visual scrutiny next to Mantine's (correctly centered) version.
84
+
85
+ **Root cause:** `.MuiButton-startIcon`/`.MuiButton-endIcon` are real global class names MUI's `Button` applies directly in the DOM — not local CSS Modules classes generated from this file. Referencing them as plain `.MuiButton-startIcon` (rather than `:global(.MuiButton-startIcon)`, the pattern already used correctly for `.Mui-disabled` elsewhere in this same file) meant Vite's CSS Modules silently hashed them into scoped names — `.Button-module__MuiButton-startIcon___<hash>` — that never matched anything real in the DOM. Every rule targeting them (the icon↔label gap margin, and the icon-only margin reset) was a total no-op; icon-only buttons were left with MUI's own unreset default `margin-right` on the icon, which is what visibly pushed the icon off-center.
86
+
87
+ **Fix:** wrapped every `.MuiButton-startIcon`/`.MuiButton-endIcon` reference in `:global(...)`.
88
+
89
+ **Not otherwise fixed, flagged separately:** the same unwrapped-global-class pattern shows up in at least `Stepper.module.css` (`.Mui-active`/`.Mui-completed`/`.MuiStepLabel-root`, fully unwrapped) and `SegmentedControl.module.css`, and partially in `Label.module.css`/`Accordion.module.css` — meaning some of those components' MUI-state-driven styling may also be silently no-op'ing. Out of scope for this fix (Button only, per what was asked); worth a dedicated sweep.
90
+
91
+ ---
92
+
93
+ ## `line-height` wiring gap vs Mantine (Matt Massey, 2026-08-19)
94
+
95
+ **Reported symptom:** descenders on letters like "p"/"g" clipped in the Default story.
96
+
97
+ **Investigation:** live-verified both adapters in Storybook (Playwright) at the `Default` and `OutlineSmall` stories, including a direct canvas `measureText` check of the `gpqjy` glyph set in Lexend at 14px (`--recursica_tokens_font_line-heights_default: 1.05em` → 14.7px line box vs ~14.0px actual glyph ink) — no visible clipping reproduced in Chromium; both adapters rendered pixel-identical crops. The line-height token itself is objectively tight (near-zero headroom), but that's shared by both adapters and isn't itself mui-specific.
98
+
99
+ **Real discrepancy found:** `.root`'s "Shared Defaults" set `line-height` once, unconditionally, from the _default_-size token, and `.labelText` merely did `line-height: inherit` — so the small-size line-height token was never actually referenced (it was `recursica-ignore`d as "redundant"). Mantine's `Button.module.css`, by contrast, sets `line-height` directly on `.labelText` per size, from each size's own token. They currently resolve to the same literal value, so this wasn't visually observable, but it's a latent divergence from the source of truth — a future token change to the small-size line-height would silently not apply in adapter-mui-v7.
100
+
101
+ **Fix:** moved `line-height` off `.root` and onto `.labelText` (default token), added `.root[data-size="small"] .labelText { line-height: ... }` (small token), and removed the now-inaccurate `recursica-ignore` for that token — matching Mantine's structure exactly.
102
+
103
+ ---
104
+
105
+ ## Button doesn't shrink inside a constraining container (Genesis, 2026-08-27)
106
+
107
+ **Bug:** in the `TruncatedLabel` story (`<div style={{ maxWidth: 250 }}><Button>...long label.../Button></div>`), the button ignored the 250px wrapper entirely and rendered at its full 534px intrinsic width, overflowing the wrapper instead of shrinking and showing the ellipsis.
108
+
109
+ **Root cause:** `.root` has `width: fit-content` (to hug its own content instead of stretching in flex columns) but no `max-width`. Verified via Playwright: the wrapper measured exactly 250px, but `fit-content` on `.root` still resolved to its 534px `max-content` size — it doesn't reliably clamp against a narrower containing block on its own. Same root cause and identical fix in mantine-adapter.
110
+
111
+ **Fix:** added `max-width: 100%` to `.root`. It's a no-op when the parent is wide enough (confirmed no change to `Default`/`IconOnly`/`TextWithIcon` story widths), and clamps the button to the parent's resolved width when the parent is narrower — at which point the existing `overflow: hidden` (`.root`) + `text-overflow: ellipsis`/`white-space: nowrap` (`.labelText`) take over, exactly as already documented above.
112
+
113
+ ---
114
+
115
+ ## `.labelText` descender clipping (Matt Massey, 2026-08-28)
116
+
117
+ `.labelText` used plain `overflow: hidden` to make `text-overflow: ellipsis` work, which also
118
+ clips descenders (e.g. the "g" in a long label) whenever `text_line-height` is tighter than the
119
+ font's natural ascent+descent. Switched to `overflow: clip; overflow-clip-margin: 0.35em;` — same
120
+ truncation, but ink can bleed slightly past the line box before it's actually clipped. `.root`'s
121
+ own `overflow: hidden` (the max-width truncation bounding box, above) is untouched — it has
122
+ padding around the label so it isn't tight against the glyphs the way `.labelText` is.
123
+ Project-wide fix; see Chip's `CHIP_IMPLEMENTATION_NOTES.md` for the original discovery.
@@ -0,0 +1,413 @@
1
+ /* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
2
+ * Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
3
+ * recursica-allow-brand: --recursica_brand_states_focus_blur
4
+ * recursica-allow-brand: --recursica_brand_states_focus_border-size
5
+ * recursica-allow-brand: --recursica_brand_states_focus_color
6
+ * recursica-allow-brand: --recursica_brand_states_focus_margin
7
+ * recursica-allow-brand: --recursica_brand_states_hover_color
8
+ * recursica-allow-brand: --recursica_brand_states_hover_opacity
9
+ */
10
+
11
+ /* Baseline and Reset */
12
+ .root {
13
+ box-sizing: border-box;
14
+ margin: 0;
15
+ border-style: solid;
16
+ overflow: hidden; /* Truncation bounding box */
17
+ position: relative;
18
+ transition: all 0.2s ease;
19
+ width: fit-content; /* Prevent stretching in flex columns */
20
+ max-width: 100%; /* Let a constraining parent (e.g. max-width container) actually shrink the button; fit-content alone ignores it */
21
+
22
+ /* Shared Defaults */
23
+ font-family: var(
24
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-family
25
+ );
26
+ font-size: var(
27
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-size
28
+ );
29
+ font-style: var(
30
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-style
31
+ );
32
+ font-weight: var(
33
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_font-weight
34
+ );
35
+ letter-spacing: var(
36
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_letter-spacing
37
+ );
38
+ text-decoration: var(
39
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_text-decoration
40
+ );
41
+ text-transform: var(
42
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_text-transform
43
+ );
44
+ }
45
+
46
+ /* Reset MUI native properties */
47
+ .root {
48
+ text-transform: none;
49
+ min-width: 0;
50
+ color: inherit;
51
+ background-color: transparent;
52
+ }
53
+
54
+ /* Internal layout logic for Truncation */
55
+ .root > *:not(:global(.MuiButton-loadingIndicator)) {
56
+ min-width: 0;
57
+ position: relative;
58
+ z-index: 1;
59
+ }
60
+
61
+ .label {
62
+ display: flex;
63
+ align-items: center;
64
+ min-width: 0;
65
+ flex: 1 1 0;
66
+ }
67
+
68
+ .labelText {
69
+ display: block;
70
+ min-width: 0;
71
+ overflow: clip; /* HARDCODE: `hidden` clips descenders (e.g. "g") when text_line-height is
72
+ tighter than the font's natural ascent+descent; overflow-clip-margin gives ink a small bleed
73
+ allowance while still clipping genuinely overflowing text (see Chip's IMPLEMENTATION_NOTES.md). */
74
+ overflow-clip-margin: 0.35em;
75
+ text-overflow: ellipsis;
76
+ white-space: nowrap;
77
+ font-size: inherit;
78
+ line-height: var(
79
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_text_line-height
80
+ );
81
+ }
82
+ /* Removed data-loading background override to rely on native disabled opacities like Mantine */
83
+
84
+ /* ==== SIZES ==== */
85
+ .root[data-size="default"] {
86
+ height: var(
87
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_height
88
+ );
89
+ }
90
+ .root[data-size="default"][data-content="label"] {
91
+ border-radius: var(
92
+ --recursica_ui-kit_components_button_variants_content_label_variants_sizes_default_properties_border-radius
93
+ );
94
+ min-width: var(
95
+ --recursica_ui-kit_components_button_variants_content_label_variants_sizes_default_properties_min-width
96
+ );
97
+ padding: 0
98
+ var(
99
+ --recursica_ui-kit_components_button_variants_content_label_variants_sizes_default_properties_horizontal-padding
100
+ );
101
+ }
102
+ .root[data-size="default"][data-content="icon-label"] {
103
+ border-radius: var(
104
+ --recursica_ui-kit_components_button_variants_content_icon-label_variants_sizes_default_properties_border-radius
105
+ );
106
+ min-width: var(
107
+ --recursica_ui-kit_components_button_variants_content_icon-label_variants_sizes_default_properties_min-width
108
+ );
109
+ padding: 0
110
+ var(
111
+ --recursica_ui-kit_components_button_variants_content_icon-label_variants_sizes_default_properties_horizontal-padding
112
+ );
113
+ }
114
+ .root[data-size="default"][data-content="icon-only"] {
115
+ border-radius: var(
116
+ --recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_default_properties_border-radius
117
+ );
118
+ min-width: var(
119
+ --recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_default_properties_min-width
120
+ );
121
+ padding: 0
122
+ var(
123
+ --recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_default_properties_horizontal-padding
124
+ );
125
+ }
126
+ .root[data-size="default"] .labelText {
127
+ max-width: var(
128
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_max-label-width
129
+ );
130
+ }
131
+ .root[data-size="small"] {
132
+ height: var(
133
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_height
134
+ );
135
+
136
+ /* Override specific typography for small */
137
+ font-family: var(
138
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_text_font-family
139
+ );
140
+ font-size: var(
141
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_text_font-size
142
+ );
143
+ font-weight: var(
144
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_text_font-weight
145
+ );
146
+ }
147
+ .root[data-size="small"][data-content="label"] {
148
+ border-radius: var(
149
+ --recursica_ui-kit_components_button_variants_content_label_variants_sizes_small_properties_border-radius
150
+ );
151
+ min-width: var(
152
+ --recursica_ui-kit_components_button_variants_content_label_variants_sizes_small_properties_min-width
153
+ );
154
+ padding: 0
155
+ var(
156
+ --recursica_ui-kit_components_button_variants_content_label_variants_sizes_small_properties_horizontal-padding
157
+ );
158
+ }
159
+ .root[data-size="small"][data-content="icon-label"] {
160
+ border-radius: var(
161
+ --recursica_ui-kit_components_button_variants_content_icon-label_variants_sizes_small_properties_border-radius
162
+ );
163
+ min-width: var(
164
+ --recursica_ui-kit_components_button_variants_content_icon-label_variants_sizes_small_properties_min-width
165
+ );
166
+ padding: 0
167
+ var(
168
+ --recursica_ui-kit_components_button_variants_content_icon-label_variants_sizes_small_properties_horizontal-padding
169
+ );
170
+ }
171
+ .root[data-size="small"][data-content="icon-only"] {
172
+ border-radius: var(
173
+ --recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_small_properties_border-radius
174
+ );
175
+ min-width: var(
176
+ --recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_small_properties_min-width
177
+ );
178
+ padding: 0
179
+ var(
180
+ --recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_small_properties_horizontal-padding
181
+ );
182
+ }
183
+ .root[data-size="small"] .labelText {
184
+ max-width: var(
185
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_max-label-width
186
+ );
187
+ line-height: var(
188
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_text_line-height
189
+ );
190
+ }
191
+
192
+ /* Icon Resets */
193
+ .iconWrapper {
194
+ display: flex;
195
+ align-items: center;
196
+ justify-content: center;
197
+ flex-shrink: 0;
198
+ }
199
+ .iconWrapper > * {
200
+ width: 100%;
201
+ height: 100%;
202
+ object-fit: contain;
203
+ }
204
+ .root[data-size="default"] .iconWrapper {
205
+ width: var(
206
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_icon
207
+ );
208
+ height: var(
209
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_icon
210
+ );
211
+ }
212
+ .root[data-size="small"] .iconWrapper {
213
+ width: var(
214
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_icon
215
+ );
216
+ height: var(
217
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_icon
218
+ );
219
+ }
220
+
221
+ /* Loading state: hide the label/icon (they stay in the DOM/layout, matching
222
+ mantine-adapter's opacity:0 approach) so only MUI's own centered
223
+ loadingIndicator is visible — see IMPLEMENTATION_NOTES.md. */
224
+ .root[data-loading="true"] .labelText,
225
+ .root[data-loading="true"] .iconWrapper {
226
+ opacity: 0;
227
+ }
228
+
229
+ /* MUI uses .MuiButton-startIcon and .MuiButton-endIcon — real global classes MUI applies
230
+ directly, not local CSS Modules classes, so they must be wrapped in :global() (same as
231
+ .Mui-disabled below) or Vite's CSS Modules hashes them into scoped names that never match
232
+ anything in the actual DOM, silently no-op'ing every rule below. */
233
+ .root[data-size="default"] :global(.MuiButton-startIcon) {
234
+ margin-left: 0;
235
+ margin-right: var(
236
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_icon-text-gap
237
+ );
238
+ }
239
+ .root[data-size="default"] :global(.MuiButton-endIcon) {
240
+ margin-right: 0;
241
+ margin-left: var(
242
+ --recursica_ui-kit_components_button_variants_sizes_default_properties_icon-text-gap
243
+ );
244
+ }
245
+ .root[data-size="small"] :global(.MuiButton-startIcon) {
246
+ margin-left: 0;
247
+ margin-right: var(
248
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_icon-text-gap
249
+ );
250
+ }
251
+ .root[data-size="small"] :global(.MuiButton-endIcon) {
252
+ margin-right: 0;
253
+ margin-left: var(
254
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_icon-text-gap
255
+ );
256
+ }
257
+
258
+ /* Icon-only logic overrides */
259
+ .root[data-content="icon-only"] .labelText {
260
+ display: none;
261
+ }
262
+ .root[data-content="icon-only"] :global(.MuiButton-startIcon),
263
+ .root[data-content="icon-only"] :global(.MuiButton-endIcon) {
264
+ margin-right: 0;
265
+ margin-left: 0;
266
+ }
267
+
268
+ /* Disabled */
269
+ .root:disabled,
270
+ .root:global(.Mui-disabled) {
271
+ cursor: not-allowed;
272
+ }
273
+
274
+ /* Global Hover Hack Overlay */
275
+ .root::after {
276
+ content: "";
277
+ position: absolute;
278
+ inset: 0;
279
+ border-radius: inherit;
280
+ z-index: 0;
281
+ pointer-events: none;
282
+ transition: opacity 150ms ease;
283
+ opacity: 0;
284
+ background-color: var(--recursica_brand_states_hover_color);
285
+ }
286
+ .root:hover:not(:disabled):not(:global(.Mui-disabled))::after {
287
+ opacity: var(--recursica_brand_states_hover_opacity);
288
+ }
289
+
290
+ /* ==== VARIANTS ==== */
291
+
292
+ /* SOLID */
293
+ .root[data-variant="solid"] {
294
+ border-width: var(
295
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_border-size
296
+ );
297
+ box-shadow: var(
298
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_elevation
299
+ );
300
+ background-color: var(
301
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_background-color
302
+ );
303
+ border-color: var(
304
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_border-color
305
+ );
306
+ color: var(
307
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_text-color
308
+ );
309
+ /* Exposed so the loading-state Loader (style={{ "--loader-color": "var(--button-color)" }}
310
+ in Button.tsx) matches this exact text-color token — see IMPLEMENTATION_NOTES.md. */
311
+ --button-color: var(
312
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_text-color
313
+ );
314
+ }
315
+ .root[data-variant="solid"] .iconWrapper {
316
+ color: var(
317
+ --recursica_ui-kit_components_button_variants_styles_solid_properties_colors_icon-color
318
+ );
319
+ }
320
+ .root[data-variant="solid"]:disabled,
321
+ .root[data-variant="solid"]:global(.Mui-disabled) {
322
+ opacity: var(
323
+ --recursica_ui-kit_components_button_variants_styles_solid_variants_states_disabled_properties_opacity
324
+ );
325
+ box-shadow: var(
326
+ --recursica_ui-kit_components_button_variants_styles_solid_variants_states_disabled_properties_elevation
327
+ );
328
+ }
329
+
330
+ /* OUTLINE */
331
+ .root[data-variant="outline"] {
332
+ border-width: var(
333
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_border-size
334
+ );
335
+ box-shadow: var(
336
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_elevation
337
+ );
338
+ background-color: var(
339
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_background-color
340
+ );
341
+ border-color: var(
342
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_border-color
343
+ );
344
+ color: var(
345
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_text-color
346
+ );
347
+ --button-color: var(
348
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_text-color
349
+ );
350
+ }
351
+ .root[data-variant="outline"] .iconWrapper {
352
+ color: var(
353
+ --recursica_ui-kit_components_button_variants_styles_outline_properties_colors_icon-color
354
+ );
355
+ }
356
+ .root[data-variant="outline"]:disabled,
357
+ .root[data-variant="outline"]:global(.Mui-disabled) {
358
+ opacity: var(
359
+ --recursica_ui-kit_components_button_variants_styles_outline_variants_states_disabled_properties_opacity
360
+ );
361
+ box-shadow: var(
362
+ --recursica_ui-kit_components_button_variants_styles_outline_variants_states_disabled_properties_elevation
363
+ );
364
+ }
365
+
366
+ /* TEXT */
367
+ .root[data-variant="text"] {
368
+ border-width: var(
369
+ --recursica_ui-kit_components_button_variants_styles_text_properties_border-size
370
+ );
371
+ box-shadow: var(
372
+ --recursica_ui-kit_components_button_variants_styles_text_properties_elevation
373
+ );
374
+ background-color: var(
375
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_background-color
376
+ );
377
+ border-color: var(
378
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_border-color
379
+ );
380
+ color: var(
381
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_text-color
382
+ );
383
+ --button-color: var(
384
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_text-color
385
+ );
386
+ }
387
+ .root[data-variant="text"] .iconWrapper {
388
+ color: var(
389
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_icon-color
390
+ );
391
+ }
392
+ .root[data-variant="text"]:disabled,
393
+ .root[data-variant="text"]:global(.Mui-disabled) {
394
+ opacity: var(
395
+ --recursica_ui-kit_components_button_variants_styles_text_variants_states_disabled_properties_opacity
396
+ );
397
+ box-shadow: var(
398
+ --recursica_ui-kit_components_button_variants_styles_text_variants_states_disabled_properties_elevation
399
+ );
400
+ }
401
+
402
+ /* Focus State Mapping (native browser focus outline replaced with the recursica focus ring).
403
+ Placed after every variant's own box-shadow (elevation) rule so it wins the cascade at equal
404
+ attribute-selector specificity regardless of variant. */
405
+ .root:focus-visible {
406
+ outline: none;
407
+ box-shadow:
408
+ 0 0 0 var(--recursica_brand_states_focus_border-size)
409
+ var(--recursica_brand_states_focus_color),
410
+ 0 0 var(--recursica_brand_states_focus_blur)
411
+ var(--recursica_brand_states_focus_margin)
412
+ var(--recursica_brand_states_focus_color);
413
+ }