@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,103 @@
1
+ import { forwardRef, type CSSProperties } from "react";
2
+ import {
3
+ Menu as MuiMenu,
4
+ type MenuProps as MuiMenuProps,
5
+ MenuItem as MuiMenuItem,
6
+ type MenuItemProps as MuiMenuItemProps,
7
+ Divider as MuiDivider,
8
+ type DividerProps as MuiDividerProps,
9
+ } from "@mui/material";
10
+ import {
11
+ filterStylingProps,
12
+ mergeClassNames,
13
+ type RecursicaOverStyled,
14
+ } from "../../utils/filterStylingProps";
15
+ import styles from "./Menu.module.css";
16
+
17
+ import { type RecursicaMenuProps } from "@recursica/adapter-common";
18
+
19
+ export type MenuProps = RecursicaOverStyled<MuiMenuProps & RecursicaMenuProps>;
20
+
21
+ export const Menu = forwardRef<HTMLDivElement, MenuProps>(function Menu(
22
+ { overStyled = false, className, maxHeight, ...rest },
23
+ ref,
24
+ ) {
25
+ const sanitizedProps = filterStylingProps(rest, overStyled);
26
+ const restRecord = sanitizedProps as Record<string, unknown>;
27
+
28
+ const mergedClassNames = mergeClassNames(
29
+ {
30
+ paper: styles.dropdown,
31
+ list: styles.dropdown,
32
+ },
33
+ restRecord.classes as Partial<Record<string, string>> | undefined,
34
+ );
35
+
36
+ // `maxHeight` is a caller-supplied override of the token-driven dropdown max-height, applied
37
+ // to the Paper slot's inline style — an explicit per-instance escape hatch, not a design token.
38
+ const callerSlotProps = restRecord.slotProps as
39
+ | { paper?: Record<string, unknown> }
40
+ | undefined;
41
+ const mergedSlotProps = maxHeight
42
+ ? {
43
+ ...callerSlotProps,
44
+ paper: {
45
+ ...callerSlotProps?.paper,
46
+ style: {
47
+ ...(callerSlotProps?.paper?.style as CSSProperties | undefined),
48
+ maxHeight,
49
+ },
50
+ },
51
+ }
52
+ : callerSlotProps;
53
+
54
+ return (
55
+ <MuiMenu
56
+ ref={ref}
57
+ {...(sanitizedProps as MuiMenuProps)}
58
+ className={className}
59
+ classes={mergedClassNames}
60
+ {...(mergedSlotProps
61
+ ? { slotProps: mergedSlotProps as MuiMenuProps["slotProps"] }
62
+ : {})}
63
+ />
64
+ );
65
+ });
66
+
67
+ Menu.displayName = "Menu";
68
+
69
+ export type MenuItemProps = RecursicaOverStyled<MuiMenuItemProps>;
70
+
71
+ export const MenuItem = forwardRef<HTMLLIElement, MenuItemProps>(
72
+ function MenuItem({ overStyled = false, className, ...rest }, ref) {
73
+ const sanitizedProps = filterStylingProps(rest, overStyled);
74
+
75
+ return (
76
+ <MuiMenuItem
77
+ ref={ref}
78
+ {...(sanitizedProps as MuiMenuItemProps)}
79
+ className={`${styles.item} ${className || ""}`}
80
+ />
81
+ );
82
+ },
83
+ );
84
+
85
+ MenuItem.displayName = "MenuItem";
86
+
87
+ export type MenuDividerProps = RecursicaOverStyled<MuiDividerProps>;
88
+
89
+ export const MenuDivider = forwardRef<HTMLHRElement, MenuDividerProps>(
90
+ function MenuDivider({ overStyled = false, className, ...rest }, ref) {
91
+ const sanitizedProps = filterStylingProps(rest, overStyled);
92
+
93
+ return (
94
+ <MuiDivider
95
+ ref={ref}
96
+ {...(sanitizedProps as MuiDividerProps)}
97
+ className={`${styles.divider} ${className || ""}`}
98
+ />
99
+ );
100
+ },
101
+ );
102
+
103
+ MenuDivider.displayName = "MenuDivider";
@@ -0,0 +1,53 @@
1
+ # Menu - Usage Guide
2
+
3
+ This document describes how to integrate and use the `Menu` component in your projects using `@recursica/adapter-mui-v7`.
4
+
5
+ ---
6
+
7
+ ## 1. Import Reference
8
+
9
+ ```tsx
10
+ import { Menu } from "@recursica/adapter-mui-v7";
11
+ ```
12
+
13
+ ---
14
+
15
+ ## 2. Basic Example
16
+
17
+ ```tsx
18
+ import React from "react";
19
+ import { Menu } from "@recursica/adapter-mui-v7";
20
+
21
+ export default function Demo() {
22
+ return (
23
+ <Menu>
24
+ <Menu.Target>
25
+ <Button>Toggle Menu</Button>
26
+ </Menu.Target>
27
+ <Menu.Dropdown>
28
+ <Menu.Item>Profile</Menu.Item>
29
+ <Menu.Item>Settings</Menu.Item>
30
+ <Menu.Item color="red">Logout</Menu.Item>
31
+ </Menu.Dropdown>
32
+ </Menu>
33
+ );
34
+ }
35
+ ```
36
+
37
+ ---
38
+
39
+ ## 3. Design System Integration
40
+
41
+ All Recursica components in the `@recursica/adapter-mui-v7` package adhere strictly to design system spacing, scaling, and behavior patterns.
42
+
43
+ > [!IMPORTANT]
44
+ >
45
+ > - **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.
46
+ > - **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.
47
+ > - **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.
48
+
49
+ ---
50
+
51
+ ## 4. Notes
52
+
53
+ - `maxHeight` on `<Menu>` overrides the dropdown's token-driven max-height with an explicit pixel (or other CSS length) value, e.g. `<Menu maxHeight={320}>`. It's a per-instance escape hatch, not a design token — leave it unset to use the token default.
@@ -0,0 +1 @@
1
+ export * from "./Menu";
@@ -0,0 +1,31 @@
1
+ # Modal Implementation Notes
2
+
3
+ ## `.title` descender clipping (Matt Massey, 2026-08-28)
4
+
5
+ `.title` truncates with an ellipsis (`white-space: nowrap; text-overflow: ellipsis`) rather than
6
+ wrapping, needing `flex: 1 1 auto; min-width: 0;` since it's a flex child of `.header` alongside
7
+ the close button. It used plain `overflow: hidden` to make the ellipsis work, which also clips
8
+ descenders (e.g. the "g" in a long title) whenever `text_line-height` is tighter than the font's
9
+ natural ascent+descent. Switched to `overflow: clip; overflow-clip-margin: 0.35em;` — same
10
+ truncation, but ink can bleed slightly past the line box before it's actually clipped.
11
+ Project-wide fix; see Chip's `CHIP_IMPLEMENTATION_NOTES.md` for the original discovery. Matches
12
+ mantine-adapter's equivalent `.title` rule (see its own `MODAL_IMPLEMENTATION_NOTES.md`).
13
+
14
+ ## Vertical anchor position (source-of-truth audit, 2026-08-30)
15
+
16
+ **Decision:** Anchor the modal near the top of the viewport instead of MUI's own default
17
+ vertical centering, matching mantine's `Modal`, which has no `centered` override and so uses
18
+ its own library default (near-top, via `.mantine-Modal-inner`'s `align-items: flex-start` +
19
+ `padding: 30px 40px` — unstyled by any Recursica token).
20
+
21
+ **Implementation:** MUI's `Dialog` centers its paper both axes by default via
22
+ `.MuiDialog-container`. `.root :global(.MuiDialog-container)` overrides that to
23
+ `align-items: flex-start; padding: 30px 40px;`, matching mantine's numbers exactly since
24
+ neither side is token-driven — this is purely "reproduce the source of truth's own default
25
+ library shape" (see Grid's `IMPLEMENTATION_NOTES.md` for the same rule applied to Grid).
26
+ `.inner` (the paper) also gets `margin: 0` — MUI's paper ships its own default 32px margin on
27
+ top of the container padding, which would double the offset otherwise.
28
+
29
+ Residual: still a small width/horizontal-offset gap against mantine's golden after this fix
30
+ (diffPixels dropped from ~172k to ~25k, still over the 2500 threshold) — not yet root-caused,
31
+ see `OPEN_QUESTIONS.txt`.
@@ -0,0 +1,302 @@
1
+ /* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
2
+ * Close button is styled to match the Button component's text/icon-only variant, so it reuses
3
+ * the same global hover/focus state tokens Button.module.css exempts.
4
+ * recursica-allow-brand: --recursica_brand_states_focus_blur
5
+ * recursica-allow-brand: --recursica_brand_states_focus_border-size
6
+ * recursica-allow-brand: --recursica_brand_states_focus_color
7
+ * recursica-allow-brand: --recursica_brand_states_focus_margin
8
+ * recursica-allow-brand: --recursica_brand_states_hover_color
9
+ * recursica-allow-brand: --recursica_brand_states_hover_opacity
10
+ */
11
+
12
+ .root {
13
+ }
14
+
15
+ /* MUI's Dialog container centers its paper vertically by default. Mantine's Modal has no such
16
+ behavior — it anchors near the top (its own `.mantine-Modal-inner` default: align-items:
17
+ flex-start, padding: 30px 40px, unstyled by any Recursica token). Reproducing that shape here
18
+ since nothing here is Recursica-token-driven; it's purely "match the source of truth's own
19
+ default library behavior" per the layout-components rule (see Grid's IMPLEMENTATION_NOTES.md). */
20
+ .root :global(.MuiDialog-container) {
21
+ align-items: flex-start;
22
+ padding: 30px 40px;
23
+ }
24
+
25
+ .inner {
26
+ /* Mantine applies padding to inner to keep modal away from edges. We rely on content constraints. */
27
+ /* MUI's paper also ships its own default 32px margin on top of that — zero it out so the
28
+ container's padding (below) is the only source of edge spacing, matching Mantine's shape. */
29
+ margin: 0;
30
+
31
+ /* Unlike Mantine, where `.content` (Modal.Content) wraps header/body/footer as one element,
32
+ MUI's Dialog renders header/body(.content)/footer as separate siblings inside this Paper
33
+ (mapped via `classes.paper`) — so the border-radius belongs here, on the Paper that is the
34
+ whole visible modal, not on the body's DialogContent below. `overflow: hidden` clips the
35
+ header/footer's square corners to match. No box-shadow — Mantine's static default story
36
+ renders with none. */
37
+ border-radius: var(
38
+ --recursica_ui-kit_components_modal_properties_border-radius
39
+ );
40
+ overflow: hidden;
41
+ }
42
+
43
+ .content {
44
+ /* Geometric Bounds */
45
+ min-width: var(--recursica_ui-kit_components_modal_properties_min-width);
46
+ max-width: var(--recursica_ui-kit_components_modal_properties_max-width);
47
+ min-height: var(--recursica_ui-kit_components_modal_properties_min-height);
48
+
49
+ /* Restrict max-height to either the UI Kit max or the viewport bounds to force internal scrolling */
50
+ max-height: min(
51
+ var(--recursica_ui-kit_components_modal_properties_max-height),
52
+ calc(100vh - 4rem)
53
+ );
54
+ overflow: hidden;
55
+
56
+ /* Box model */
57
+ border-width: var(--recursica_ui-kit_components_modal_properties_border-size);
58
+ border-color: var(
59
+ --recursica_ui-kit_components_modal_properties_colors_border-color
60
+ );
61
+ border-style: solid;
62
+
63
+ /* Appearance */
64
+ background-color: var(
65
+ --recursica_ui-kit_components_modal_properties_colors_content-background-color
66
+ );
67
+
68
+ /* Internal Flex container to trap header and let body scroll */
69
+ display: flex;
70
+ flex-direction: column;
71
+ }
72
+
73
+ .header {
74
+ display: flex; /* HARDCODE: puts the title and close button side-by-side so the title has a bounded width to truncate against */
75
+ align-items: center;
76
+ justify-content: space-between;
77
+ padding: var(
78
+ --recursica_ui-kit_components_modal_properties_header-footer-vertical-padding
79
+ )
80
+ var(
81
+ --recursica_ui-kit_components_modal_properties_header-footer-horizontal-padding
82
+ );
83
+ background-color: transparent; /* Inherit from content */
84
+ }
85
+
86
+ .title {
87
+ flex: 1 1 auto; /* HARDCODE: let the title claim the space between the header edge and the close button */
88
+ min-width: 0; /* HARDCODE: required for text-overflow ellipsis to take effect on a flex child */
89
+ overflow: clip; /* HARDCODE: `hidden` clips descenders (e.g. "g") when text_line-height is
90
+ tighter than the font's natural ascent+descent; overflow-clip-margin gives ink a small bleed
91
+ allowance while still clipping genuinely overflowing text (see Chip's IMPLEMENTATION_NOTES.md). */
92
+ overflow-clip-margin: 0.35em;
93
+ white-space: nowrap;
94
+ text-overflow: ellipsis;
95
+
96
+ color: var(--recursica_ui-kit_components_modal_properties_colors_title);
97
+
98
+ /* Direct Figma Typography Mapping */
99
+ font-family: var(
100
+ --recursica_ui-kit_components_modal_properties_header-style_fontFamily
101
+ );
102
+ font-size: var(
103
+ --recursica_ui-kit_components_modal_properties_header-style_fontSize
104
+ );
105
+ font-style: var(
106
+ --recursica_ui-kit_components_modal_properties_header-style_fontStyle
107
+ );
108
+ font-weight: var(
109
+ --recursica_ui-kit_components_modal_properties_header-style_fontWeight
110
+ );
111
+ letter-spacing: var(
112
+ --recursica_ui-kit_components_modal_properties_header-style_letterSpacing
113
+ );
114
+ line-height: var(
115
+ --recursica_ui-kit_components_modal_properties_header-style_lineHeight
116
+ );
117
+ text-transform: var(
118
+ --recursica_ui-kit_components_modal_properties_header-style_textCase
119
+ );
120
+ text-decoration: var(
121
+ --recursica_ui-kit_components_modal_properties_header-style_textDecoration
122
+ );
123
+ }
124
+
125
+ .bodyWrapper {
126
+ /* This is the container that overrides Mantine's native Body. It strips padding and acts as a flex column. */
127
+ padding: 0;
128
+ display: flex;
129
+ flex-direction: column;
130
+ flex: 1 1 auto;
131
+ overflow: hidden;
132
+ min-height: 0; /* Critical for flex child scrolling constraint */
133
+ }
134
+
135
+ .scrollArea {
136
+ padding: var(
137
+ --recursica_ui-kit_components_modal_properties_content-vertical-padding
138
+ )
139
+ var(
140
+ --recursica_ui-kit_components_modal_properties_content-horizontal-padding
141
+ );
142
+
143
+ /* Internal scrolling */
144
+ flex: 1 1 auto;
145
+ overflow-y: auto;
146
+ min-height: 0; /* Critical for flex child scrolling constraint */
147
+
148
+ color: var(--recursica_ui-kit_components_modal_properties_colors_content);
149
+
150
+ /* Direct Figma Typography Mapping */
151
+ font-family: var(
152
+ --recursica_ui-kit_components_modal_properties_content-style_fontFamily
153
+ );
154
+ font-size: var(
155
+ --recursica_ui-kit_components_modal_properties_content-style_fontSize
156
+ );
157
+ font-style: var(
158
+ --recursica_ui-kit_components_modal_properties_content-style_fontStyle
159
+ );
160
+ font-weight: var(
161
+ --recursica_ui-kit_components_modal_properties_content-style_fontWeight
162
+ );
163
+ letter-spacing: var(
164
+ --recursica_ui-kit_components_modal_properties_content-style_letterSpacing
165
+ );
166
+ line-height: var(
167
+ --recursica_ui-kit_components_modal_properties_content-style_lineHeight
168
+ );
169
+ text-transform: var(
170
+ --recursica_ui-kit_components_modal_properties_content-style_textCase
171
+ );
172
+ text-decoration: var(
173
+ --recursica_ui-kit_components_modal_properties_content-style_textDecoration
174
+ );
175
+
176
+ /* Ensure button gap token is easily usable if developers use standard spacing */
177
+ --modal-button-gap: var(
178
+ --recursica_ui-kit_components_modal_properties_button-gap
179
+ );
180
+
181
+ /* Smooth divider transitions */
182
+ transition: border-color 0.15s ease;
183
+ border-top: var(
184
+ --recursica_ui-kit_components_modal_properties_scroll-divider-size
185
+ )
186
+ solid transparent;
187
+ border-bottom: var(
188
+ --recursica_ui-kit_components_modal_properties_scroll-divider-size
189
+ )
190
+ solid transparent;
191
+ }
192
+
193
+ .scrollArea[data-scrolled-top] {
194
+ border-top-color: var(
195
+ --recursica_ui-kit_components_modal_properties_colors_scroll-divider
196
+ );
197
+ }
198
+
199
+ .scrollArea[data-scrolled-bottom] {
200
+ border-bottom-color: var(
201
+ --recursica_ui-kit_components_modal_properties_colors_scroll-divider
202
+ );
203
+ }
204
+
205
+ .footer {
206
+ padding: var(
207
+ --recursica_ui-kit_components_modal_properties_header-footer-vertical-padding
208
+ )
209
+ var(
210
+ --recursica_ui-kit_components_modal_properties_header-footer-horizontal-padding
211
+ );
212
+ background-color: transparent;
213
+ display: flex;
214
+ justify-content: flex-end;
215
+ gap: var(--recursica_ui-kit_components_modal_properties_button-gap);
216
+ }
217
+
218
+ .close {
219
+ /* Matches the Button component's text-variant, icon-only, small-size visual treatment
220
+ (see Button.module.css) so the modal close control looks like a Recursica Button
221
+ rather than MUI's native IconButton. */
222
+ box-sizing: border-box;
223
+ display: flex;
224
+ align-items: center;
225
+ justify-content: center;
226
+ position: relative;
227
+ overflow: hidden;
228
+ transition: all 0.2s ease;
229
+
230
+ height: var(
231
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_height
232
+ );
233
+ min-width: var(
234
+ --recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_small_properties_min-width
235
+ );
236
+ padding: 0
237
+ var(
238
+ --recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_small_properties_horizontal-padding
239
+ );
240
+ border-radius: var(
241
+ --recursica_ui-kit_components_button_variants_content_icon-only_variants_sizes_small_properties_border-radius
242
+ );
243
+
244
+ border-style: solid;
245
+ border-width: var(
246
+ --recursica_ui-kit_components_button_variants_styles_text_properties_border-size
247
+ );
248
+ border-color: var(
249
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_border-color
250
+ );
251
+ background-color: var(
252
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_background-color
253
+ );
254
+ color: var(
255
+ --recursica_ui-kit_components_button_variants_styles_text_properties_colors_icon-color
256
+ );
257
+ }
258
+
259
+ .close svg {
260
+ position: relative;
261
+ z-index: 1;
262
+ width: var(
263
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_icon
264
+ );
265
+ height: var(
266
+ --recursica_ui-kit_components_button_variants_sizes_small_properties_icon
267
+ );
268
+ }
269
+
270
+ .close::after {
271
+ content: "";
272
+ position: absolute;
273
+ inset: 0;
274
+ border-radius: inherit;
275
+ z-index: 0;
276
+ pointer-events: none;
277
+ transition: opacity 150ms ease;
278
+ opacity: 0;
279
+ background-color: var(--recursica_brand_states_hover_color);
280
+ }
281
+ .close:hover:not(:disabled)::after {
282
+ opacity: var(--recursica_brand_states_hover_opacity);
283
+ }
284
+
285
+ /* MuiIconButton injects its own `:hover` background via emotion at render time, which lands in
286
+ the DOM after this stylesheet and wins the tie at equal specificity — same class of conflict
287
+ documented in DatePicker.module.css's error/disabled state overrides. `!important` keeps the
288
+ button's own background transparent so only the `::after` overlay above renders the hover
289
+ feedback, matching Button's single-overlay hover treatment exactly. */
290
+ .close:hover {
291
+ background-color: transparent !important;
292
+ }
293
+
294
+ .close:focus-visible {
295
+ outline: none;
296
+ box-shadow:
297
+ 0 0 0 var(--recursica_brand_states_focus_border-size)
298
+ var(--recursica_brand_states_focus_color),
299
+ 0 0 var(--recursica_brand_states_focus_blur)
300
+ var(--recursica_brand_states_focus_margin)
301
+ var(--recursica_brand_states_focus_color);
302
+ }
@@ -0,0 +1,105 @@
1
+ import { useState } from "react";
2
+ import type { Meta, StoryObj } from "@storybook/react";
3
+ import { Modal, type ModalProps } from "./Modal";
4
+ import { Button } from "../Button";
5
+
6
+ const meta: Meta<typeof Modal> = {
7
+ title: "UI-Kit/Modal",
8
+ component: Modal,
9
+ tags: ["autodocs"],
10
+ argTypes: {
11
+ opened: { table: { disable: true } },
12
+ onClose: { table: { disable: true } },
13
+ defaultChecked: { table: { disable: true } },
14
+ },
15
+ };
16
+
17
+ export default meta;
18
+
19
+ type Story = StoryObj<typeof Modal>;
20
+
21
+ const DefaultWrapper = (args: ModalProps) => {
22
+ // Starts opened so the modal is visible without pressing a button first.
23
+ const [opened, setOpened] = useState(true);
24
+ return (
25
+ <>
26
+ <Modal {...args} opened={opened} onClose={() => setOpened(false)}>
27
+ Please log in to continue accessing this feature.
28
+ <Modal.Footer>
29
+ <Button variant="outline" onClick={() => setOpened(false)}>
30
+ Cancel
31
+ </Button>
32
+ <Button onClick={() => setOpened(false)}>Confirm</Button>
33
+ </Modal.Footer>
34
+ </Modal>
35
+ <Button onClick={() => setOpened(true)}>Open Modal</Button>
36
+ </>
37
+ );
38
+ };
39
+
40
+ export const Default: Story = {
41
+ args: {
42
+ title: "Authentication Required",
43
+ },
44
+ render: (args) => <DefaultWrapper {...args} />,
45
+ };
46
+
47
+ const LongTitleWrapper = (args: ModalProps) => {
48
+ const [opened, setOpened] = useState(true);
49
+ return (
50
+ <>
51
+ <Modal {...args} opened={opened} onClose={() => setOpened(false)}>
52
+ The title above is longer than the header can display, so it truncates
53
+ with an ellipsis instead of wrapping onto a second line.
54
+ <Modal.Footer>
55
+ <Button onClick={() => setOpened(false)}>Got it</Button>
56
+ </Modal.Footer>
57
+ </Modal>
58
+ <Button onClick={() => setOpened(true)}>Open Modal</Button>
59
+ </>
60
+ );
61
+ };
62
+
63
+ export const LongTitle: Story = {
64
+ args: {
65
+ title:
66
+ "This Modal Title Is Deliberately Long Enough To Exceed The Available Header Width",
67
+ },
68
+ render: (args) => <LongTitleWrapper {...args} />,
69
+ };
70
+
71
+ const ScrollingWrapper = (args: ModalProps) => {
72
+ // Starts opened so the modal is visible without pressing a button first.
73
+ const [opened, setOpened] = useState(true);
74
+ return (
75
+ <>
76
+ <Modal {...args} opened={opened} onClose={() => setOpened(false)}>
77
+ <p>
78
+ This modal demonstrates the dynamically injected scroll dividers. When
79
+ this body content overflows, the borders between the Header and Footer
80
+ automatically appear to define the scrolling boundary.
81
+ </p>
82
+ {Array(20)
83
+ .fill(0)
84
+ .map((_, i) => (
85
+ <p key={i}>Scrolling content block {i + 1}...</p>
86
+ ))}
87
+ {/* The new Footer abstraction */}
88
+ <Modal.Footer>
89
+ <Button variant="outline" onClick={() => setOpened(false)}>
90
+ Decline
91
+ </Button>
92
+ <Button onClick={() => setOpened(false)}>Accept Terms</Button>
93
+ </Modal.Footer>
94
+ </Modal>
95
+ <Button onClick={() => setOpened(true)}>Open Scrolling Modal</Button>
96
+ </>
97
+ );
98
+ };
99
+
100
+ export const ScrollingContent: Story = {
101
+ args: {
102
+ title: "Terms and Conditions",
103
+ },
104
+ render: (args) => <ScrollingWrapper {...args} />,
105
+ };
@@ -0,0 +1 @@
1
+ // Placeholder for future Modal component tests. Add tests here if/when needed.