@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,231 @@
1
+ /* HARDCODED VALUES:
2
+ - border-style: solid: Structural rendering rule for the panel border.
3
+ - flexbox layout on .content & .body: Required to create a vertical flex context that pushes the footer to the bottom.
4
+ - position: sticky & negative margins on .footer: A CSS technique used to break the footer out of the .body padding constraints so it stretches edge-to-edge, while remaining fixed at the bottom of the scroll container.
5
+ - z-index: 10 on .footer: Ensures the footer covers the body content as it scrolls underneath.
6
+ */
7
+
8
+ /* ======================================
9
+ PANEL PAPER (MUI Drawer's actual positioned/sized DOM node)
10
+ ====================================== */
11
+
12
+ .paper {
13
+ /* MUI's Drawer `classes` prop only exposes its own slots (root, paper, docked, ...) — unlike
14
+ Mantine's `classNames`, it has no content/header/title/body slots to bind the rest of this
15
+ file's classes into. The box-model/appearance chrome below lives on `.content` instead,
16
+ rendered as an explicit child of Paper (see Panel.tsx). Strip Paper's own default MUI
17
+ appearance (elevation box-shadow, paper background) so only `.content`'s chrome shows —
18
+ otherwise the two would double up as a square-cornered shadow behind the rounded one. */
19
+ background-color: transparent;
20
+ box-shadow: none;
21
+ }
22
+
23
+ /* ======================================
24
+ PANEL CONTENT (the whole visible panel box, rendered inside Paper)
25
+ ====================================== */
26
+
27
+ .content {
28
+ background-color: var(
29
+ --recursica_ui-kit_components_panel_properties_colors_background-color
30
+ );
31
+ border-style: solid;
32
+ border-width: var(--recursica_ui-kit_components_panel_properties_border-size);
33
+ border-color: var(
34
+ --recursica_ui-kit_components_panel_properties_colors_border-color
35
+ );
36
+ border-radius: var(
37
+ --recursica_ui-kit_components_panel_properties_border-radius
38
+ );
39
+ box-shadow: var(--recursica_ui-kit_components_panel_properties_elevation);
40
+ min-width: var(--recursica_ui-kit_components_panel_properties_min-width);
41
+ max-width: var(--recursica_ui-kit_components_panel_properties_max-width);
42
+
43
+ display: flex;
44
+ flex-direction: column;
45
+ height: 100%;
46
+ }
47
+
48
+ /* ======================================
49
+ PANEL HEADER
50
+ ====================================== */
51
+
52
+ .header {
53
+ /* HARDCODE: Mantine's `Drawer.Header` is flex (title + close button side-by-side) natively;
54
+ MUI's header here is a plain manually-built div (see Panel.tsx), so the layout has to be
55
+ declared explicitly. */
56
+ display: flex;
57
+ align-items: center;
58
+ justify-content: space-between;
59
+
60
+ background-color: var(
61
+ --recursica_ui-kit_components_panel_properties_colors_header-background-color
62
+ );
63
+ padding: var(
64
+ --recursica_ui-kit_components_panel_properties_header-footer-vertical-padding
65
+ )
66
+ var(
67
+ --recursica_ui-kit_components_panel_properties_header-footer-horizontal-padding
68
+ );
69
+ border-bottom: var(
70
+ --recursica_ui-kit_components_panel_properties_divider-size
71
+ )
72
+ solid
73
+ var(--recursica_ui-kit_components_panel_properties_colors_divider-color);
74
+ gap: var(--recursica_ui-kit_components_panel_properties_header-close-gap);
75
+ }
76
+
77
+ .close {
78
+ /* No Recursica token namespace exists for a panel close icon (Mantine's own Panel doesn't
79
+ style one either — it renders Mantine's plain default CloseButton) — flex-shrink keeps it
80
+ from being squeezed by a long, truncating title. */
81
+ flex-shrink: 0;
82
+ }
83
+
84
+ /* ======================================
85
+ PANEL TITLE
86
+ ====================================== */
87
+
88
+ .title {
89
+ color: var(--recursica_ui-kit_components_panel_properties_colors_title);
90
+
91
+ /* Direct Figma Typography Mapping */
92
+ font-family: var(
93
+ --recursica_ui-kit_components_panel_properties_header-style_fontFamily
94
+ );
95
+ font-size: var(
96
+ --recursica_ui-kit_components_panel_properties_header-style_fontSize
97
+ );
98
+ font-style: var(
99
+ --recursica_ui-kit_components_panel_properties_header-style_fontStyle
100
+ );
101
+ font-weight: var(
102
+ --recursica_ui-kit_components_panel_properties_header-style_fontWeight
103
+ );
104
+ letter-spacing: var(
105
+ --recursica_ui-kit_components_panel_properties_header-style_letterSpacing
106
+ );
107
+ line-height: var(
108
+ --recursica_ui-kit_components_panel_properties_header-style_lineHeight
109
+ );
110
+ text-transform: var(
111
+ --recursica_ui-kit_components_panel_properties_header-style_textCase
112
+ );
113
+ text-decoration: var(
114
+ --recursica_ui-kit_components_panel_properties_header-style_textDecoration
115
+ );
116
+ }
117
+
118
+ .titleTruncate {
119
+ composes: title;
120
+ white-space: nowrap;
121
+ overflow: clip; /* HARDCODE: `hidden` clips descenders (e.g. "g") when text_line-height is
122
+ tighter than the font's natural ascent+descent; overflow-clip-margin gives ink a small bleed
123
+ allowance while still clipping genuinely overflowing text (see Chip's IMPLEMENTATION_NOTES.md). */
124
+ overflow-clip-margin: 0.35em;
125
+ text-overflow: ellipsis;
126
+ display: block;
127
+ flex: 1;
128
+ min-width: 0;
129
+ }
130
+
131
+ /* ======================================
132
+ PANEL BODY
133
+ ====================================== */
134
+
135
+ .body {
136
+ padding: var(
137
+ --recursica_ui-kit_components_panel_properties_content-vertical-padding
138
+ )
139
+ var(
140
+ --recursica_ui-kit_components_panel_properties_content-horizontal-padding
141
+ );
142
+ color: var(--recursica_ui-kit_components_panel_properties_colors_content);
143
+
144
+ flex: 1;
145
+ display: flex;
146
+ flex-direction: column;
147
+ overflow-y: auto;
148
+
149
+ /* Direct Figma Typography Mapping */
150
+ font-family: var(
151
+ --recursica_ui-kit_components_panel_properties_content-style_fontFamily
152
+ );
153
+ font-size: var(
154
+ --recursica_ui-kit_components_panel_properties_content-style_fontSize
155
+ );
156
+ font-style: var(
157
+ --recursica_ui-kit_components_panel_properties_content-style_fontStyle
158
+ );
159
+ font-weight: var(
160
+ --recursica_ui-kit_components_panel_properties_content-style_fontWeight
161
+ );
162
+ letter-spacing: var(
163
+ --recursica_ui-kit_components_panel_properties_content-style_letterSpacing
164
+ );
165
+ line-height: var(
166
+ --recursica_ui-kit_components_panel_properties_content-style_lineHeight
167
+ );
168
+ text-transform: var(
169
+ --recursica_ui-kit_components_panel_properties_content-style_textCase
170
+ );
171
+ text-decoration: var(
172
+ --recursica_ui-kit_components_panel_properties_content-style_textDecoration
173
+ );
174
+ }
175
+
176
+ /* ======================================
177
+ PANEL FOOTER
178
+ ====================================== */
179
+
180
+ .footer {
181
+ background-color: var(
182
+ --recursica_ui-kit_components_panel_properties_colors_footer-background-color
183
+ );
184
+ padding: var(
185
+ --recursica_ui-kit_components_panel_properties_header-footer-vertical-padding
186
+ )
187
+ var(
188
+ --recursica_ui-kit_components_panel_properties_header-footer-horizontal-padding
189
+ );
190
+ border-top: var(--recursica_ui-kit_components_panel_properties_divider-size)
191
+ solid
192
+ var(--recursica_ui-kit_components_panel_properties_colors_divider-color);
193
+
194
+ display: flex;
195
+ align-items: center;
196
+ justify-content: flex-end;
197
+ gap: var(--recursica_ui-kit_components_panel_properties_footer-button-gap);
198
+
199
+ /* Ensure footer sticks to the bottom of the scroll container */
200
+ margin-top: auto;
201
+ position: sticky;
202
+
203
+ /* Break out of .body padding constraints to stretch edge-to-edge */
204
+ bottom: calc(
205
+ var(
206
+ --recursica_ui-kit_components_panel_properties_content-vertical-padding
207
+ ) *
208
+ -1
209
+ );
210
+ margin-left: calc(
211
+ var(
212
+ --recursica_ui-kit_components_panel_properties_content-horizontal-padding
213
+ ) *
214
+ -1
215
+ );
216
+ margin-right: calc(
217
+ var(
218
+ --recursica_ui-kit_components_panel_properties_content-horizontal-padding
219
+ ) *
220
+ -1
221
+ );
222
+ margin-bottom: calc(
223
+ var(
224
+ --recursica_ui-kit_components_panel_properties_content-vertical-padding
225
+ ) *
226
+ -1
227
+ );
228
+
229
+ /* Render over scrolling content */
230
+ z-index: 10;
231
+ }
@@ -0,0 +1,227 @@
1
+ import { useState } from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import { Panel, type PanelProps } from "./Panel";
4
+ import { Button } from "../Button";
5
+ import { Text } from "../Text/Text";
6
+
7
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8
+ type PanelStoryArgs = Record<string, any>;
9
+
10
+ const meta: Meta = {
11
+ title: "UI-Kit/Panel",
12
+ component: Panel,
13
+ tags: ["autodocs"],
14
+ argTypes: {
15
+ placement: {
16
+ control: "select",
17
+ options: ["left", "right", "top", "bottom"],
18
+ description: "Side of the screen the panel slides in from.",
19
+ },
20
+ title: {
21
+ control: "text",
22
+ description: "Panel title displayed in the header.",
23
+ },
24
+ withOverlay: {
25
+ control: "boolean",
26
+ description: "Whether to display a background overlay.",
27
+ },
28
+ withCloseButton: {
29
+ control: "boolean",
30
+ description: "Whether to display the close button in the header.",
31
+ },
32
+ wrapHeaderText: {
33
+ control: "boolean",
34
+ description:
35
+ "If true, forces the header text to a single line and truncates with an ellipsis.",
36
+ },
37
+ // Hide auto-detected HTML attributes
38
+ defaultChecked: { table: { disable: true } },
39
+ defaultValue: { table: { disable: true } },
40
+ suppressContentEditableWarning: { table: { disable: true } },
41
+ suppressHydrationWarning: { table: { disable: true } },
42
+ },
43
+ parameters: {
44
+ layout: "fullscreen",
45
+ docs: {
46
+ description: {
47
+ component: `
48
+ The \`Panel\` component slides in or expands from the edge of the screen to reveal additional content or functionality. Built on Mui's \`Drawer\`, it enforces Recursica design tokens for styling.
49
+
50
+ ### Anatomy
51
+ 1. **Header** — Title and close icon, remains fixed on scroll
52
+ 2. **Divider** — Separates header/footer from content
53
+ 3. **Body (Slot)** — Scrollable content area for custom content
54
+ 4. **Footer** — Fixed action buttons (Recursica-specific)
55
+
56
+ ### Usage
57
+ \`\`\`tsx
58
+ const [opened, { open, close }] = useDisclosure(false);
59
+
60
+ <Button onClick={open}>Open Panel</Button>
61
+ <Panel opened={opened} onClose={close} title="Settings" placement="right">
62
+ Content goes here
63
+ <Panel.Footer>
64
+ <Button variant="outline">Cancel</Button>
65
+ <Button variant="solid">Save</Button>
66
+ </Panel.Footer>
67
+ </Panel>
68
+ \`\`\`
69
+ `,
70
+ },
71
+ },
72
+ },
73
+ };
74
+
75
+ export default meta;
76
+
77
+ type Story = StoryObj<PanelStoryArgs>;
78
+
79
+ export const Default: Story = {
80
+ args: {
81
+ placement: "right",
82
+ title: "Panel Title",
83
+ withOverlay: true,
84
+ withCloseButton: true,
85
+ wrapHeaderText: false,
86
+ },
87
+ render: ({ wrapHeaderText, ...args }: PanelStoryArgs) => {
88
+ // eslint-disable-next-line react-hooks/rules-of-hooks
89
+ const [opened, setOpened] = useState(false);
90
+
91
+ return (
92
+ <>
93
+ <Button variant="solid" onClick={() => setOpened(true)}>
94
+ Open Panel
95
+ </Button>
96
+ <Panel
97
+ {...(args as PanelProps)}
98
+ opened={opened}
99
+ onClose={() => setOpened(false)}
100
+ title="Panel Title"
101
+ placement="right"
102
+ wrapHeaderText={wrapHeaderText}
103
+ >
104
+ <Text>
105
+ This is the panel body content area. Panels slide in from the edge
106
+ of the screen to reveal supplementary information, navigation
107
+ options, or toolsets.
108
+ </Text>
109
+ <Panel.Footer>
110
+ <Button variant="outline" onClick={() => setOpened(false)}>
111
+ Cancel
112
+ </Button>
113
+ <Button variant="solid">Save</Button>
114
+ </Panel.Footer>
115
+ </Panel>
116
+ </>
117
+ );
118
+ },
119
+ };
120
+
121
+ export const LeftPlacement: Story = {
122
+ args: {
123
+ placement: "left",
124
+ title: "Navigation",
125
+ withOverlay: true,
126
+ withCloseButton: true,
127
+ wrapHeaderText: false,
128
+ },
129
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
130
+ render: ({ withLayer, layer, ...args }: PanelStoryArgs) => {
131
+ // eslint-disable-next-line react-hooks/rules-of-hooks
132
+ const [opened, setOpened] = useState(false);
133
+
134
+ return (
135
+ <>
136
+ <Button variant="outline" onClick={() => setOpened(true)}>
137
+ Open Left Panel
138
+ </Button>
139
+ <Panel
140
+ {...(args as PanelProps)}
141
+ opened={opened}
142
+ onClose={() => setOpened(false)}
143
+ >
144
+ <Text>
145
+ A panel sliding in from the left, commonly used for navigation menus
146
+ or sidebars.
147
+ </Text>
148
+ </Panel>
149
+ </>
150
+ );
151
+ },
152
+ };
153
+
154
+ export const ScrollableContent: Story = {
155
+ args: {
156
+ placement: "right",
157
+ title: "Scrollable Panel",
158
+ withOverlay: true,
159
+ withCloseButton: true,
160
+ wrapHeaderText: false,
161
+ },
162
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
163
+ render: ({ withLayer, layer, ...args }: PanelStoryArgs) => {
164
+ // eslint-disable-next-line react-hooks/rules-of-hooks
165
+ const [opened, setOpened] = useState(false);
166
+
167
+ return (
168
+ <>
169
+ <Button variant="solid" onClick={() => setOpened(true)}>
170
+ Open Scrollable Panel
171
+ </Button>
172
+ <Panel
173
+ {...(args as PanelProps)}
174
+ opened={opened}
175
+ onClose={() => setOpened(false)}
176
+ >
177
+ {Array.from({ length: 20 }).map((_, i) => (
178
+ <p key={i} style={{ marginBottom: "1rem" }}>
179
+ Paragraph {i + 1}: This is sample content to demonstrate the
180
+ scrollable behavior of the panel when content exceeds the viewport
181
+ height.
182
+ </p>
183
+ ))}
184
+ <Panel.Footer>
185
+ <Button variant="outline" onClick={() => setOpened(false)}>
186
+ Close
187
+ </Button>
188
+ <Button variant="solid">Apply</Button>
189
+ </Panel.Footer>
190
+ </Panel>
191
+ </>
192
+ );
193
+ },
194
+ };
195
+
196
+ export const LongTitle: Story = {
197
+ args: {
198
+ placement: "right",
199
+ title:
200
+ "This is a ridiculously long panel title designed to test how the header CSS handles text overflow and whether it truncates correctly or breaks the layout",
201
+ withOverlay: true,
202
+ withCloseButton: true,
203
+ wrapHeaderText: true,
204
+ },
205
+ render: ({ ...args }: PanelStoryArgs) => {
206
+ // eslint-disable-next-line react-hooks/rules-of-hooks
207
+ const [opened, setOpened] = useState(false);
208
+
209
+ return (
210
+ <>
211
+ <Button variant="solid" onClick={() => setOpened(true)}>
212
+ Open Long Title Panel
213
+ </Button>
214
+ <Panel
215
+ {...(args as PanelProps)}
216
+ opened={opened}
217
+ onClose={() => setOpened(false)}
218
+ >
219
+ <Text>
220
+ Check the header to see if the long title is handled gracefully
221
+ without pushing the close button off screen.
222
+ </Text>
223
+ </Panel>
224
+ </>
225
+ );
226
+ },
227
+ };
@@ -0,0 +1 @@
1
+ // Placeholder for future Panel component tests. Add tests here if/when needed.
@@ -0,0 +1,186 @@
1
+ import { forwardRef, type ReactNode } from "react";
2
+ import {
3
+ Drawer as MuiDrawer,
4
+ type DrawerProps as MuiDrawerProps,
5
+ IconButton as MuiIconButton,
6
+ } from "@mui/material";
7
+ import {
8
+ filterStylingProps,
9
+ mergeClassNames,
10
+ type RecursicaOverStyled,
11
+ } from "../../utils/filterStylingProps";
12
+ import styles from "./Panel.module.css";
13
+
14
+ // ============================================================
15
+ // PANEL (Drawer)
16
+ // ============================================================
17
+
18
+ import { type RecursicaPanelProps as BaseRecursicaPanelProps } from "@recursica/adapter-common";
19
+
20
+ /**
21
+ * Recursica Panel root props. Extends Mui Drawer.
22
+ */
23
+ export interface RecursicaPanelProps
24
+ extends Omit<
25
+ MuiDrawerProps,
26
+ "classes" | "position" | "style" | "anchor" | "open" | "title"
27
+ >,
28
+ BaseRecursicaPanelProps {
29
+ /** Panel header title label. */
30
+ title?: ReactNode;
31
+ /** Whether to display a background overlay. Default true. */
32
+ withOverlay?: boolean;
33
+ /** Whether to display the close button in the header. Default true. */
34
+ withCloseButton?: boolean;
35
+ }
36
+
37
+ export type PanelProps = RecursicaOverStyled<RecursicaPanelProps>;
38
+
39
+ const CloseIcon = () => (
40
+ <svg
41
+ xmlns="http://www.w3.org/2000/svg"
42
+ width="16"
43
+ height="16"
44
+ viewBox="0 0 24 24"
45
+ fill="none"
46
+ stroke="currentColor"
47
+ strokeWidth="2"
48
+ strokeLinecap="round"
49
+ strokeLinejoin="round"
50
+ >
51
+ <path d="M18 6L6 18M6 6l12 12" />
52
+ </svg>
53
+ );
54
+
55
+ /**
56
+ * Recursica Panel component wrapping Mui's Drawer.
57
+ *
58
+ * Panels slide in or expand from the edge of the screen to reveal
59
+ * additional content or functionality. They are commonly used to provide
60
+ * supplementary information, navigation options, or toolsets without
61
+ * cluttering the main interface.
62
+ *
63
+ * ```tsx
64
+ * <Panel opened={opened} onClose={close} title="Panel Title" placement="right">
65
+ * <Panel.Body>
66
+ * Content goes here
67
+ * </Panel.Body>
68
+ * </Panel>
69
+ * ```
70
+ *
71
+ * Mui Drawer sub-components available via dot-notation:
72
+ * - `Panel.Header` — Top section with title and close button
73
+ * - `Panel.Title` — Title text within the header
74
+ * - `Panel.CloseButton` — Close button within the header
75
+ * - `Panel.Body` — Scrollable body content area
76
+ * - `Panel.Content` — Outer content container
77
+ * - `Panel.Overlay` — Background overlay
78
+ * - `Panel.Root` — Root element for advanced composition
79
+ * - `Panel.Stack` — Stacked drawer context
80
+ */
81
+ const PanelBase = function Panel({
82
+ overStyled = false,
83
+ placement = "right",
84
+ keepMounted = true,
85
+ wrapHeaderText = true,
86
+ opened,
87
+ title,
88
+ withOverlay = true,
89
+ withCloseButton = true,
90
+ onClose,
91
+ children,
92
+ ...rest
93
+ }: PanelProps) {
94
+ const sanitizedProps = filterStylingProps(rest, overStyled);
95
+
96
+ // MUI Drawer's `classes` prop only recognizes its own slot names (`root`, `paper`,
97
+ // `docked`, ...) — unlike Mantine's `classNames`, it has no `content`/`header`/`title`/`body`
98
+ // slots to bind into. Passing those keys here used to silently no-op every one of them, which
99
+ // is why the panel rendered with none of its Recursica chrome (border, radius, sizing) and no
100
+ // header at all: MUI's raw Drawer has no `title`/`withCloseButton` convenience API the way
101
+ // Mantine's does, so those props were being spread onto the DOM as inert attributes instead of
102
+ // building a header. The box-model/appearance chrome (border, radius, shadow, size bounds) now
103
+ // lives on an explicit `.content` wrapper rendered as Paper's child instead; `.paper` strips
104
+ // MUI's own default Paper appearance so only the wrapper's chrome is visible.
105
+ const mergedClassNames = mergeClassNames(
106
+ { paper: styles.paper },
107
+ (sanitizedProps as Record<string, unknown>).classes as
108
+ | Partial<Record<string, string>>
109
+ | undefined,
110
+ );
111
+
112
+ return (
113
+ <MuiDrawer
114
+ anchor={placement} /* Recursica default: right; Mui default: left */
115
+ keepMounted={keepMounted}
116
+ open={Boolean(opened)}
117
+ onClose={onClose}
118
+ hideBackdrop={!withOverlay}
119
+ {...(sanitizedProps as unknown as MuiDrawerProps)}
120
+ classes={mergedClassNames as unknown as MuiDrawerProps["classes"]}
121
+ >
122
+ <div className={styles.content}>
123
+ {(title || withCloseButton) && (
124
+ <div className={styles.header}>
125
+ {title && (
126
+ <div
127
+ className={wrapHeaderText ? styles.titleTruncate : styles.title}
128
+ >
129
+ {title}
130
+ </div>
131
+ )}
132
+ {withCloseButton && (
133
+ <MuiIconButton
134
+ size="small"
135
+ aria-label="Close"
136
+ onClick={(e) => onClose?.(e, "backdropClick")}
137
+ className={styles.close}
138
+ >
139
+ <CloseIcon />
140
+ </MuiIconButton>
141
+ )}
142
+ </div>
143
+ )}
144
+ <div className={styles.body}>{children}</div>
145
+ </div>
146
+ </MuiDrawer>
147
+ );
148
+ };
149
+ PanelBase.displayName = "Panel";
150
+
151
+ // ============================================================
152
+ // PANEL FOOTER (custom — Mui Drawer has no Footer sub-component)
153
+ // ============================================================
154
+
155
+ export type PanelFooterProps = RecursicaOverStyled<
156
+ React.HTMLAttributes<HTMLDivElement>
157
+ >;
158
+
159
+ /**
160
+ * Panel footer section with action buttons.
161
+ * Separated from the body by a divider. Remains fixed at the bottom.
162
+ * This is a Recursica-specific sub-component; Mui Drawer does not
163
+ * natively provide a footer.
164
+ */
165
+ export const PanelFooter = forwardRef<HTMLDivElement, PanelFooterProps>(
166
+ function PanelFooter({ overStyled = false, ...rest }, ref) {
167
+ const sanitizedProps = filterStylingProps(rest, overStyled);
168
+ const classNameProp = (sanitizedProps as Record<string, unknown>)
169
+ .className as string | undefined;
170
+
171
+ const finalClassName = classNameProp
172
+ ? `${styles.footer} ${classNameProp}`
173
+ : styles.footer;
174
+
175
+ return <div ref={ref} {...sanitizedProps} className={finalClassName} />;
176
+ },
177
+ );
178
+ PanelFooter.displayName = "PanelFooter";
179
+
180
+ // ============================================================
181
+ type PanelComponent = typeof PanelBase & {
182
+ Footer: typeof PanelFooter;
183
+ };
184
+
185
+ export const Panel = PanelBase as PanelComponent;
186
+ Panel.Footer = PanelFooter;
@@ -0,0 +1,46 @@
1
+ # Panel - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Panel` component in your projects using `@recursica/adapter-mui-v7`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Panel } from "@recursica/adapter-mui-v7";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Panel } from "@recursica/adapter-mui-v7";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Panel>
24
+ <Text>This is a clean, structured visual container.</Text>
25
+ </Panel>
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.
41
+
42
+ ---
43
+
44
+ ## 4. Key Integration Features & Constraints
45
+
46
+ `Panel` accepts a `placement` prop (`"left"`, `"right"`, `"top"`, or `"bottom"`) that controls which edge of the screen the panel slides in from, and defaults to `"right"`. This prop was renamed from `position` to `placement`.
@@ -0,0 +1 @@
1
+ export * from "./Panel";