@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,247 @@
1
+ /**
2
+ * Radio.module.css
3
+ *
4
+ * HARDCODED VALUES:
5
+ * - margin / padding: 0 — Structural resets; consider token if spacing needed.
6
+ * - cursor: pointer / not-allowed — Baseline interactive indications.
7
+ * - appearance / box-sizing / border-style — necessary normalization for inputs.
8
+ * - transition: all 0.2s ease — Animation curve; consider a transition token.
9
+ * - min-width: 0 — Forces text wrap boundary in flex children.
10
+ */
11
+
12
+ /* --- GROUP STYLES --- */
13
+ .groupRoot {
14
+ padding: var(
15
+ --recursica_ui-kit_components_radio-button-group_properties_padding
16
+ );
17
+ margin: 0; /* HARDCODE: structural reset; consider token if layout needs change */
18
+ display: flex;
19
+ flex-direction: column;
20
+ gap: var(
21
+ --recursica_ui-kit_components_radio-button-group_properties_item-gap
22
+ );
23
+ }
24
+
25
+ /* SideBySide Variant */
26
+ .groupRoot[data-layout="side-by-side"] {
27
+ flex-direction: row;
28
+ flex-wrap: wrap;
29
+ gap: var(
30
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_gutter
31
+ );
32
+ padding-top: var(
33
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_vertical-padding
34
+ );
35
+ padding-bottom: var(
36
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_vertical-padding
37
+ );
38
+ margin-top: var(
39
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_top-bottom-margin
40
+ );
41
+ margin-bottom: var(
42
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_top-bottom-margin
43
+ );
44
+ }
45
+
46
+ /* Stacked Variant */
47
+ .groupRoot[data-layout="stacked"] {
48
+ flex-direction: column;
49
+ margin-top: var(
50
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_stacked_properties_label-field-gap
51
+ );
52
+ margin-bottom: var(
53
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_stacked_properties_top-bottom-margin
54
+ );
55
+ }
56
+
57
+ /* --- PRIMITIVE RADIO STYLES --- */
58
+
59
+ .root {
60
+ max-width: var(
61
+ --recursica_ui-kit_components_radio-button-item_properties_max-width
62
+ );
63
+ }
64
+
65
+ .body {
66
+ display: flex;
67
+ align-items: flex-start;
68
+ gap: var(
69
+ --recursica_ui-kit_components_radio-button-item_properties_label-gap
70
+ );
71
+ }
72
+
73
+ .inner {
74
+ display: flex;
75
+ align-items: center;
76
+ justify-content: center;
77
+ margin: 0; /* HARDCODE: structural reset */
78
+ width: var(--recursica_ui-kit_components_radio-button_properties_size);
79
+ height: var(--recursica_ui-kit_components_radio-button_properties_size);
80
+ /* Apply font-size to this element so that an 'em' based line-height token evaluates to the correct exact pixel value. */
81
+ font-size: var(
82
+ --recursica_ui-kit_components_radio-button-item_properties_text_font-size
83
+ );
84
+ /* Mathematically syncs the physical input radio bounding block visually with the center of the text's first line.
85
+ NOTE: Since the Figma line-height token resolves to an 'em' length (e.g. 1.05em), we CANNOT multiply it by font-size in CSS.
86
+ Instead, it naturally evaluates to the correct height because we applied the font-size above. */
87
+ margin-top: calc(
88
+ (
89
+ var(
90
+ --recursica_ui-kit_components_radio-button-item_properties_text_line-height
91
+ ) -
92
+ var(--recursica_ui-kit_components_radio-button_properties_size)
93
+ ) /
94
+ 2
95
+ );
96
+ }
97
+
98
+ /* Base explicit reset masking underlying framework defaults.
99
+ MUI's native <input type="radio"> stays invisible (SwitchBase overlays it with
100
+ opacity: 0) — it is not the visual circle. The circle is drawn by our own
101
+ icon/checkedIcon node (see Radio.tsx), a sibling of the input, so it's styled
102
+ here directly rather than through MUI's `classes` prop (MUI has no "radio" slot). */
103
+ .radio {
104
+ display: flex;
105
+ align-items: center;
106
+ justify-content: center;
107
+ cursor: pointer; /* HARDCODE: core interaction behavior */
108
+ box-sizing: border-box; /* HARDCODE: ensures size includes borders */
109
+ width: var(--recursica_ui-kit_components_radio-button_properties_size);
110
+ height: var(--recursica_ui-kit_components_radio-button_properties_size);
111
+ border-radius: var(
112
+ --recursica_ui-kit_components_radio-button_properties_border-radius
113
+ );
114
+ border-width: var(
115
+ --recursica_ui-kit_components_radio-button_properties_border-size
116
+ );
117
+ border-style: solid; /* HARDCODE: normalize primitive border-style */
118
+
119
+ /* Standard unchecked state */
120
+ background-color: var(
121
+ --recursica_ui-kit_components_radio-button_variants_selection-states_unselected_properties_colors_background-color
122
+ );
123
+ border-color: var(
124
+ --recursica_ui-kit_components_radio-button_variants_selection-states_unselected_properties_colors_border-color
125
+ );
126
+ transition: all 0.2s ease; /* HARDCODE: consider global transition token */
127
+ }
128
+
129
+ /* Checked State */
130
+ .radioChecked {
131
+ background-color: var(
132
+ --recursica_ui-kit_components_radio-button_variants_selection-states_selected_properties_colors_background-color
133
+ );
134
+ border-color: var(
135
+ --recursica_ui-kit_components_radio-button_variants_selection-states_selected_properties_colors_border-color
136
+ );
137
+ }
138
+
139
+ /* Disabled State (colors now differ per selection state; MUI applies its `disabled`
140
+ classKey to the same root element as `root`, so `.root.disabled` targets the
141
+ actual disabled instance and cascades to the decorative icon div inside it —
142
+ mirrors Checkbox's split). */
143
+ .root.disabled .radio {
144
+ cursor: not-allowed; /* HARDCODE: disabled state default */
145
+ }
146
+ .root.disabled .radio:not(.radioChecked) {
147
+ opacity: var(
148
+ --recursica_ui-kit_components_radio-button_variants_selection-states_unselected_variants_states_disabled_properties_opacity
149
+ );
150
+ background-color: var(
151
+ --recursica_ui-kit_components_radio-button_variants_selection-states_unselected_variants_states_disabled_properties_colors_background-color
152
+ );
153
+ border-color: var(
154
+ --recursica_ui-kit_components_radio-button_variants_selection-states_unselected_variants_states_disabled_properties_colors_border-color
155
+ );
156
+ }
157
+ .root.disabled .radioChecked {
158
+ opacity: var(
159
+ --recursica_ui-kit_components_radio-button_variants_selection-states_selected_variants_states_disabled_properties_opacity
160
+ );
161
+ background-color: var(
162
+ --recursica_ui-kit_components_radio-button_variants_selection-states_selected_variants_states_disabled_properties_colors_background-color
163
+ );
164
+ border-color: var(
165
+ --recursica_ui-kit_components_radio-button_variants_selection-states_selected_variants_states_disabled_properties_colors_border-color
166
+ );
167
+ }
168
+
169
+ .icon {
170
+ pointer-events: none;
171
+ width: var(--recursica_ui-kit_components_radio-button_properties_icon-size);
172
+ height: var(--recursica_ui-kit_components_radio-button_properties_icon-size);
173
+ }
174
+ /* No icon-color token exists for the unselected state (no icon is visible then) */
175
+ .radioChecked .icon {
176
+ color: var(
177
+ --recursica_ui-kit_components_radio-button_variants_selection-states_selected_properties_colors_icon-color
178
+ );
179
+ }
180
+ .root.disabled .radioChecked .icon {
181
+ color: var(
182
+ --recursica_ui-kit_components_radio-button_variants_selection-states_selected_variants_states_disabled_properties_colors_icon-color
183
+ );
184
+ }
185
+
186
+ .root .labelWrapper {
187
+ /* display: flex (not the browser default block) blockifies the native inline
188
+ <label> child per the CSS Display spec's flex-item blockification rule —
189
+ matches Mantine's own labelWrapper (inline-flex), whose flex context does
190
+ the same to its label. Without it, the label stays inline and its line box
191
+ picks up extra half-leading height, visually shifting it below vertical
192
+ center against the circle. */
193
+ display: flex;
194
+ flex-direction: column;
195
+ padding: 0; /* HARDCODE: structural layout reset */
196
+ margin: 0; /* HARDCODE: structural layout reset */
197
+ flex: 1;
198
+ min-width: 0; /* HARDCODE: forces text wrap boundary in flex child */
199
+ }
200
+
201
+ .root .label {
202
+ cursor: pointer; /* HARDCODE: interactive affordance */
203
+ padding: 0; /* HARDCODE: reset layout */
204
+ margin: 0; /* HARDCODE: reset layout */
205
+ word-wrap: break-word;
206
+ white-space: normal;
207
+ color: var(
208
+ --recursica_ui-kit_components_radio-button-item_properties_colors_text-color
209
+ );
210
+ font-family: var(
211
+ --recursica_ui-kit_components_radio-button-item_properties_text_font-family
212
+ );
213
+ font-size: var(
214
+ --recursica_ui-kit_components_radio-button-item_properties_text_font-size
215
+ );
216
+ font-weight: var(
217
+ --recursica_ui-kit_components_radio-button-item_properties_text_font-weight
218
+ );
219
+ line-height: var(
220
+ --recursica_ui-kit_components_radio-button-item_properties_text_line-height
221
+ );
222
+ font-style: var(
223
+ --recursica_ui-kit_components_radio-button-item_properties_text_font-style
224
+ );
225
+ letter-spacing: var(
226
+ --recursica_ui-kit_components_radio-button-item_properties_text_letter-spacing
227
+ );
228
+ text-decoration: var(
229
+ --recursica_ui-kit_components_radio-button-item_properties_text_text-decoration
230
+ );
231
+ text-transform: var(
232
+ --recursica_ui-kit_components_radio-button-item_properties_text_text-transform
233
+ );
234
+ }
235
+ .root:has(input:disabled) .label {
236
+ cursor: not-allowed; /* HARDCODE: disabled interaction */
237
+ color: var(
238
+ --recursica_ui-kit_components_radio-button-item_properties_colors_disabled-text
239
+ );
240
+ opacity: var(
241
+ --recursica_ui-kit_components_radio-button-item_variants_states_disabled_properties_opacity
242
+ );
243
+ }
244
+
245
+ /* description/error text renders via AssistiveElement directly (see Radio.tsx) —
246
+ it owns its own tokenized styling. AssistiveElement has no disabled state and
247
+ must never dim. */
@@ -0,0 +1,93 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Radio } from "./Radio";
3
+
4
+ const meta: Meta<typeof Radio> = {
5
+ title: "UI-Kit/Radio",
6
+ component: Radio,
7
+ tags: ["autodocs"],
8
+ parameters: {
9
+ docs: {
10
+ description: {
11
+ component: `
12
+ The \`Radio\` component represents a fundamental standalone boolean selection node mapping to the native HTML \`<input type="radio">\`.
13
+
14
+ > [!WARNING]
15
+ > This component represents the isolated primitive structure. If you need macro form configurations, standard vertical alignments, side-by-side array wrappers, or integrated assistive text and error borders natively, you MUST use the \`<Radio.Group>\` orchestrator instead!
16
+ `,
17
+ },
18
+ },
19
+ },
20
+ argTypes: {
21
+ disabled: {
22
+ control: "boolean",
23
+ },
24
+ checked: {
25
+ control: "boolean",
26
+ },
27
+ readOnly: {
28
+ control: "boolean",
29
+ },
30
+ error: {
31
+ control: "boolean",
32
+ },
33
+ defaultChecked: {
34
+ control: "boolean",
35
+ },
36
+ controlMaxWidth: { table: { disable: true } },
37
+ controlMinWidth: { table: { disable: true } },
38
+ },
39
+ };
40
+
41
+ export default meta;
42
+
43
+ type Story = StoryObj<typeof Radio>;
44
+
45
+ export const Default: Story = {
46
+ args: {
47
+ label: "Standard Radio Primitive",
48
+ },
49
+ };
50
+
51
+ export const SideBySideLayout: Story = {
52
+ args: {
53
+ label: "Opt-in form alignment",
54
+ formLayout: "side-by-side",
55
+ },
56
+ };
57
+
58
+ export const CheckedState: Story = {
59
+ args: {
60
+ ...Default.args,
61
+ defaultChecked: true,
62
+ },
63
+ };
64
+
65
+ export const DisabledUnchecked: Story = {
66
+ args: {
67
+ ...Default.args,
68
+ disabled: true,
69
+ },
70
+ };
71
+
72
+ export const DisabledChecked: Story = {
73
+ args: {
74
+ ...Default.args,
75
+ disabled: true,
76
+ defaultChecked: true,
77
+ },
78
+ };
79
+
80
+ export const ReadOnly: Story = {
81
+ args: {},
82
+ render: () => (
83
+ <div
84
+ style={{
85
+ display: "flex",
86
+ flexDirection: "column",
87
+ gap: "24px",
88
+ }}
89
+ >
90
+ <Radio label="Account Type" defaultChecked readOnly />
91
+ </div>
92
+ ),
93
+ };
@@ -0,0 +1 @@
1
+ // Placeholder for future Radio component tests. Add tests here if/when needed.
@@ -0,0 +1,223 @@
1
+ import { forwardRef } from "react";
2
+ import {
3
+ Radio as MuiRadio,
4
+ type RadioProps as MuiRadioProps,
5
+ } from "@mui/material";
6
+ import { type ReadOnlyControlProps } from "@recursica/adapter-common";
7
+ import { RadioGroup } from "./RadioGroup";
8
+ import {
9
+ filterStylingProps,
10
+ omitUnsupportedProps,
11
+ mergeClassNames,
12
+ type RecursicaOverStyled,
13
+ } from "../../utils/filterStylingProps";
14
+ import {
15
+ type RequireAccessibleLabel,
16
+ type RecursicaRadioProps,
17
+ } from "@recursica/adapter-common";
18
+ import {
19
+ FormControlLayout,
20
+ type FormControlLayoutProps,
21
+ } from "../FormControlLayout/FormControlLayout";
22
+ import { AssistiveElement } from "../AssistiveElement/AssistiveElement";
23
+
24
+ import styles from "./Radio.module.css";
25
+
26
+ const RadioIcon: React.FC<{
27
+ className?: string;
28
+ style?: React.CSSProperties;
29
+ }> = ({ className, style }) => (
30
+ <svg
31
+ xmlns="http://www.w3.org/2000/svg"
32
+ viewBox="0 0 16 16"
33
+ fill="currentColor"
34
+ className={className}
35
+ style={style}
36
+ >
37
+ <circle cx="8" cy="8" r="5" />
38
+ </svg>
39
+ );
40
+
41
+ export type RadioWrapperProps = Omit<MuiRadioProps, "size" | "color"> &
42
+ RecursicaRadioProps &
43
+ ReadOnlyControlProps &
44
+ Pick<
45
+ FormControlLayoutProps,
46
+ "formLayout" | "labelSize" | "controlMaxWidth" | "controlMinWidth"
47
+ >;
48
+
49
+ export type RecursicaRadioPropsAlias =
50
+ RequireAccessibleLabel<RadioWrapperProps>;
51
+
52
+ export type RadioProps = RecursicaOverStyled<RecursicaRadioPropsAlias>;
53
+
54
+ type RadioComponent = React.ForwardRefExoticComponent<
55
+ RadioProps & React.RefAttributes<HTMLInputElement>
56
+ > & {
57
+ Group: typeof RadioGroup;
58
+ };
59
+
60
+ export const Radio = forwardRef<HTMLInputElement, RadioProps>(
61
+ function Radio(props, ref) {
62
+ const {
63
+ overStyled = false,
64
+ readOnly,
65
+ readOnlyComponent,
66
+ disabled,
67
+ formLayout,
68
+ labelSize,
69
+ controlMaxWidth,
70
+ controlMinWidth,
71
+ label,
72
+ description,
73
+ error,
74
+ style,
75
+ ...rest
76
+ } = props;
77
+ // Props this component intentionally doesn't support — deleted at runtime so they can't leak
78
+ // through even if a caller forces them via plain JavaScript, bypassing the Omit<> above.
79
+ const UNSUPPORTED_PROPS = [
80
+ "size", // Recursica controls sizing via design tokens, not MUI's native small/medium size
81
+ "color", // Colors are token-driven; MUI's native palette isn't exposed
82
+ ] as const satisfies readonly (keyof MuiRadioProps)[];
83
+
84
+ const sanitizedProps = omitUnsupportedProps(
85
+ filterStylingProps(rest, overStyled),
86
+ UNSUPPORTED_PROPS,
87
+ );
88
+ const restRecord = sanitizedProps as Record<string, unknown>;
89
+
90
+ // NOTE: MUI's actual prop is "classes", not "classNames" (that's Mantine's naming) — this
91
+ // was reading the wrong key and silently doing nothing. Fixed. Also "body"/"inner"/"radio"/
92
+ // "icon"/"labelWrapper"/"label" below were never real MUI `classes` slots (MUI's Radio only
93
+ // recognizes root/checked/disabled/colorPrimary/colorSecondary/sizeSmall, plus "input" from
94
+ // the underlying SwitchBase) — those slot names are Mantine's own Radio classNames API,
95
+ // copy-pasted over verbatim. Since none of them existed as real slots, MUI silently dropped
96
+ // them, so the circle (all its background/border CSS lived under `.radio`) never rendered —
97
+ // only the label showed. Fixed by keeping only the real slots here and drawing the circle as
98
+ // our own combined icon/checkedIcon node instead (see radioNode below), same pattern already
99
+ // used by Checkbox.
100
+ const mergedClassNames = mergeClassNames(
101
+ {
102
+ root: styles.root,
103
+ checked: styles.checked,
104
+ disabled: styles.disabled,
105
+ },
106
+ restRecord.classes as Partial<Record<string, string>> | undefined,
107
+ );
108
+
109
+ const classNameProp = restRecord.className as string | undefined;
110
+ const finalClass = classNameProp
111
+ ? `${styles.root} ${classNameProp}`
112
+ : styles.root;
113
+
114
+ if (readOnly && !!readOnlyComponent) {
115
+ const isChecked = !!(restRecord.checked ?? restRecord.defaultChecked);
116
+ const ReadOnlyComp = readOnlyComponent;
117
+ const roNode = (
118
+ <ReadOnlyComp
119
+ {...props}
120
+ checked={isChecked}
121
+ label={restRecord.label as React.ReactNode}
122
+ />
123
+ );
124
+
125
+ if (formLayout) {
126
+ return (
127
+ <FormControlLayout
128
+ formLayout={formLayout}
129
+ labelSize={labelSize}
130
+ controlMaxWidth={controlMaxWidth}
131
+ controlMinWidth={controlMinWidth}
132
+ >
133
+ {roNode}
134
+ </FormControlLayout>
135
+ );
136
+ }
137
+
138
+ return <>{roNode}</>;
139
+ }
140
+
141
+ // MUI's icon/checkedIcon fully replace the visual (they're the only child SwitchBase
142
+ // renders alongside the invisible native input) — so the ring + dot both have to live in
143
+ // one combined node per state, same pattern as Checkbox's icon/checkedIcon divs.
144
+ // sanitizedProps spreads FIRST: these render-critical props (icon/checkedIcon/className/
145
+ // classes/disabled/disableRipple/sx) must win over anything of the same name coming through
146
+ // from the caller, or they'd silently clobber the exact rendering this component depends on.
147
+ const radioNode = (
148
+ <MuiRadio
149
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
150
+ ref={ref as any}
151
+ {...(sanitizedProps as unknown as MuiRadioProps)}
152
+ icon={<div className={styles.radio} />}
153
+ checkedIcon={
154
+ <div className={`${styles.radio} ${styles.radioChecked}`}>
155
+ <RadioIcon className={styles.icon} />
156
+ </div>
157
+ }
158
+ className={!label ? `${finalClass} ${styles.inner}` : styles.inner}
159
+ classes={mergedClassNames}
160
+ disabled={readOnly || disabled}
161
+ disableRipple
162
+ sx={label ? { padding: 0 } : undefined}
163
+ />
164
+ );
165
+
166
+ const finalNode = label ? (
167
+ <div className={finalClass} style={style as React.CSSProperties}>
168
+ <div className={styles.body}>
169
+ {radioNode}
170
+ <div className={styles.labelWrapper}>
171
+ <label
172
+ className={styles.label}
173
+ htmlFor={restRecord.id as string}
174
+ data-disabled={readOnly || disabled ? true : undefined}
175
+ >
176
+ {label as React.ReactNode}
177
+ </label>
178
+ {/* description/error are mutually exclusive — error takes precedence */}
179
+ {error ? (
180
+ <AssistiveElement
181
+ assistiveVariant="error"
182
+ assistiveWithIcon={false}
183
+ >
184
+ {error}
185
+ </AssistiveElement>
186
+ ) : (
187
+ description && (
188
+ <AssistiveElement
189
+ assistiveVariant="help"
190
+ assistiveWithIcon={false}
191
+ >
192
+ {description}
193
+ </AssistiveElement>
194
+ )
195
+ )}
196
+ </div>
197
+ </div>
198
+ </div>
199
+ ) : (
200
+ <div className={finalClass} style={style as React.CSSProperties}>
201
+ {radioNode}
202
+ </div>
203
+ );
204
+
205
+ if (formLayout) {
206
+ return (
207
+ <FormControlLayout
208
+ formLayout={formLayout}
209
+ labelSize={labelSize}
210
+ controlMaxWidth={controlMaxWidth}
211
+ controlMinWidth={controlMinWidth}
212
+ >
213
+ {finalNode}
214
+ </FormControlLayout>
215
+ );
216
+ }
217
+
218
+ return finalNode;
219
+ },
220
+ ) as RadioComponent;
221
+
222
+ Radio.displayName = "Radio";
223
+ Radio.Group = RadioGroup;
@@ -0,0 +1,117 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Radio } from "./Radio";
3
+ import { RadioGroup } from "./RadioGroup";
4
+ import { useState } from "react";
5
+ import { formControlArgTypes } from "../../../.storybook/commonArgTypes";
6
+
7
+ const meta: Meta<typeof RadioGroup> = {
8
+ title: "UI-Kit/RadioGroup",
9
+ component: RadioGroup,
10
+ tags: ["autodocs"],
11
+ parameters: {
12
+ docs: {
13
+ description: {
14
+ component: `
15
+ The \`RadioGroup\` component is the mandatory organizational wrapper aggregating multiple \`Radio\` primitives into structurally bound unified selection arrays. It inherently leverages the \`FormControlWrapper\` granting native access to macroscopic layout structuring, assistive descriptions, and strict flex arrays.
16
+
17
+ We exclusively utilize the \`formLayout\` parameter to control macro-level form flow:
18
+ - **\`formLayout="stacked"\`**: Top-to-bottom layout cascading the Label bounding box down vertically into a standard stacked radio column array.
19
+ - **\`formLayout="side-by-side"\`**: Flow architecture pulling the grouping Label dynamically to the left while structurally organizing the internal radios cleanly alongside it horizontally.
20
+ `,
21
+ },
22
+ },
23
+ },
24
+ argTypes: {
25
+ ...formControlArgTypes,
26
+ readOnly: {
27
+ control: "boolean",
28
+ description:
29
+ "Toggles structural read-only data presentation bypassing interaction boundaries completely.",
30
+ },
31
+ },
32
+ };
33
+
34
+ export default meta;
35
+
36
+ type Story = StoryObj<typeof RadioGroup>;
37
+
38
+ export const Default: Story = {
39
+ args: {
40
+ formLayout: "stacked",
41
+ label: "Standard Group",
42
+ },
43
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
44
+ render: function StoryRender({ withLayer, layer, ...args }: any) {
45
+ const [value, setValue] = useState<string>("");
46
+ return (
47
+ <RadioGroup {...args} value={value} onChange={(_e, val) => setValue(val)}>
48
+ <Radio value="1" label="Option 1" />
49
+ <Radio value="2" label="Option 2" />
50
+ </RadioGroup>
51
+ );
52
+ },
53
+ };
54
+
55
+ export const StackedLayout: Story = {
56
+ args: {
57
+ formLayout: "stacked",
58
+ required: true,
59
+ label: "Hosting Provider",
60
+ error: "You must select a deployment provider.",
61
+ },
62
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
63
+ render: function StoryRender({ withLayer, layer, ...args }: any) {
64
+ const [value, setValue] = useState<string>("aws");
65
+ return (
66
+ <RadioGroup {...args} value={value} onChange={(_e, val) => setValue(val)}>
67
+ <Radio value="aws" label="Amazon Web Services" />
68
+ <Radio
69
+ value="gcp"
70
+ label="Google Cloud Platform (with completely distributed edge computing environments bridging local runtime boundaries seamlessly.)"
71
+ />
72
+ <Radio value="azure" label="Microsoft Azure" />
73
+ </RadioGroup>
74
+ );
75
+ },
76
+ };
77
+
78
+ export const SideBySideLayout: Story = {
79
+ args: {
80
+ formLayout: "side-by-side",
81
+ labelOptionalText: "Recommended",
82
+ labelWithEditIcon: true,
83
+ label: "Deployment Region",
84
+ assistiveText: "Select the data center closest to your user base.",
85
+ },
86
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
87
+ render: function StoryRender({ withLayer, layer, ...args }: any) {
88
+ const [value, setValue] = useState<string>("us-east");
89
+ return (
90
+ <RadioGroup {...args} value={value} onChange={(_e, val) => setValue(val)}>
91
+ <Radio value="us-east" label="US East (N. Virginia)" />
92
+ <Radio value="us-west" label="US West (Oregon)" />
93
+ <Radio value="eu-central" label="EU Central (Frankfurt)" />
94
+ </RadioGroup>
95
+ );
96
+ },
97
+ };
98
+
99
+ export const ReadOnly: Story = {
100
+ args: {
101
+ readOnly: true,
102
+ formLayout: "stacked",
103
+ required: true,
104
+ label: "Selected Framework",
105
+ assistiveText: "This selection cannot be changed after initialization.",
106
+ },
107
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
108
+ render: function StoryRender({ withLayer, layer, ...args }: any) {
109
+ const [value, setValue] = useState<string>("react");
110
+ return (
111
+ <RadioGroup {...args} value={value} onChange={(_e, val) => setValue(val)}>
112
+ <Radio value="react" label="React" />
113
+ <Radio value="vue" label="Vue" />
114
+ </RadioGroup>
115
+ );
116
+ },
117
+ };