@recursica/mantine-adapter 0.9.4 → 0.11.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 (290) hide show
  1. package/.storybook/commonArgTypes.ts +148 -0
  2. package/CHANGELOG.md +94 -0
  3. package/README.md +48 -332
  4. package/dist/index.d.ts +2 -8
  5. package/dist/mantine-adapter.cjs +2 -0
  6. package/dist/mantine-adapter.cjs.map +1 -0
  7. package/dist/mantine-adapter.css +1 -0
  8. package/dist/mantine-adapter.js +1963 -0
  9. package/dist/mantine-adapter.js.map +1 -0
  10. package/dist/src/components/Accordion/Accordion.d.ts +42 -0
  11. package/dist/src/components/Accordion/index.d.ts +1 -0
  12. package/dist/src/components/AssistiveElement/AssistiveElement.d.ts +10 -0
  13. package/dist/src/components/Avatar/Avatar.d.ts +9 -0
  14. package/dist/src/components/Avatar/index.d.ts +1 -0
  15. package/dist/src/components/Badge/Badge.d.ts +8 -0
  16. package/dist/src/components/Breadcrumb/Breadcrumb.d.ts +6 -0
  17. package/dist/src/components/Button/Button.d.ts +10 -0
  18. package/dist/src/components/Button/index.d.ts +1 -0
  19. package/dist/src/components/Card/Card.d.ts +38 -0
  20. package/dist/src/components/Checkbox/Checkbox.d.ts +13 -0
  21. package/dist/src/components/Checkbox/CheckboxGroup.d.ts +9 -0
  22. package/dist/src/components/Chip/Chip.d.ts +15 -0
  23. package/dist/src/components/Container/Container.d.ts +18 -0
  24. package/dist/src/components/DatePicker/DatePicker.d.ts +3 -0
  25. package/dist/src/components/Dropdown/Dropdown.d.ts +11 -0
  26. package/dist/src/components/FileInput/FileInput.d.ts +3 -0
  27. package/dist/src/components/FileUpload/FileUpload.d.ts +3 -0
  28. package/dist/src/components/Flex/Flex.d.ts +17 -0
  29. package/dist/src/components/FormControlLayout/FormControlLayout.d.ts +21 -0
  30. package/dist/src/components/FormControlWrapper/FormControlWrapper.d.ts +20 -0
  31. package/dist/src/components/Group/Group.d.ts +17 -0
  32. package/dist/src/components/HoverCard/HoverCard.d.ts +3 -0
  33. package/dist/src/components/Label/Label.d.ts +19 -0
  34. package/dist/src/components/Label/index.d.ts +1 -0
  35. package/dist/src/components/Link/Link.d.ts +3 -0
  36. package/dist/src/components/Loader/Loader.d.ts +10 -0
  37. package/dist/src/components/Menu/Menu.d.ts +3 -0
  38. package/dist/src/components/Modal/Modal.d.ts +3 -0
  39. package/dist/src/components/NumberInput/NumberInput.d.ts +3 -0
  40. package/dist/src/components/Pagination/Pagination.d.ts +3 -0
  41. package/dist/src/components/Panel/Panel.d.ts +3 -0
  42. package/dist/src/components/Popover/Popover.d.ts +3 -0
  43. package/dist/src/components/Radio/Radio.d.ts +13 -0
  44. package/dist/src/components/Radio/RadioGroup.d.ts +9 -0
  45. package/dist/src/components/ReadOnlyField/ReadOnlyBooleanField.d.ts +5 -0
  46. package/dist/src/components/ReadOnlyField/ReadOnlyField.d.ts +20 -0
  47. package/dist/src/components/ReadOnlyField/ReadOnlySwitchField.d.ts +5 -0
  48. package/dist/src/components/ReadOnlyField/ReadOnlyTextField.d.ts +8 -0
  49. package/dist/src/components/ReadOnlyField/WithReadOnlyWrapper.d.ts +28 -0
  50. package/dist/src/components/ReadOnlyField/index.d.ts +5 -0
  51. package/dist/src/components/Search/Search.d.ts +3 -0
  52. package/dist/src/components/SegmentedControl/SegmentedControl.d.ts +3 -0
  53. package/dist/src/components/Slider/Slider.d.ts +3 -0
  54. package/dist/src/components/Stack/Stack.d.ts +15 -0
  55. package/dist/src/components/Stepper/Stepper.d.ts +3 -0
  56. package/dist/src/components/Switch/Switch.d.ts +13 -0
  57. package/dist/src/components/Switch/SwitchGroup.d.ts +9 -0
  58. package/dist/src/components/Table/Table.d.ts +3 -0
  59. package/dist/src/components/Tabs/Tabs.d.ts +3 -0
  60. package/dist/src/components/Text/Text.d.ts +17 -0
  61. package/dist/src/components/TextArea/TextArea.d.ts +15 -0
  62. package/dist/src/components/TextField/TextField.d.ts +9 -0
  63. package/dist/src/components/TimePicker/TimePicker.d.ts +3 -0
  64. package/dist/src/components/Timeline/Timeline.d.ts +3 -0
  65. package/dist/src/components/Title/Title.d.ts +13 -0
  66. package/dist/src/components/Toast/Toast.d.ts +3 -0
  67. package/dist/src/components/Tooltip/Tooltip.d.ts +3 -0
  68. package/dist/src/components/TransferList/TransferList.d.ts +3 -0
  69. package/dist/src/components/index.d.ts +48 -0
  70. package/dist/src/index.d.ts +2 -0
  71. package/dist/src/types/index.d.ts +6 -0
  72. package/dist/src/utils/ColorSchemeWrapper.d.ts +3 -0
  73. package/dist/src/utils/RequireAccessibleLabel.d.ts +18 -0
  74. package/dist/src/utils/copyToClipboard.d.ts +8 -0
  75. package/dist/src/utils/filterStylingProps.d.ts +36 -0
  76. package/dist/src/utils/index.d.ts +1 -0
  77. package/dist/vite.config.d.ts +2 -0
  78. package/dist/vite.svg +1 -0
  79. package/dist/vitest.workspace.d.ts +2 -0
  80. package/package.json +74 -35
  81. package/src/OverStyling.stories.tsx +174 -0
  82. package/src/Version.stories.tsx +56 -0
  83. package/src/components/Accordion/ACCORDION_IMPLEMENTATION_NOTES.md +48 -0
  84. package/src/components/Accordion/Accordion.module.css +282 -0
  85. package/src/components/Accordion/Accordion.stories.tsx +145 -0
  86. package/src/components/Accordion/Accordion.tsx +200 -0
  87. package/src/components/Accordion/index.ts +1 -0
  88. package/src/components/AssistiveElement/AssistiveElement.module.css +111 -0
  89. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +75 -0
  90. package/src/components/AssistiveElement/AssistiveElement.tsx +91 -0
  91. package/src/components/Avatar/AVATAR_IMPLEMENTATION_NOTES.md +24 -0
  92. package/src/components/Avatar/Avatar.module.css +340 -0
  93. package/src/components/Avatar/Avatar.stories.tsx +107 -0
  94. package/src/components/Avatar/Avatar.tsx +100 -0
  95. package/src/components/Avatar/index.ts +1 -0
  96. package/src/components/Badge/BADGE_IMPLEMENTATION_NOTES.md +18 -0
  97. package/src/components/Badge/Badge.module.css +124 -0
  98. package/src/components/Badge/Badge.stories.tsx +78 -0
  99. package/src/components/Badge/Badge.tsx +66 -0
  100. package/src/components/Breadcrumb/BREADCRUMB_IMPLEMENTATION_NOTES.md +14 -0
  101. package/src/components/Breadcrumb/Breadcrumb.module.css +26 -0
  102. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +77 -0
  103. package/src/components/Breadcrumb/Breadcrumb.tsx +64 -0
  104. package/src/components/Button/Button.module.css +275 -0
  105. package/src/components/Button/Button.stories.tsx +103 -0
  106. package/src/components/Button/Button.tsx +122 -0
  107. package/src/components/Button/IMPLEMENTATION_NOTES.md +45 -0
  108. package/src/components/Button/index.ts +1 -0
  109. package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +10 -0
  110. package/src/components/Card/Card.module.css +60 -0
  111. package/src/components/Card/Card.stories.tsx +141 -0
  112. package/src/components/Card/Card.tsx +176 -0
  113. package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +25 -0
  114. package/src/components/Checkbox/Checkbox.module.css +204 -0
  115. package/src/components/Checkbox/Checkbox.stories.tsx +94 -0
  116. package/src/components/Checkbox/Checkbox.tsx +159 -0
  117. package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
  118. package/src/components/Checkbox/CheckboxGroup.tsx +120 -0
  119. package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +35 -0
  120. package/src/components/Chip/Chip.module.css +218 -0
  121. package/src/components/Chip/Chip.stories.tsx +115 -0
  122. package/src/components/Chip/Chip.tsx +143 -0
  123. package/src/components/Container/CONTAINER_IMPLEMENTATION_NOTES.md +4 -0
  124. package/src/components/Container/Container.module.css +7 -0
  125. package/src/components/Container/Container.stories.tsx +118 -0
  126. package/src/components/Container/Container.tsx +89 -0
  127. package/src/components/DatePicker/DatePicker.stories.tsx +18 -0
  128. package/src/components/DatePicker/DatePicker.tsx +7 -0
  129. package/src/components/Dropdown/DROPDOWN_IMPLEMENTATION_NOTES.md +7 -0
  130. package/src/components/Dropdown/Dropdown.module.css +272 -0
  131. package/src/components/Dropdown/Dropdown.stories.tsx +91 -0
  132. package/src/components/Dropdown/Dropdown.tsx +174 -0
  133. package/src/components/FileInput/FileInput.stories.tsx +18 -0
  134. package/src/components/FileInput/FileInput.tsx +7 -0
  135. package/src/components/FileUpload/FileUpload.stories.tsx +18 -0
  136. package/src/components/FileUpload/FileUpload.tsx +7 -0
  137. package/src/components/Flex/FLEX_IMPLEMENTATION_NOTES.md +4 -0
  138. package/src/components/Flex/Flex.module.css +7 -0
  139. package/src/components/Flex/Flex.stories.tsx +128 -0
  140. package/src/components/Flex/Flex.tsx +68 -0
  141. package/src/components/FormControlLayout/FormControlLayout.module.css +80 -0
  142. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +82 -0
  143. package/src/components/FormControlLayout/FormControlLayout.tsx +78 -0
  144. package/src/components/FormControlWrapper/FORMCONTROLWRAPPER_IMPLEMENTATION_NOTES.md +32 -0
  145. package/src/components/FormControlWrapper/FormControlWrapper.module.css +8 -0
  146. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +129 -0
  147. package/src/components/FormControlWrapper/FormControlWrapper.tsx +157 -0
  148. package/src/components/Group/GROUP_IMPLEMENTATION_NOTES.md +4 -0
  149. package/src/components/Group/Group.module.css +7 -0
  150. package/src/components/Group/Group.stories.tsx +120 -0
  151. package/src/components/Group/Group.tsx +68 -0
  152. package/src/components/HoverCard/HoverCard.stories.tsx +17 -0
  153. package/src/components/HoverCard/HoverCard.tsx +7 -0
  154. package/src/components/Label/LABEL_IMPLEMENTATION_NOTES.md +48 -0
  155. package/src/components/Label/Label.module.css +140 -0
  156. package/src/components/Label/Label.stories.tsx +122 -0
  157. package/src/components/Label/Label.tsx +127 -0
  158. package/src/components/Label/index.ts +1 -0
  159. package/src/components/Link/Link.stories.tsx +17 -0
  160. package/src/components/Link/Link.tsx +7 -0
  161. package/src/components/Loader/Loader.module.css +60 -0
  162. package/src/components/Loader/Loader.stories.tsx +103 -0
  163. package/src/components/Loader/Loader.tsx +76 -0
  164. package/src/components/Menu/Menu.stories.tsx +17 -0
  165. package/src/components/Menu/Menu.tsx +7 -0
  166. package/src/components/Modal/Modal.stories.tsx +17 -0
  167. package/src/components/Modal/Modal.tsx +7 -0
  168. package/src/components/NumberInput/NumberInput.stories.tsx +18 -0
  169. package/src/components/NumberInput/NumberInput.tsx +7 -0
  170. package/src/components/Pagination/Pagination.stories.tsx +17 -0
  171. package/src/components/Pagination/Pagination.tsx +7 -0
  172. package/src/components/Panel/Panel.stories.tsx +17 -0
  173. package/src/components/Panel/Panel.tsx +7 -0
  174. package/src/components/Popover/Popover.stories.tsx +17 -0
  175. package/src/components/Popover/Popover.tsx +7 -0
  176. package/src/components/Radio/Radio.module.css +207 -0
  177. package/src/components/Radio/Radio.stories.tsx +90 -0
  178. package/src/components/Radio/Radio.tsx +174 -0
  179. package/src/components/Radio/RadioGroup.stories.tsx +117 -0
  180. package/src/components/Radio/RadioGroup.tsx +118 -0
  181. package/src/components/ReadOnlyField/READ_ONLY_FIELD_IMPLEMENTATION_NOTES.md +15 -0
  182. package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
  183. package/src/components/ReadOnlyField/ReadOnlyField.module.css +49 -0
  184. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +163 -0
  185. package/src/components/ReadOnlyField/ReadOnlyField.tsx +102 -0
  186. package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
  187. package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
  188. package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
  189. package/src/components/ReadOnlyField/index.ts +5 -0
  190. package/src/components/Search/Search.stories.tsx +17 -0
  191. package/src/components/Search/Search.tsx +7 -0
  192. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +18 -0
  193. package/src/components/SegmentedControl/SegmentedControl.tsx +7 -0
  194. package/src/components/Slider/Slider.stories.tsx +18 -0
  195. package/src/components/Slider/Slider.tsx +7 -0
  196. package/src/components/Stack/STACK_IMPLEMENTATION_NOTES.md +4 -0
  197. package/src/components/Stack/Stack.module.css +7 -0
  198. package/src/components/Stack/Stack.stories.tsx +108 -0
  199. package/src/components/Stack/Stack.tsx +66 -0
  200. package/src/components/Stepper/Stepper.stories.tsx +17 -0
  201. package/src/components/Stepper/Stepper.tsx +7 -0
  202. package/src/components/Switch/SWITCH_IMPLEMENTATION_NOTES.md +28 -0
  203. package/src/components/Switch/Switch.module.css +199 -0
  204. package/src/components/Switch/Switch.stories.tsx +111 -0
  205. package/src/components/Switch/Switch.tsx +168 -0
  206. package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
  207. package/src/components/Switch/SwitchGroup.tsx +118 -0
  208. package/src/components/Table/Table.stories.tsx +17 -0
  209. package/src/components/Table/Table.tsx +7 -0
  210. package/src/components/Tabs/Tabs.stories.tsx +17 -0
  211. package/src/components/Tabs/Tabs.tsx +7 -0
  212. package/src/components/Text/Text.stories.tsx +88 -0
  213. package/src/components/Text/Text.tsx +54 -0
  214. package/src/components/TextArea/TEXTAREA_IMPLEMENTATION_NOTES.md +7 -0
  215. package/src/components/TextArea/TextArea.module.css +225 -0
  216. package/src/components/TextArea/TextArea.stories.tsx +91 -0
  217. package/src/components/TextArea/TextArea.tsx +152 -0
  218. package/src/components/TextField/TEXTFIELD_IMPLEMENTATION_NOTES.md +19 -0
  219. package/src/components/TextField/TextField.module.css +225 -0
  220. package/src/components/TextField/TextField.stories.tsx +162 -0
  221. package/src/components/TextField/TextField.tsx +139 -0
  222. package/src/components/TimePicker/TimePicker.stories.tsx +18 -0
  223. package/src/components/TimePicker/TimePicker.tsx +7 -0
  224. package/src/components/Timeline/Timeline.stories.tsx +17 -0
  225. package/src/components/Timeline/Timeline.tsx +7 -0
  226. package/src/components/Title/Title.stories.tsx +63 -0
  227. package/src/components/Title/Title.tsx +45 -0
  228. package/src/components/Toast/Toast.stories.tsx +17 -0
  229. package/src/components/Toast/Toast.tsx +7 -0
  230. package/src/components/Tooltip/Tooltip.stories.tsx +17 -0
  231. package/src/components/Tooltip/Tooltip.tsx +7 -0
  232. package/src/components/TransferList/TransferList.stories.tsx +17 -0
  233. package/src/components/TransferList/TransferList.tsx +7 -0
  234. package/src/components/index.ts +48 -0
  235. package/src/env.d.ts +7 -0
  236. package/src/index.ts +3 -0
  237. package/src/types/index.ts +9 -0
  238. package/src/types/mantine.d.ts +7 -0
  239. package/src/types/scss-modules.d.ts +9 -0
  240. package/src/utils/ColorSchemeWrapper.tsx +27 -0
  241. package/src/utils/RequireAccessibleLabel.ts +12 -0
  242. package/src/utils/copyToClipboard.ts +36 -0
  243. package/src/utils/filterStylingProps.ts +141 -0
  244. package/src/utils/index.ts +1 -0
  245. package/dist/adapter/generateBorderRadiusType.d.ts +0 -3
  246. package/dist/adapter/generateBorderRadiusType.d.ts.map +0 -1
  247. package/dist/adapter/generateColorTypes.d.ts +0 -6
  248. package/dist/adapter/generateColorTypes.d.ts.map +0 -1
  249. package/dist/adapter/generateIcons.d.ts +0 -8
  250. package/dist/adapter/generateIcons.d.ts.map +0 -1
  251. package/dist/adapter/generateMantineTheme.d.ts +0 -19
  252. package/dist/adapter/generateMantineTheme.d.ts.map +0 -1
  253. package/dist/adapter/generatePrettierignore.d.ts +0 -3
  254. package/dist/adapter/generatePrettierignore.d.ts.map +0 -1
  255. package/dist/adapter/generateRecursicaObject.d.ts +0 -7
  256. package/dist/adapter/generateRecursicaObject.d.ts.map +0 -1
  257. package/dist/adapter/generateRecursicaThemes.d.ts +0 -12
  258. package/dist/adapter/generateRecursicaThemes.d.ts.map +0 -1
  259. package/dist/adapter/generateRecursicaTokens.d.ts +0 -3
  260. package/dist/adapter/generateRecursicaTokens.d.ts.map +0 -1
  261. package/dist/adapter/generateSpacersType.d.ts +0 -3
  262. package/dist/adapter/generateSpacersType.d.ts.map +0 -1
  263. package/dist/adapter/generateUiKit.d.ts +0 -8
  264. package/dist/adapter/generateUiKit.d.ts.map +0 -1
  265. package/dist/adapter/generateVanillaExtractThemes.d.ts +0 -12
  266. package/dist/adapter/generateVanillaExtractThemes.d.ts.map +0 -1
  267. package/dist/adapter/index.d.ts +0 -44
  268. package/dist/adapter/index.d.ts.map +0 -1
  269. package/dist/cli.d.ts +0 -6
  270. package/dist/cli.d.ts.map +0 -1
  271. package/dist/index.d.ts.map +0 -1
  272. package/dist/index.js +0 -921
  273. package/dist/index.js.map +0 -1
  274. package/dist/main.cjs +0 -928
  275. package/dist/main.cjs.map +0 -1
  276. package/dist/main.d.ts +0 -2
  277. package/dist/main.d.ts.map +0 -1
  278. package/dist/main.js +0 -926
  279. package/dist/main.js.map +0 -1
  280. package/dist/shared/processTokens.d.ts +0 -22
  281. package/dist/shared/processTokens.d.ts.map +0 -1
  282. package/dist/types.d.ts +0 -62
  283. package/dist/types.d.ts.map +0 -1
  284. package/dist/utils/fileCheck.d.ts +0 -8
  285. package/dist/utils/fileCheck.d.ts.map +0 -1
  286. package/dist/utils/loadConfig.d.ts +0 -24
  287. package/dist/utils/loadConfig.d.ts.map +0 -1
  288. package/dist/webworker.d.ts +0 -2
  289. package/dist/webworker.d.ts.map +0 -1
  290. package/dist/webworker.js +0 -791
@@ -0,0 +1,207 @@
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
+ 0
17
+ );
18
+ margin: 0; /* HARDCODE: structural reset; consider token if layout needs change */
19
+ display: flex !important;
20
+ flex-direction: column;
21
+ gap: var(
22
+ --recursica_ui-kit_components_radio-button-group_properties_item-gap,
23
+ 16px
24
+ );
25
+ }
26
+
27
+ /* SideBySide Variant */
28
+ .groupRoot[data-layout="side-by-side"] {
29
+ flex-direction: column;
30
+ flex-wrap: wrap;
31
+ padding-top: var(
32
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_vertical-padding
33
+ );
34
+ padding-bottom: var(
35
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_vertical-padding
36
+ );
37
+ margin-top: var(
38
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_top-bottom-margin
39
+ );
40
+ margin-bottom: var(
41
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_side-by-side_properties_top-bottom-margin
42
+ );
43
+ }
44
+
45
+ /* Stacked Variant */
46
+ .groupRoot[data-layout="stacked"] {
47
+ flex-direction: column;
48
+ margin-top: var(
49
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_stacked_properties_top-bottom-margin
50
+ );
51
+ margin-bottom: var(
52
+ --recursica_ui-kit_components_radio-button-group_variants_layouts_stacked_properties_top-bottom-margin
53
+ );
54
+ }
55
+
56
+ /* --- PRIMITIVE RADIO STYLES --- */
57
+
58
+ .root {
59
+ max-width: var(
60
+ --recursica_ui-kit_components_radio-button-item_properties_max-width
61
+ );
62
+ }
63
+
64
+ .body {
65
+ display: flex;
66
+ align-items: flex-start;
67
+ gap: var(
68
+ --recursica_ui-kit_components_radio-button-item_properties_label-gap
69
+ );
70
+ }
71
+
72
+ .inner {
73
+ display: flex !important;
74
+ align-items: center !important;
75
+ justify-content: center !important;
76
+ margin: 0 !important; /* HARDCODE: structural reset */
77
+ width: var(
78
+ --recursica_ui-kit_components_radio-button_properties_size
79
+ ) !important;
80
+ height: var(
81
+ --recursica_ui-kit_components_radio-button_properties_size
82
+ ) !important;
83
+ /* Mathematically syncs the physical input radio bounding block visually with the center of the text's first line natively. */
84
+ margin-top: calc(
85
+ (
86
+ var(
87
+ --recursica_ui-kit_components_radio-button-item_properties_text_line-height
88
+ ) *
89
+ var(
90
+ --recursica_ui-kit_components_radio-button-item_properties_text_font-size
91
+ ) -
92
+ var(--recursica_ui-kit_components_radio-button_properties_size)
93
+ ) /
94
+ 2
95
+ ) !important;
96
+ }
97
+
98
+ /* Base explicit reset masking underlying framework defaults */
99
+ .radio {
100
+ cursor: pointer; /* HARDCODE: core interaction behavior */
101
+ appearance: none; /* HARDCODE: reset native widget */
102
+ box-sizing: border-box !important; /* HARDCODE: ensures size includes borders */
103
+ width: var(
104
+ --recursica_ui-kit_components_radio-button_properties_size
105
+ ) !important;
106
+ height: var(
107
+ --recursica_ui-kit_components_radio-button_properties_size
108
+ ) !important;
109
+ border-radius: var(
110
+ --recursica_ui-kit_components_radio-button_properties_border-radius
111
+ ) !important;
112
+ border-width: var(
113
+ --recursica_ui-kit_components_radio-button_properties_border-size
114
+ ) !important;
115
+ border-style: solid; /* HARDCODE: normalize primitive border-style */
116
+
117
+ /* Standard unchecked state */
118
+ background-color: var(
119
+ --recursica_ui-kit_components_radio-button_properties_colors_background-unselected
120
+ ) !important;
121
+ border-color: var(
122
+ --recursica_ui-kit_components_radio-button_properties_colors_border-unselected
123
+ ) !important;
124
+ transition: all 0.2s ease; /* HARDCODE: consider global transition token */
125
+ }
126
+
127
+ /* Checked State */
128
+ .radio:checked {
129
+ background-color: var(
130
+ --recursica_ui-kit_components_radio-button_properties_colors_background-selected
131
+ ) !important;
132
+ border-color: var(
133
+ --recursica_ui-kit_components_radio-button_properties_colors_border-selected
134
+ ) !important;
135
+ }
136
+
137
+ /* Disabled State */
138
+ .radio:disabled {
139
+ cursor: not-allowed; /* HARDCODE: disabled state default */
140
+ opacity: var(
141
+ --recursica_ui-kit_components_radio-button_properties_disabled-opacity
142
+ ) !important;
143
+ background-color: var(
144
+ --recursica_ui-kit_components_radio-button_properties_colors_disabled-background
145
+ ) !important;
146
+ border-color: var(
147
+ --recursica_ui-kit_components_radio-button_properties_colors_disabled-border
148
+ ) !important;
149
+ }
150
+
151
+ .icon {
152
+ position: absolute;
153
+ inset: 0;
154
+ margin: auto;
155
+ pointer-events: none;
156
+ width: var(
157
+ --recursica_ui-kit_components_radio-button_properties_icon-size
158
+ ) !important;
159
+ height: var(
160
+ --recursica_ui-kit_components_radio-button_properties_icon-size
161
+ ) !important;
162
+ color: var(
163
+ --recursica_ui-kit_components_radio-button_properties_colors_icon-color
164
+ ) !important;
165
+ }
166
+ .radio:disabled + .iconWrapper .icon,
167
+ .radio:disabled + .icon {
168
+ color: var(
169
+ --recursica_ui-kit_components_radio-button_properties_colors_disabled-icon
170
+ ) !important;
171
+ }
172
+
173
+ .labelWrapper {
174
+ padding: 0 !important; /* HARDCODE: structural layout reset */
175
+ margin: 0 !important; /* HARDCODE: structural layout reset */
176
+ flex: 1;
177
+ min-width: 0; /* HARDCODE: forces text wrap boundary in flex child */
178
+ }
179
+
180
+ .label {
181
+ cursor: pointer; /* HARDCODE: interactive affordance */
182
+ padding: 0 !important; /* HARDCODE: reset layout */
183
+ margin: 0 !important; /* HARDCODE: reset layout */
184
+ word-wrap: break-word;
185
+ white-space: normal;
186
+ color: var(
187
+ --recursica_ui-kit_components_radio-button-item_properties_text_color
188
+ ) !important;
189
+ font-family: var(
190
+ --recursica_ui-kit_components_radio-button-item_properties_text_font-family
191
+ );
192
+ font-size: var(
193
+ --recursica_ui-kit_components_radio-button-item_properties_text_font-size
194
+ );
195
+ font-weight: var(
196
+ --recursica_ui-kit_components_radio-button-item_properties_text_font-weight
197
+ );
198
+ line-height: var(
199
+ --recursica_ui-kit_components_radio-button-item_properties_text_line-height
200
+ );
201
+ }
202
+ .root[data-disabled] .label {
203
+ cursor: not-allowed; /* HARDCODE: disabled interaction */
204
+ opacity: var(
205
+ --recursica_ui-kit_components_radio-button_properties_disabled-opacity
206
+ );
207
+ }
@@ -0,0 +1,90 @@
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
+ checked: {
22
+ control: "boolean",
23
+ },
24
+ readOnly: {
25
+ control: "boolean",
26
+ },
27
+ error: {
28
+ control: "boolean",
29
+ },
30
+ defaultChecked: {
31
+ control: "boolean",
32
+ },
33
+ controlMaxWidth: { table: { disable: true } },
34
+ controlMinWidth: { table: { disable: true } },
35
+ },
36
+ };
37
+
38
+ export default meta;
39
+
40
+ type Story = StoryObj<typeof Radio>;
41
+
42
+ export const Default: Story = {
43
+ args: {
44
+ label: "Standard Radio Primitive",
45
+ },
46
+ };
47
+
48
+ export const SideBySideLayout: Story = {
49
+ args: {
50
+ label: "Opt-in form alignment",
51
+ formLayout: "side-by-side",
52
+ },
53
+ };
54
+
55
+ export const CheckedState: Story = {
56
+ args: {
57
+ ...Default.args,
58
+ defaultChecked: true,
59
+ },
60
+ };
61
+
62
+ export const DisabledUnchecked: Story = {
63
+ args: {
64
+ ...Default.args,
65
+ disabled: true,
66
+ },
67
+ };
68
+
69
+ export const DisabledChecked: Story = {
70
+ args: {
71
+ ...Default.args,
72
+ disabled: true,
73
+ defaultChecked: true,
74
+ },
75
+ };
76
+
77
+ export const ReadOnly: Story = {
78
+ args: {},
79
+ render: () => (
80
+ <div
81
+ style={{
82
+ display: "flex",
83
+ flexDirection: "column",
84
+ gap: "24px",
85
+ }}
86
+ >
87
+ <Radio label="Account Type" defaultChecked readOnly />
88
+ </div>
89
+ ),
90
+ };
@@ -0,0 +1,174 @@
1
+ import { forwardRef } from "react";
2
+ import {
3
+ Radio as MantineRadio,
4
+ type RadioProps as MantineRadioProps,
5
+ } from "@mantine/core";
6
+ import { type ReadOnlyControlProps } from "@recursica/adapter-common";
7
+ import { RadioGroup } from "./RadioGroup";
8
+ import {
9
+ filterStylingProps,
10
+ type RecursicaOverStyled,
11
+ } from "../../utils/filterStylingProps";
12
+ import { type RequireAccessibleLabel } from "../../utils/RequireAccessibleLabel";
13
+ import {
14
+ FormControlLayout,
15
+ type FormControlLayoutProps,
16
+ } from "../FormControlLayout/FormControlLayout";
17
+
18
+ import styles from "./Radio.module.css";
19
+
20
+ const RadioIcon: React.FC<{
21
+ className?: string;
22
+ style?: React.CSSProperties;
23
+ }> = ({ className, style }) => (
24
+ <svg
25
+ xmlns="http://www.w3.org/2000/svg"
26
+ viewBox="0 0 16 16"
27
+ fill="currentColor"
28
+ className={className}
29
+ style={style}
30
+ >
31
+ <circle cx="8" cy="8" r="5" />
32
+ </svg>
33
+ );
34
+
35
+ export type RecursicaRadioProps = RequireAccessibleLabel<
36
+ Omit<
37
+ MantineRadioProps,
38
+ "size" | "color" | "radius" | "iconColor" | "variant"
39
+ > &
40
+ ReadOnlyControlProps &
41
+ Pick<
42
+ FormControlLayoutProps,
43
+ "formLayout" | "labelSize" | "controlMaxWidth" | "controlMinWidth"
44
+ >
45
+ >;
46
+
47
+ export type RadioProps = RecursicaOverStyled<RecursicaRadioProps>;
48
+
49
+ type RadioComponent = React.ForwardRefExoticComponent<
50
+ RadioProps & React.RefAttributes<HTMLInputElement>
51
+ > & {
52
+ Group: typeof RadioGroup;
53
+ };
54
+
55
+ export const Radio = forwardRef<HTMLInputElement, RadioProps>(
56
+ function Radio(props, ref) {
57
+ const {
58
+ overStyled = false,
59
+ readOnly,
60
+ readOnlyComponent,
61
+ disabled,
62
+ formLayout,
63
+ labelSize,
64
+ controlMaxWidth,
65
+ controlMinWidth,
66
+ ...rest
67
+ } = props;
68
+ const sanitizedProps = filterStylingProps(rest, overStyled);
69
+ const restRecord = sanitizedProps as Record<string, unknown>;
70
+
71
+ // Actively delete dimension bindings that bypass the abstraction
72
+ delete restRecord["size"];
73
+ delete restRecord["color"];
74
+ delete restRecord["radius"];
75
+ delete restRecord["variant"];
76
+ delete restRecord["iconColor"];
77
+
78
+ const mergedClassNames: Partial<Record<string, string>> = {
79
+ root: styles.root,
80
+ body: styles.body,
81
+ inner: styles.inner,
82
+ radio: styles.radio,
83
+ icon: styles.icon,
84
+ labelWrapper: styles.labelWrapper,
85
+ label: styles.label,
86
+ };
87
+
88
+ const classNamesProp = restRecord.classNames;
89
+ if (
90
+ classNamesProp &&
91
+ typeof classNamesProp === "object" &&
92
+ !Array.isArray(classNamesProp)
93
+ ) {
94
+ const o = classNamesProp as Partial<Record<string, string>>;
95
+ mergedClassNames.root = o.root ? `${styles.root} ${o.root}` : styles.root;
96
+ mergedClassNames.body = o.body ? `${styles.body} ${o.body}` : styles.body;
97
+ mergedClassNames.inner = o.inner
98
+ ? `${styles.inner} ${o.inner}`
99
+ : styles.inner;
100
+ mergedClassNames.radio = o.radio
101
+ ? `${styles.radio} ${o.radio}`
102
+ : styles.radio;
103
+ mergedClassNames.icon = o.icon ? `${styles.icon} ${o.icon}` : styles.icon;
104
+ mergedClassNames.labelWrapper = o.labelWrapper
105
+ ? `${styles.labelWrapper} ${o.labelWrapper}`
106
+ : styles.labelWrapper;
107
+ mergedClassNames.label = o.label
108
+ ? `${styles.label} ${o.label}`
109
+ : styles.label;
110
+ }
111
+
112
+ const classNameProp = restRecord.className as string | undefined;
113
+ const finalClass = classNameProp
114
+ ? `${styles.root} ${classNameProp}`
115
+ : styles.root;
116
+
117
+ if (readOnly && !!readOnlyComponent) {
118
+ const isChecked = !!(restRecord.checked ?? restRecord.defaultChecked);
119
+ const ReadOnlyComp = readOnlyComponent;
120
+ const roNode = (
121
+ <ReadOnlyComp
122
+ {...props}
123
+ checked={isChecked}
124
+ label={restRecord.label as React.ReactNode}
125
+ />
126
+ );
127
+
128
+ if (formLayout) {
129
+ return (
130
+ <FormControlLayout
131
+ formLayout={formLayout}
132
+ labelSize={labelSize}
133
+ controlMaxWidth={controlMaxWidth}
134
+ controlMinWidth={controlMinWidth}
135
+ >
136
+ {roNode}
137
+ </FormControlLayout>
138
+ );
139
+ }
140
+
141
+ return <>{roNode}</>;
142
+ }
143
+
144
+ // We omit Mantine's sizing/coloring so we rely strictly on variables from Radio.module.css
145
+ const radioNode = (
146
+ <MantineRadio
147
+ ref={ref}
148
+ icon={RadioIcon}
149
+ className={finalClass}
150
+ classNames={mergedClassNames}
151
+ disabled={readOnly || disabled}
152
+ {...(sanitizedProps as unknown as MantineRadioProps)}
153
+ />
154
+ );
155
+
156
+ if (formLayout) {
157
+ return (
158
+ <FormControlLayout
159
+ formLayout={formLayout}
160
+ labelSize={labelSize}
161
+ controlMaxWidth={controlMaxWidth}
162
+ controlMinWidth={controlMinWidth}
163
+ >
164
+ {radioNode}
165
+ </FormControlLayout>
166
+ );
167
+ }
168
+
169
+ return radioNode;
170
+ },
171
+ ) as RadioComponent;
172
+
173
+ Radio.displayName = "Radio";
174
+ 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={setValue}>
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={setValue}>
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={setValue}>
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={setValue}>
112
+ <Radio value="react" label="React" />
113
+ <Radio value="vue" label="Vue" />
114
+ </RadioGroup>
115
+ );
116
+ },
117
+ };
@@ -0,0 +1,118 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import React, { forwardRef } from "react";
3
+ import {
4
+ Radio as MantineRadio,
5
+ type RadioGroupProps as MantineRadioGroupProps,
6
+ } from "@mantine/core";
7
+ import { type ReadOnlyControlProps } from "@recursica/adapter-common";
8
+ import {
9
+ filterStylingProps,
10
+ type RecursicaOverStyled,
11
+ } from "../../utils/filterStylingProps";
12
+ import { type RecursicaFormControlWrapperProps } from "../FormControlWrapper/FormControlWrapper";
13
+ import { WithReadOnlyWrapper } from "../ReadOnlyField/WithReadOnlyWrapper";
14
+ import styles from "./Radio.module.css";
15
+
16
+ export interface RecursicaRadioGroupProps
17
+ extends Omit<MantineRadioGroupProps, "size" | "labelProps">,
18
+ Omit<
19
+ RecursicaFormControlWrapperProps,
20
+ "controlMaxWidth" | "controlMinWidth"
21
+ >,
22
+ ReadOnlyControlProps {}
23
+
24
+ export type RadioGroupProps = RecursicaOverStyled<RecursicaRadioGroupProps>;
25
+
26
+ export const RadioGroup = forwardRef<HTMLDivElement, RadioGroupProps>(
27
+ function RadioGroup(props, ref) {
28
+ const {
29
+ overStyled = false,
30
+ formLayout = "stacked",
31
+
32
+ // Label Wrappers
33
+ labelSize,
34
+ labelAlignment,
35
+ labelOptionalText,
36
+ labelWithEditIcon,
37
+ onLabelEditClick,
38
+
39
+ // Base Mantine Extracted Attributes
40
+ label,
41
+ description,
42
+ assistiveText,
43
+ assistiveWithIcon,
44
+ error,
45
+ required,
46
+ withAsterisk,
47
+ id,
48
+ className,
49
+ style,
50
+ children,
51
+ readOnly,
52
+ readOnlyComponent,
53
+ emptyValueComponent,
54
+ value,
55
+ defaultValue,
56
+ ...rest
57
+ } = props;
58
+ const sanitizedProps = filterStylingProps(rest, overStyled);
59
+ const restRecord = sanitizedProps as Record<string, unknown>;
60
+
61
+ // Delete prohibited sizing hooks from bypassing the variables
62
+ delete restRecord["size"];
63
+
64
+ return (
65
+ <WithReadOnlyWrapper
66
+ className={className}
67
+ style={style as React.CSSProperties}
68
+ controlMaxWidth="var(--recursica_ui-kit_components_radio-button-item_properties_max-width)"
69
+ controlMinWidth={undefined}
70
+ overStyled={overStyled as true}
71
+ labelElement="div" // Strictly override. ARIA grouping prohibits interactive radios nested natively inside <label>.
72
+ formLayout={formLayout}
73
+ labelSize={labelSize}
74
+ labelAlignment={labelAlignment}
75
+ labelOptionalText={labelOptionalText}
76
+ labelWithEditIcon={labelWithEditIcon}
77
+ onLabelEditClick={onLabelEditClick}
78
+ label={label}
79
+ description={description}
80
+ assistiveText={assistiveText}
81
+ assistiveWithIcon={assistiveWithIcon}
82
+ error={error}
83
+ required={required}
84
+ withAsterisk={withAsterisk}
85
+ id={id}
86
+ readOnly={readOnly && !!readOnlyComponent}
87
+ readOnlyComponent={readOnlyComponent}
88
+ emptyValueComponent={emptyValueComponent}
89
+ readOnlyType="text"
90
+ readOnlyValue={value !== undefined ? value : defaultValue}
91
+ readOnlyNativeProps={props}
92
+ activeComponent={
93
+ <MantineRadio.Group
94
+ ref={ref}
95
+ /* Natively bind local disabled lock dynamically */
96
+ {...(sanitizedProps as unknown as MantineRadioGroupProps)}
97
+ disabled={readOnly || (restRecord as any).disabled}
98
+ value={value}
99
+ defaultValue={defaultValue}
100
+ >
101
+ <div className={styles.groupRoot} data-layout={formLayout}>
102
+ {React.Children.map(children, (child) => {
103
+ if (React.isValidElement(child)) {
104
+ return React.cloneElement(child as React.ReactElement<any>, {
105
+ disabled: readOnly || (child.props as any).disabled,
106
+ });
107
+ }
108
+ return child;
109
+ })}
110
+ </div>
111
+ </MantineRadio.Group>
112
+ }
113
+ />
114
+ );
115
+ },
116
+ );
117
+
118
+ RadioGroup.displayName = "RadioGroup";