@recursica/adapter-mantine-v8 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 (362) hide show
  1. package/.storybook/commonArgTypes.ts +148 -0
  2. package/ARCHITECTURE.md +18 -0
  3. package/CHANGELOG.md +688 -0
  4. package/LICENSE +21 -0
  5. package/OVERSTYLING.md +56 -0
  6. package/README.md +70 -0
  7. package/SETUP.md +93 -0
  8. package/USAGE.md +57 -0
  9. package/dist/adapter-mantine-v8.cjs +12 -0
  10. package/dist/adapter-mantine-v8.cjs.map +1 -0
  11. package/dist/adapter-mantine-v8.css +1 -0
  12. package/dist/adapter-mantine-v8.js +5759 -0
  13. package/dist/adapter-mantine-v8.js.map +1 -0
  14. package/dist/index.d.ts +2095 -0
  15. package/dist/test.html +1 -0
  16. package/dist/vite.svg +1 -0
  17. package/docs/PHILOSOPHY.md +39 -0
  18. package/llms.txt +74 -0
  19. package/package.json +131 -0
  20. package/recursica_brand.json +2677 -0
  21. package/recursica_tokens.json +799 -0
  22. package/recursica_ui-kit.json +14981 -0
  23. package/recursica_variables_scoped.css +30489 -0
  24. package/src/GlobalExemptions.modules.css +7 -0
  25. package/src/Introduction.stories.tsx +154 -0
  26. package/src/OverStyling.tsx +79 -0
  27. package/src/Version.tsx +44 -0
  28. package/src/components/Accordion/ACCORDION_IMPLEMENTATION_NOTES.md +72 -0
  29. package/src/components/Accordion/Accordion.module.css +367 -0
  30. package/src/components/Accordion/Accordion.stories.tsx +189 -0
  31. package/src/components/Accordion/Accordion.test.tsx +1 -0
  32. package/src/components/Accordion/Accordion.tsx +220 -0
  33. package/src/components/Accordion/USAGE.md +51 -0
  34. package/src/components/Accordion/index.ts +1 -0
  35. package/src/components/AssistiveElement/ASSISTIVEELEMENT_IMPLEMENTATION_NOTES.md +45 -0
  36. package/src/components/AssistiveElement/AssistiveElement.module.css +111 -0
  37. package/src/components/AssistiveElement/AssistiveElement.stories.tsx +68 -0
  38. package/src/components/AssistiveElement/AssistiveElement.test.tsx +1 -0
  39. package/src/components/AssistiveElement/AssistiveElement.tsx +93 -0
  40. package/src/components/AssistiveElement/USAGE.md +36 -0
  41. package/src/components/AutoComplete/AUTOCOMPLETE_IMPLEMENTATION_NOTES.md +42 -0
  42. package/src/components/AutoComplete/AutoComplete.module.css +430 -0
  43. package/src/components/AutoComplete/AutoComplete.stories.tsx +336 -0
  44. package/src/components/AutoComplete/AutoComplete.test.tsx +1 -0
  45. package/src/components/AutoComplete/AutoComplete.tsx +179 -0
  46. package/src/components/AutoComplete/USAGE.md +80 -0
  47. package/src/components/Avatar/AVATAR_IMPLEMENTATION_NOTES.md +34 -0
  48. package/src/components/Avatar/Avatar.module.css +336 -0
  49. package/src/components/Avatar/Avatar.stories.tsx +92 -0
  50. package/src/components/Avatar/Avatar.test.tsx +1 -0
  51. package/src/components/Avatar/Avatar.tsx +108 -0
  52. package/src/components/Avatar/USAGE.md +38 -0
  53. package/src/components/Avatar/index.ts +1 -0
  54. package/src/components/Badge/BADGE_IMPLEMENTATION_NOTES.md +18 -0
  55. package/src/components/Badge/Badge.module.css +127 -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 +64 -0
  59. package/src/components/Badge/USAGE.md +56 -0
  60. package/src/components/Breadcrumb/BREADCRUMB_IMPLEMENTATION_NOTES.md +47 -0
  61. package/src/components/Breadcrumb/Breadcrumb.module.css +48 -0
  62. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +114 -0
  63. package/src/components/Breadcrumb/Breadcrumb.test.tsx +1 -0
  64. package/src/components/Breadcrumb/Breadcrumb.tsx +85 -0
  65. package/src/components/Breadcrumb/USAGE.md +55 -0
  66. package/src/components/Breadcrumb/markCurrentPageItem.test.ts +49 -0
  67. package/src/components/Button/Button.module.css +446 -0
  68. package/src/components/Button/Button.stories.tsx +196 -0
  69. package/src/components/Button/Button.styleIsolation.dom.test.tsx +98 -0
  70. package/src/components/Button/Button.tsx +184 -0
  71. package/src/components/Button/IMPLEMENTATION_NOTES.md +109 -0
  72. package/src/components/Button/USAGE.md +80 -0
  73. package/src/components/Button/index.ts +1 -0
  74. package/src/components/Card/CARD_IMPLEMENTATION_NOTES.md +17 -0
  75. package/src/components/Card/Card.module.css +119 -0
  76. package/src/components/Card/Card.stories.tsx +131 -0
  77. package/src/components/Card/Card.test.tsx +1 -0
  78. package/src/components/Card/Card.tsx +248 -0
  79. package/src/components/Card/USAGE.md +63 -0
  80. package/src/components/Checkbox/CHECKBOX_IMPLEMENTATION_NOTES.md +25 -0
  81. package/src/components/Checkbox/Checkbox.module.css +267 -0
  82. package/src/components/Checkbox/Checkbox.stories.tsx +97 -0
  83. package/src/components/Checkbox/Checkbox.test.tsx +1 -0
  84. package/src/components/Checkbox/Checkbox.tsx +151 -0
  85. package/src/components/Checkbox/CheckboxGroup.stories.tsx +139 -0
  86. package/src/components/Checkbox/CheckboxGroup.tsx +147 -0
  87. package/src/components/Checkbox/USAGE.md +48 -0
  88. package/src/components/Chip/CHIP_IMPLEMENTATION_NOTES.md +110 -0
  89. package/src/components/Chip/Chip.module.css +288 -0
  90. package/src/components/Chip/Chip.stories.tsx +128 -0
  91. package/src/components/Chip/Chip.test.tsx +1 -0
  92. package/src/components/Chip/Chip.tsx +157 -0
  93. package/src/components/Chip/USAGE.md +55 -0
  94. package/src/components/Container/CONTAINER_IMPLEMENTATION_NOTES.md +4 -0
  95. package/src/components/Container/Container.module.css +7 -0
  96. package/src/components/Container/Container.stories.tsx +118 -0
  97. package/src/components/Container/Container.test.tsx +1 -0
  98. package/src/components/Container/Container.tsx +69 -0
  99. package/src/components/Container/USAGE.md +47 -0
  100. package/src/components/DatePicker/DATEPICKER_IMPLEMENTATION_NOTES.md +31 -0
  101. package/src/components/DatePicker/DatePicker.icons.tsx +27 -0
  102. package/src/components/DatePicker/DatePicker.module.css +566 -0
  103. package/src/components/DatePicker/DatePicker.stories.tsx +158 -0
  104. package/src/components/DatePicker/DatePicker.test.tsx +1 -0
  105. package/src/components/DatePicker/DatePicker.tsx +218 -0
  106. package/src/components/DatePicker/USAGE.md +49 -0
  107. package/src/components/Dropdown/BareDropdown.tsx +97 -0
  108. package/src/components/Dropdown/DROPDOWN_IMPLEMENTATION_NOTES.md +12 -0
  109. package/src/components/Dropdown/Dropdown.module.css +477 -0
  110. package/src/components/Dropdown/Dropdown.stories.tsx +252 -0
  111. package/src/components/Dropdown/Dropdown.test.tsx +1 -0
  112. package/src/components/Dropdown/Dropdown.tsx +213 -0
  113. package/src/components/Dropdown/USAGE.md +69 -0
  114. package/src/components/FileInput/FILEINPUT_IMPLEMENTATION_NOTES.md +153 -0
  115. package/src/components/FileInput/FileInput.module.css +280 -0
  116. package/src/components/FileInput/FileInput.stories.tsx +313 -0
  117. package/src/components/FileInput/FileInput.test.tsx +1 -0
  118. package/src/components/FileInput/FileInput.tsx +417 -0
  119. package/src/components/FileInput/USAGE.md +145 -0
  120. package/src/components/FileUpload/FILEUPLOAD_IMPLEMENTATION_NOTES.md +244 -0
  121. package/src/components/FileUpload/FileUpload.module.css +205 -0
  122. package/src/components/FileUpload/FileUpload.stories.tsx +362 -0
  123. package/src/components/FileUpload/FileUpload.test.tsx +1 -0
  124. package/src/components/FileUpload/FileUpload.tsx +354 -0
  125. package/src/components/FileUpload/USAGE.md +199 -0
  126. package/src/components/Flex/FLEX_IMPLEMENTATION_NOTES.md +4 -0
  127. package/src/components/Flex/Flex.module.css +7 -0
  128. package/src/components/Flex/Flex.stories.tsx +128 -0
  129. package/src/components/Flex/Flex.test.tsx +1 -0
  130. package/src/components/Flex/Flex.tsx +75 -0
  131. package/src/components/Flex/USAGE.md +48 -0
  132. package/src/components/FormControlLayout/FormControlLayout.module.css +90 -0
  133. package/src/components/FormControlLayout/FormControlLayout.stories.tsx +118 -0
  134. package/src/components/FormControlLayout/FormControlLayout.test.tsx +1 -0
  135. package/src/components/FormControlLayout/FormControlLayout.tsx +74 -0
  136. package/src/components/FormControlLayout/USAGE.md +40 -0
  137. package/src/components/FormControlWrapper/FORMCONTROLWRAPPER_IMPLEMENTATION_NOTES.md +32 -0
  138. package/src/components/FormControlWrapper/FormControlWrapper.module.css +75 -0
  139. package/src/components/FormControlWrapper/FormControlWrapper.stories.tsx +129 -0
  140. package/src/components/FormControlWrapper/FormControlWrapper.test.tsx +1 -0
  141. package/src/components/FormControlWrapper/FormControlWrapper.tsx +151 -0
  142. package/src/components/FormControlWrapper/USAGE.md +47 -0
  143. package/src/components/Grid/GRID_IMPLEMENTATION_NOTES.md +18 -0
  144. package/src/components/Grid/Grid.module.css +11 -0
  145. package/src/components/Grid/Grid.stories.tsx +206 -0
  146. package/src/components/Grid/Grid.test.tsx +1 -0
  147. package/src/components/Grid/Grid.tsx +140 -0
  148. package/src/components/Grid/USAGE.md +47 -0
  149. package/src/components/Group/GROUP_IMPLEMENTATION_NOTES.md +4 -0
  150. package/src/components/Group/Group.module.css +7 -0
  151. package/src/components/Group/Group.stories.tsx +120 -0
  152. package/src/components/Group/Group.test.tsx +1 -0
  153. package/src/components/Group/Group.tsx +60 -0
  154. package/src/components/Group/USAGE.md +48 -0
  155. package/src/components/Heading/HEADING_IMPLEMENTATION_NOTES.md +18 -0
  156. package/src/components/Heading/Heading.module.css +13 -0
  157. package/src/components/Heading/Heading.stories.tsx +50 -0
  158. package/src/components/Heading/Heading.test.tsx +1 -0
  159. package/src/components/Heading/Heading.tsx +52 -0
  160. package/src/components/Heading/USAGE.md +36 -0
  161. package/src/components/HoverCard/HOVERCARD_IMPLEMENTATION_NOTES.md +77 -0
  162. package/src/components/HoverCard/HoverCard.module.css +90 -0
  163. package/src/components/HoverCard/HoverCard.stories.tsx +172 -0
  164. package/src/components/HoverCard/HoverCard.test.tsx +1 -0
  165. package/src/components/HoverCard/HoverCard.tsx +133 -0
  166. package/src/components/HoverCard/USAGE.md +52 -0
  167. package/src/components/Label/LABEL_IMPLEMENTATION_NOTES.md +48 -0
  168. package/src/components/Label/Label.module.css +141 -0
  169. package/src/components/Label/Label.stories.tsx +131 -0
  170. package/src/components/Label/Label.test.tsx +1 -0
  171. package/src/components/Label/Label.tsx +113 -0
  172. package/src/components/Label/USAGE.md +47 -0
  173. package/src/components/Label/index.ts +1 -0
  174. package/src/components/Layer/USAGE.md +54 -0
  175. package/src/components/Link/IMPLEMENTATION_NOTES.md +19 -0
  176. package/src/components/Link/Link.module.css +110 -0
  177. package/src/components/Link/Link.stories.tsx +58 -0
  178. package/src/components/Link/Link.test.tsx +1 -0
  179. package/src/components/Link/Link.tsx +67 -0
  180. package/src/components/Link/USAGE.md +56 -0
  181. package/src/components/Link/index.ts +1 -0
  182. package/src/components/Loader/LOADER_IMPLEMENTATION_NOTES.md +24 -0
  183. package/src/components/Loader/Loader.animate.dom.test.tsx +82 -0
  184. package/src/components/Loader/Loader.module.css +63 -0
  185. package/src/components/Loader/Loader.stories.tsx +123 -0
  186. package/src/components/Loader/Loader.test.tsx +1 -0
  187. package/src/components/Loader/Loader.tsx +69 -0
  188. package/src/components/Loader/USAGE.md +44 -0
  189. package/src/components/Menu/MENU_IMPLEMENTATION_NOTES.md +88 -0
  190. package/src/components/Menu/Menu.module.css +280 -0
  191. package/src/components/Menu/Menu.stories.tsx +371 -0
  192. package/src/components/Menu/Menu.test.tsx +1 -0
  193. package/src/components/Menu/Menu.tsx +373 -0
  194. package/src/components/Menu/USAGE.md +55 -0
  195. package/src/components/Modal/MODAL_IMPLEMENTATION_NOTES.md +32 -0
  196. package/src/components/Modal/Modal.module.css +302 -0
  197. package/src/components/Modal/Modal.stories.tsx +105 -0
  198. package/src/components/Modal/Modal.test.tsx +1 -0
  199. package/src/components/Modal/Modal.tsx +368 -0
  200. package/src/components/Modal/USAGE.md +58 -0
  201. package/src/components/Modal/index.ts +1 -0
  202. package/src/components/NumberInput/NUMBER_INPUT_IMPLEMENTATION_NOTES.md +24 -0
  203. package/src/components/NumberInput/NumberInput.module.css +302 -0
  204. package/src/components/NumberInput/NumberInput.stories.tsx +96 -0
  205. package/src/components/NumberInput/NumberInput.test.tsx +1 -0
  206. package/src/components/NumberInput/NumberInput.tsx +157 -0
  207. package/src/components/NumberInput/USAGE.md +52 -0
  208. package/src/components/Pagination/IMPLEMENTATION_NOTES.md +16 -0
  209. package/src/components/Pagination/Pagination.icons.tsx +66 -0
  210. package/src/components/Pagination/Pagination.module.css +188 -0
  211. package/src/components/Pagination/Pagination.stories.tsx +48 -0
  212. package/src/components/Pagination/Pagination.test.tsx +1 -0
  213. package/src/components/Pagination/Pagination.tsx +265 -0
  214. package/src/components/Pagination/USAGE.md +36 -0
  215. package/src/components/Pagination/index.ts +5 -0
  216. package/src/components/Panel/PANEL_IMPLEMENTATION_NOTES.md +116 -0
  217. package/src/components/Panel/Panel.module.css +209 -0
  218. package/src/components/Panel/Panel.stories.tsx +227 -0
  219. package/src/components/Panel/Panel.test.tsx +1 -0
  220. package/src/components/Panel/Panel.tsx +269 -0
  221. package/src/components/Panel/USAGE.md +56 -0
  222. package/src/components/Popover/IMPLEMENTATION_NOTES.md +77 -0
  223. package/src/components/Popover/Popover.module.css +86 -0
  224. package/src/components/Popover/Popover.stories.tsx +133 -0
  225. package/src/components/Popover/Popover.test.tsx +1 -0
  226. package/src/components/Popover/Popover.tsx +142 -0
  227. package/src/components/Popover/USAGE.md +61 -0
  228. package/src/components/Popover/index.ts +1 -0
  229. package/src/components/Radio/Radio.module.css +231 -0
  230. package/src/components/Radio/Radio.stories.tsx +93 -0
  231. package/src/components/Radio/Radio.test.tsx +1 -0
  232. package/src/components/Radio/Radio.tsx +168 -0
  233. package/src/components/Radio/RadioGroup.stories.tsx +117 -0
  234. package/src/components/Radio/RadioGroup.tsx +124 -0
  235. package/src/components/Radio/USAGE.md +36 -0
  236. package/src/components/ReadOnlyField/READ_ONLY_FIELD_IMPLEMENTATION_NOTES.md +15 -0
  237. package/src/components/ReadOnlyField/ReadOnlyBooleanField.tsx +21 -0
  238. package/src/components/ReadOnlyField/ReadOnlyField.module.css +54 -0
  239. package/src/components/ReadOnlyField/ReadOnlyField.stories.tsx +163 -0
  240. package/src/components/ReadOnlyField/ReadOnlyField.test.tsx +1 -0
  241. package/src/components/ReadOnlyField/ReadOnlyField.tsx +114 -0
  242. package/src/components/ReadOnlyField/ReadOnlySwitchField.tsx +21 -0
  243. package/src/components/ReadOnlyField/ReadOnlyTextField.tsx +48 -0
  244. package/src/components/ReadOnlyField/USAGE.md +44 -0
  245. package/src/components/ReadOnlyField/WithReadOnlyWrapper.tsx +93 -0
  246. package/src/components/ReadOnlyField/index.ts +5 -0
  247. package/src/components/RecursicaThemeProvider/USAGE.md +60 -0
  248. package/src/components/SegmentedControl/IMPLEMENTATION_NOTES.md +25 -0
  249. package/src/components/SegmentedControl/SegmentedControl.module.css +185 -0
  250. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +106 -0
  251. package/src/components/SegmentedControl/SegmentedControl.test.tsx +1 -0
  252. package/src/components/SegmentedControl/SegmentedControl.tsx +110 -0
  253. package/src/components/SegmentedControl/USAGE.md +55 -0
  254. package/src/components/Slider/IMPLEMENTATION_NOTES.md +92 -0
  255. package/src/components/Slider/Slider.module.css +588 -0
  256. package/src/components/Slider/Slider.stories.tsx +282 -0
  257. package/src/components/Slider/Slider.test.tsx +1 -0
  258. package/src/components/Slider/Slider.tsx +391 -0
  259. package/src/components/Slider/USAGE.md +56 -0
  260. package/src/components/Stack/STACK_IMPLEMENTATION_NOTES.md +4 -0
  261. package/src/components/Stack/Stack.module.css +7 -0
  262. package/src/components/Stack/Stack.stories.tsx +108 -0
  263. package/src/components/Stack/Stack.test.tsx +1 -0
  264. package/src/components/Stack/Stack.tsx +62 -0
  265. package/src/components/Stack/USAGE.md +48 -0
  266. package/src/components/Stepper/IMPLEMENTATION_NOTES.md +28 -0
  267. package/src/components/Stepper/Stepper.module.css +404 -0
  268. package/src/components/Stepper/Stepper.stories.tsx +148 -0
  269. package/src/components/Stepper/Stepper.test.tsx +1 -0
  270. package/src/components/Stepper/Stepper.tsx +93 -0
  271. package/src/components/Stepper/USAGE.md +41 -0
  272. package/src/components/Switch/SWITCH_IMPLEMENTATION_NOTES.md +64 -0
  273. package/src/components/Switch/Switch.module.css +279 -0
  274. package/src/components/Switch/Switch.stories.tsx +114 -0
  275. package/src/components/Switch/Switch.test.tsx +1 -0
  276. package/src/components/Switch/Switch.tsx +177 -0
  277. package/src/components/Switch/SwitchGroup.stories.tsx +132 -0
  278. package/src/components/Switch/SwitchGroup.tsx +127 -0
  279. package/src/components/Switch/USAGE.md +42 -0
  280. package/src/components/Table/TABLE_IMPLEMENTATION_NOTES.md +78 -0
  281. package/src/components/Table/Table.icons.tsx +40 -0
  282. package/src/components/Table/Table.module.css +444 -0
  283. package/src/components/Table/Table.stories.tsx +140 -0
  284. package/src/components/Table/Table.test.tsx +1 -0
  285. package/src/components/Table/Table.tsx +243 -0
  286. package/src/components/Table/USAGE.md +78 -0
  287. package/src/components/Tabs/IMPLEMENTATION_NOTES.md +27 -0
  288. package/src/components/Tabs/Tabs.module.css +591 -0
  289. package/src/components/Tabs/Tabs.stories.tsx +154 -0
  290. package/src/components/Tabs/Tabs.test.tsx +1 -0
  291. package/src/components/Tabs/Tabs.tsx +114 -0
  292. package/src/components/Tabs/USAGE.md +45 -0
  293. package/src/components/Text/TEXT_IMPLEMENTATION_NOTES.md +12 -0
  294. package/src/components/Text/Text.module.css +13 -0
  295. package/src/components/Text/Text.stories.tsx +75 -0
  296. package/src/components/Text/Text.test.tsx +1 -0
  297. package/src/components/Text/Text.tsx +53 -0
  298. package/src/components/Text/USAGE.md +40 -0
  299. package/src/components/TextArea/TEXTAREA_IMPLEMENTATION_NOTES.md +7 -0
  300. package/src/components/TextArea/TextArea.module.css +183 -0
  301. package/src/components/TextArea/TextArea.stories.tsx +94 -0
  302. package/src/components/TextArea/TextArea.test.tsx +1 -0
  303. package/src/components/TextArea/TextArea.tsx +137 -0
  304. package/src/components/TextArea/USAGE.md +48 -0
  305. package/src/components/TextField/TEXTFIELD_IMPLEMENTATION_NOTES.md +19 -0
  306. package/src/components/TextField/TextField.module.css +264 -0
  307. package/src/components/TextField/TextField.stories.tsx +162 -0
  308. package/src/components/TextField/TextField.test.tsx +1 -0
  309. package/src/components/TextField/TextField.tsx +139 -0
  310. package/src/components/TextField/USAGE.md +44 -0
  311. package/src/components/TimePicker/TIMEPICKER_IMPLEMENTATION_NOTES.md +119 -0
  312. package/src/components/TimePicker/TimePicker.module.css +291 -0
  313. package/src/components/TimePicker/TimePicker.stories.tsx +141 -0
  314. package/src/components/TimePicker/TimePicker.test.tsx +1 -0
  315. package/src/components/TimePicker/TimePicker.tsx +304 -0
  316. package/src/components/TimePicker/USAGE.md +57 -0
  317. package/src/components/Timeline/TIMELINE_IMPLEMENTATION_NOTES.md +13 -0
  318. package/src/components/Timeline/Timeline.module.css +373 -0
  319. package/src/components/Timeline/Timeline.stories.tsx +128 -0
  320. package/src/components/Timeline/Timeline.test.tsx +1 -0
  321. package/src/components/Timeline/Timeline.tsx +73 -0
  322. package/src/components/Timeline/TimelineItem.tsx +79 -0
  323. package/src/components/Timeline/USAGE.md +49 -0
  324. package/src/components/Toast/TOAST_IMPLEMENTATION_NOTES.md +39 -0
  325. package/src/components/Toast/Toast.module.css +184 -0
  326. package/src/components/Toast/Toast.stories.tsx +67 -0
  327. package/src/components/Toast/Toast.test.tsx +1 -0
  328. package/src/components/Toast/Toast.tsx +82 -0
  329. package/src/components/Toast/USAGE.md +50 -0
  330. package/src/components/Toast/index.ts +1 -0
  331. package/src/components/Tooltip/TOOLTIP_IMPLEMENTATION_NOTES.md +85 -0
  332. package/src/components/Tooltip/Tooltip.module.css +91 -0
  333. package/src/components/Tooltip/Tooltip.stories.tsx +165 -0
  334. package/src/components/Tooltip/Tooltip.test.tsx +1 -0
  335. package/src/components/Tooltip/Tooltip.tsx +117 -0
  336. package/src/components/Tooltip/USAGE.md +80 -0
  337. package/src/components/TransferList/TRANSFERLIST_IMPLEMENTATION_NOTES.md +111 -0
  338. package/src/components/TransferList/TransferList.module.css +182 -0
  339. package/src/components/TransferList/TransferList.stories.tsx +121 -0
  340. package/src/components/TransferList/TransferList.test.tsx +1 -0
  341. package/src/components/TransferList/TransferList.tsx +419 -0
  342. package/src/components/TransferList/USAGE.md +77 -0
  343. package/src/components/Tree/IMPLEMENTATION_NOTES.md +48 -0
  344. package/src/components/Tree/Tree.module.css +232 -0
  345. package/src/components/Tree/Tree.stories.tsx +104 -0
  346. package/src/components/Tree/Tree.test.tsx +1 -0
  347. package/src/components/Tree/Tree.tsx +220 -0
  348. package/src/components/Tree/USAGE.md +96 -0
  349. package/src/components/Tree/index.ts +1 -0
  350. package/src/components/index.ts +52 -0
  351. package/src/env.d.ts +7 -0
  352. package/src/index.ts +179 -0
  353. package/src/types/index.ts +9 -0
  354. package/src/types/mantine.d.ts +7 -0
  355. package/src/types/scss-modules.d.ts +9 -0
  356. package/src/utils/ColorSchemeWrapper.tsx +27 -0
  357. package/src/utils/RequireAccessibleLabel.ts +1 -0
  358. package/src/utils/copyToClipboard.ts +36 -0
  359. package/src/utils/filterStylingProps.test.ts +85 -0
  360. package/src/utils/filterStylingProps.ts +150 -0
  361. package/src/utils/index.ts +1 -0
  362. package/src/utils/renderRichOption.tsx +65 -0
@@ -0,0 +1,244 @@
1
+ # FileUpload Implementation Notes
2
+
3
+ ## Architecture Overview
4
+
5
+ `FileUpload` is a fully custom composite — unlike most other adapter components, there is no
6
+ single underlying Mantine primitive to wrap (Mantine core ships `FileInput`, a styled single-line
7
+ file input, but no drag-and-drop dropzone UI; that's a separate `@mantine/dropzone` package we
8
+ deliberately did not add — see "Why not `@mantine/dropzone`" below). The component composes:
9
+
10
+ 1. **The dropzone** — a plain `<div>` handling native HTML5 drag-and-drop events
11
+ (`onDragOver`/`onDrop`), containing an upload icon, instructional text, and a hidden
12
+ `<input type="file">` triggered by...
13
+ 2. **The browse button** — this adapter's own `<Button variant="outline" size="small">`.
14
+ 3. **The file list** — this adapter's own `<Chip>` component (with `onDelete`), one per entry in
15
+ the controlled `files` prop.
16
+
17
+ This shape is **not configurable** — there is no prop to render a bare native file input without
18
+ the dropzone chrome (that's what the separate, still-stub `FileInput` component is for).
19
+
20
+ ## Why not `@mantine/dropzone`
21
+
22
+ Mantine's own drag-and-drop package (`@mantine/dropzone`) would require adding a new peer
23
+ dependency purely for its interaction logic (drag events, accept/reject callbacks) — its visual
24
+ output is fully overridden by our own CSS module regardless, and the interaction logic itself is
25
+ a handful of native `DragEvent`/`<input type="file">` handlers. Implementing it directly with
26
+ native DOM APIs keeps this component's behavior identical across the Mantine and MUI adapters
27
+ (neither ships a drag-and-drop dropzone natively), matching the "one API, any kit" goal in the
28
+ canonical `COMPONENT_DEV_GUIDE.md` more literally than either library's own package would. (Matt
29
+ Massey, 2026-08-11.)
30
+
31
+ ## Why `Chip` for the file list, not a bespoke tag element
32
+
33
+ `recursica_variables_scoped.css`'s `file-upload` token namespace defines `item-gap`/`list-spacing`
34
+ (spacing between/around file entries) but **no color/border tokens of its own for the file
35
+ entries themselves** — the visual design intentionally delegates that to the existing `Chip`
36
+ component's own token namespace (`--recursica_ui-kit_components_chip_...`). Reusing `<Chip
37
+ onDelete={...}>` directly (rather than reimplementing a similar-looking element) keeps that
38
+ separation intact per the canonical guide's "Component Specificity" rule — `FileUpload.module.css`
39
+ never reaches into `chip`'s namespace, and `Chip.module.css` never reaches into `file-upload`'s.
40
+
41
+ `checked={false}` is passed explicitly (with no `onChange`) to keep each chip a static, always-
42
+ unchecked removable tag — `Chip` is fundamentally a Mantine `Chip` (checkbox/radio-style toggle)
43
+ under the hood, and a file name isn't something a user should be able to "check"; controlling
44
+ `checked` prevents clicking the label text from toggling Chip's own selected-state styling.
45
+
46
+ ## `border-style` and the malformed Figma token
47
+
48
+ `--recursica_ui-kit_components_file-upload_properties_border-style` exists in
49
+ `recursica_variables_scoped.css`, but its value is the **literal string** `"dashed"` (quotes
50
+ included) — not a valid CSS `<line-style>` keyword. Using it via `var(...)` would silently resolve
51
+ to an invalid declaration (the browser drops it, and the border falls back to `initial`/`none`,
52
+ with no error surfaced anywhere). This is consistent with how `border-style` is already treated
53
+ everywhere else in this adapter (e.g. `TimePicker`/`DatePicker` both hardcode `border-style:
54
+ solid`) — the canonical guide explicitly lists `border-style` as a baseline/hardcoded structural
55
+ value, not a tokenized one. Hardcoded to the keyword `dashed` directly; the malformed token is
56
+ `recursica-ignore`d with a note in `FileUpload.module.css`. Worth flagging to design/Forge if the
57
+ token is meant to be consumable as-is in a future export.
58
+
59
+ ## No dedicated icon-size token
60
+
61
+ Unlike `TextField`/`DatePicker`, `file-upload` has no `properties_icon-size` token. The upload
62
+ icon is sized with a hardcoded `2rem` to visually match the Figma reference image
63
+ (`packages/adapter-common/src/components/FileUpload/fileupload.png`); revisit if a dedicated token
64
+ is ever added.
65
+
66
+ ## Dragging-over visual state (Matt Massey, 2026-08-17)
67
+
68
+ Previously flagged as a known gap ("no distinct dragging-over visual state" — there's still no
69
+ `file-upload`-specific token for it), now implemented using two existing generic tokens instead of
70
+ inventing new component-scoped ones:
71
+
72
+ - **Background**: the same "Global Hover Hack Overlay" recipe `Button.module.css` already uses —
73
+ a `::after` pseudo-element sized to `inset: 0`, `background-color:
74
+ var(--recursica_brand_states_hover_color)`, faded in to `var(--recursica_brand_states_hover_opacity)`
75
+ via `[data-dragging="true"]` instead of `:hover`. Requires `.dropzone` to be `position: relative`
76
+ and its real children `position: relative; z-index: 1` so they render above the overlay.
77
+ - **Border**: `--form-field-border-selected`, the bridge custom property `FormControlWrapper`
78
+ already sets from `--recursica_ui-kit_globals_form_field_colors_border-selected` on its own
79
+ `.root` (an ancestor of `.dropzone` here) — defined for exactly this kind of cross-component
80
+ reuse, but unused anywhere until now. Chosen over reaching for the global token directly, since
81
+ the existing bridge-var pattern is how other component CSS in this adapter already consumes
82
+ globals it doesn't own (see `FormControlWrapper.module.css`).
83
+
84
+ Tracked via a `dragCounterRef` in `FileUpload.tsx`, not a plain boolean: `dragenter`/`dragleave`
85
+ fire for every child element the pointer crosses, not just the dropzone itself, so a plain
86
+ enter-sets-true/leave-sets-false toggle flickers off every time the pointer passes over the icon,
87
+ label, or button inside the dropzone. Counting nested enter/leave pairs and only clearing the
88
+ state at net-zero avoids that.
89
+
90
+ ## Read-only mode (Matt Massey, 2026-08-18)
91
+
92
+ Previously flagged as a known gap ("no read-only mode" — see below). Unlike `TextField`/
93
+ `DatePicker`, there's no single "value" to swap for static text via `WithReadOnlyWrapper` — a file
94
+ list's read-only form is the same chip list, just without the ability to remove anything. So
95
+ `readOnly` is handled directly in `FileUpload.tsx` rather than reusing `WithReadOnlyWrapper`:
96
+
97
+ - The dropzone (icon, instructional text, Browse button, hidden `<input>`) is omitted entirely.
98
+ - Each `Chip` is rendered with no `onDelete` (and no `deleteTabIndex`/`deleteIconRef`/roving
99
+ keyboard handlers, which only exist to manage the remove icon) — `Chip` itself already renders no
100
+ remove icon at all when `onDelete` is `undefined`, so this falls out for free rather than needing
101
+ a separate `readOnly` prop on `Chip`.
102
+ - `disabled` is independent of `readOnly` and has no effect when `readOnly` is set (there's no
103
+ dropzone/remove icon left for it to disable).
104
+
105
+ Original gap this replaces: Figma's `fileupload.png` reference only depicted the interactive
106
+ dropzone and an empty state, no distinct read-only rendering — revisited once one was specified.
107
+
108
+ ## Assistive text/error delegated back to FormControlWrapper (Matt Massey, 2026-08-18)
109
+
110
+ Briefly changed to have `FileUpload` render its own `AssistiveElement` directly (dropzone →
111
+ assistive/error → file list, all inside the one `children` slot `FormControlWrapper` sees) so the
112
+ file list could sit _below_ the assistive text instead of `FormControlWrapper`'s default of
113
+ rendering assistive/error _after_ whatever `children` it's given. Reverted at Matt's request:
114
+ `assistiveText`/`error` are passed straight through to `FormControlWrapper` again (file list
115
+ renders above the assistive/error text, same as every other form control), and `FileUpload` no
116
+ longer manages its own `aria-describedby`/`aria-errormessage` wiring — `FormControlWrapper`'s own
117
+ `cloneElement` handles that automatically since `FileUpload`'s root `<div>` is a single element.
118
+
119
+ ## Built-in error for `accept` mismatches (Matt Massey, 2026-08-18)
120
+
121
+ A file rejected for not matching `accept` (see below) now surfaces as the control's own error
122
+ state by default, rather than leaving the integrator to wire up `onFilesRejected` into their own
123
+ `error` prop just to get a message on screen. `handleFiles` tracks whether the _most recent_
124
+ drop/pick attempt included an `accept` mismatch (`invalidTypeRejected` state) and `FileUpload`
125
+ computes `effectiveError = error ?? (invalidTypeRejected ? invalidFileTypeMessage : undefined)` —
126
+ an explicit `error` prop always wins over the built-in one. The message itself is a new
127
+ `invalidFileTypeMessage` prop (`RecursicaFileUploadProps`, adapter-common), defaulting to
128
+ `"File type not accepted"`. Scoped to `accept` mismatches only — a `maxSize` rejection still has no
129
+ built-in message, since `onFilesRejected` is the only signal for that case and there's no single
130
+ reasonable default (unlike the type-mismatch text, "too large" needs the actual limit in it).
131
+
132
+ ## `accept` is now enforced on drop, not just the picker dialog (Matt Massey, 2026-08-18)
133
+
134
+ The native `accept` attribute on the hidden `<input type="file">` only constrains the browser's own
135
+ file-picker dialog — it has **no effect on a `drop` event**, so a file dragged directly onto the
136
+ dropzone previously bypassed `accept` entirely regardless of extension/MIME type (the prior doc
137
+ comment on `RecursicaFileUploadProps.accept` claimed otherwise; that was wrong and has been
138
+ corrected). `handleFiles` (shared by both the picker and drop paths) now also validates every file
139
+ against `accept` via a new shared `fileMatchesAccept(file, accept)` util in `adapter-common`
140
+ (mirrors the native attribute's own comma-separated extension/MIME/MIME-wildcard semantics) and
141
+ routes non-matching files to `onFilesRejected`, the same callback already used for `maxSize`
142
+ rejections.
143
+
144
+ ## Not a nested interactive element
145
+
146
+ The dropzone `<div>` itself has no `onClick`/`role="button"`/`tabIndex` — only the explicit
147
+ "Browse files" `<Button>` opens the native file picker. Many dropzone implementations make the
148
+ entire box clickable in addition to drag-and-drop, but the Figma reference shows the button as
149
+ the sole explicit affordance, and avoiding a second, redundant click target inside (or wrapping)
150
+ a real `<button>` avoids any nested-interactive-element accessibility ambiguity. (This is
151
+ independent of the file list's own keyboard navigation below, which lives entirely in the
152
+ separate `Chip` list, not the dropzone.)
153
+
154
+ ## Custom upload icon (Matt Massey, 2026-08-17)
155
+
156
+ Added `icon?: React.ReactNode` to `RecursicaFileUploadProps` (adapter-common) — `FileUpload`
157
+ renders `icon ?? <UploadIcon />` inside the same `.uploadIcon` span either way, so a custom icon
158
+ picks up the same `color`/`width`/`height` styling the default one gets (use `currentColor` and
159
+ fill the viewbox, like `UploadIcon` does, for it to inherit correctly).
160
+
161
+ ## Browse button size (Matt Massey, 2026-08-17)
162
+
163
+ The "Browse files" `<Button>` was hardcoded to `size="small"`. There's no design rationale for a
164
+ smaller-than-normal button here — the Figma reference simply wasn't checked against `Button`'s own
165
+ size tokens closely enough when this was first built. Removed the `size` prop entirely so it falls
166
+ through to `Button`'s own default (`"default"`, the standard size used everywhere else in both
167
+ adapters).
168
+
169
+ ## Keyboard navigation for the file chip list (Matt Massey, 2026-08-17)
170
+
171
+ The file list previously had no group-level keyboard model at all — each chip's remove icon was
172
+ simply the next `tabIndex={0}` element in natural DOM order (and, in the Mantine adapter, so was
173
+ each chip's own hidden checkbox `<input>`, since `Chip`'s `isInteractive` check treats any chip
174
+ with `onDelete` as tabbable-by-default — a second, redundant tab stop specific to this adapter).
175
+ Implemented a standard roving-tabindex pattern instead, matching `Tree`'s existing keyboard model
176
+ (see `../Tree/IMPLEMENTATION_NOTES.md`) rather than inventing a new one:
177
+
178
+ - **Tab reaches exactly one stop per chip list, landing on the first chip.** `FileUpload` tracks
179
+ `activeChipIndex` (initially `0`) and passes `deleteTabIndex={index === activeChipIndex ? 0 : -1}`
180
+ to each `Chip` — a new pass-through prop added to `RecursicaChipProps`/both adapters' `Chip.tsx`
181
+ (see `../Chip/CHIP_IMPLEMENTATION_NOTES.md`) that overrides the remove icon's own tabIndex. Every
182
+ chip in the Mantine adapter is also given a plain `tabIndex={-1}` directly (flows through to
183
+ `MantineChip`'s underlying checkbox `<input>` via the existing `sanitizedProps` passthrough) to
184
+ kill that second, unwanted tab stop — the chip's label/checkbox was never meant to be
185
+ interactive here (`checked={false}`, no `onChange`), only its remove icon is.
186
+ - **Enter removes the focused chip, with focus already on its remove icon.** No new code needed —
187
+ `Chip`'s remove icon already calls `onDelete` on `Enter`/`Space`, and it's already the focused
188
+ element by construction (see above), so "focus ring on the remove icon" falls out for free from
189
+ the existing `.deleteIcon:focus-visible` style.
190
+ - **Left/Right or Up/Down move focus between chips.** A `onKeyDown` handler on the file list `<div>`
191
+ (event delegation — it fires for keydowns on any focused chip inside it) computes the next index
192
+ (wrapping at both ends) and moves real DOM focus there via `deleteIconRefs`, an array of refs
193
+ populated through the new `deleteIconRef` prop on `Chip` (same PR as `deleteTabIndex`).
194
+ - **Focus survives removal.** Since `files` is a controlled prop `FileUpload` doesn't mutate
195
+ itself, removing a chip doesn't shrink `files` until the consumer's own state update flows back
196
+ down as a new prop — a `useEffect` keyed on `files` detects the length decreasing, clamps
197
+ `activeChipIndex` to the new last-valid index, and re-focuses that chip's remove icon, so focus
198
+ never falls out of the list back to `<body>`.
199
+
200
+ ## Maximum file count (Matt Massey, 2026-08-18)
201
+
202
+ Added `maxFiles`/`maxFilesMessage` to `RecursicaFileUploadProps` (adapter-common), enforced the
203
+ same way `maxSize`/`accept` already are: `handleFiles` compares `files.length` (the current count)
204
+ plus how many of the incoming batch have already been provisionally accepted against `maxFiles`,
205
+ and routes anything past the cap to `onFilesRejected` instead of `onFilesAdded`. The built-in
206
+ `maxFilesMessage` ("Maximum of {maxFiles} files allowed") surfaces through the same
207
+ `effectiveError` mechanism `invalidFileTypeMessage` already uses — an explicit `error` prop still
208
+ wins over both, and an `accept` mismatch takes priority over a `maxFiles` one when a single drop
209
+ triggers both.
210
+
211
+ ## Read-only chips were still interactive (Matt Massey, 2026-08-18)
212
+
213
+ The `readOnly` file list (added 2026-08-18, see USAGE.md §7) rendered each filename as a
214
+ `<Chip checked={false} tabIndex={-1}>` with no `onDelete`, expecting that to be fully inert. Two
215
+ separate, previously-latent bugs made it look and behave otherwise — both fixed in
216
+ `Chip`/`Chip.module.css`, not `FileUpload` itself, so every consumer of a non-interactive `Chip`
217
+ benefits, not just this one:
218
+
219
+ - **Passing `checked` (even `false`) was misread as "interactive."** `Chip`'s `isInteractive` check
220
+ treated `checked !== undefined` as a signal that the chip was a real toggle, which forced it into
221
+ the tabbable/exposed branch — but a `checked`-controlled chip with no `onChange` can't actually be
222
+ toggled by a click (Mantine's `useUncontrolled` just ignores the click when `value` is externally
223
+ controlled), so that heuristic was measuring the wrong thing. `isInteractive` now only looks at
224
+ whether something actually responds to interaction: `onDelete`, `onClick`, or `onChange`.
225
+ - **A read-only chip's cursor still showed `pointer` on hover.** Mantine's own base styles hardcode
226
+ `cursor: pointer` on the chip label class; our CSS never overrode it, so it always leaked through
227
+ regardless of the chip's actual behavior. `.label.label` now resets it to `cursor: default` and a
228
+ new `data-interactive` attribute (set by `Chip.tsx` from the same `isInteractive` check above)
229
+ re-enables `pointer` only when the chip is genuinely clickable.
230
+ - **The truncating filename text was itself a phantom, un-styled Tab stop.** `.children` truncates
231
+ long filenames via `overflow-x: hidden` + `text-overflow: ellipsis`. Chromium treats any element
232
+ with non-`visible` overflow whose content actually overflows as a scroll container, and makes
233
+ scroll containers focusable-by-default (so a user can arrow-key-scroll them) — even with no
234
+ `tabindex` attribute at all. Any chip with a long enough label, read-only or not, silently picked
235
+ up an extra Tab stop nobody wrote and no CSS styled a focus ring for. Switched to `overflow-x:
236
+ clip`, which clips identically for our purposes (still x-axis only, descenders on the y-axis
237
+ still unaffected — see the 2026-08-18 fix above this one) but doesn't establish a scrollport, so
238
+ it's never a focus candidate.
239
+
240
+ Confirmed via Playwright against a running Storybook (not just DOM inspection): before the fix,
241
+ `Tab` from the "Browse files" button in `WithFiles` landed on the first chip's filename text, THEN
242
+ its remove icon — an extra, invisible tab stop before the intended one. After the fix, `Tab` goes
243
+ directly to the remove icon, and in `ReadOnly`, `Tab` skips the file list entirely (there's nothing
244
+ in it to focus).
@@ -0,0 +1,205 @@
1
+ /* Brand-layer exemptions (recursica-allow-brand) — see recursica-token-analyzer README.md.
2
+ * Global hover/focus/disabled state tokens (recursica_variables_scoped.css header, 'Hover & Focus states' / 'Disabled state' — implicit rule for every interactive element; components must not define their own per-component treatment).
3
+ * recursica-allow-brand: --recursica_brand_states_hover_color
4
+ * recursica-allow-brand: --recursica_brand_states_hover_opacity
5
+ */
6
+
7
+ /* HARDCODED VALUES:
8
+ - .root: display: flex; flex-direction: column; width: 100% — structural layout, not a design
9
+ token concern (matches how other block-level components like Layer are laid out).
10
+ - .dropzone: border-style: dashed — see EXEMPTIONS below.
11
+ - .uploadIcon: width/height: 2rem — no icon-size token exists for file-upload (unlike
12
+ TextField/DatePicker); sized to visually match the Figma reference. Revisit if a dedicated
13
+ token is ever added. */
14
+
15
+ /* EXEMPTIONS:
16
+ - border-style is ignored: the dropzone is deliberately dashed (conventional drop-target
17
+ affordance), not the UI Kit's solid-border default. */
18
+ /* recursica-ignore: --recursica_ui-kit_components_file-upload_properties_border-style */
19
+
20
+ /* LAYOUT SPACING OVERRIDES:
21
+ - Sets the --form-control-margin-bottom spacing hook to map component-specific layout tokens. */
22
+ .layoutOverride {
23
+ --form-control-margin-bottom: var(
24
+ --recursica_ui-kit_components_file-upload_variants_layouts_stacked_properties_top-bottom-margin
25
+ );
26
+ }
27
+
28
+ .layoutOverride[data-form-layout="side-by-side"] {
29
+ --form-control-margin-bottom: var(
30
+ --recursica_ui-kit_components_file-upload_variants_layouts_side-by-side_properties_top-bottom-margin
31
+ );
32
+ }
33
+
34
+ .root {
35
+ display: flex;
36
+ flex-direction: column;
37
+ width: 100%;
38
+ gap: var(--recursica_ui-kit_components_file-upload_properties_list-spacing);
39
+ }
40
+
41
+ .dropzone {
42
+ display: flex;
43
+ flex-direction: column;
44
+ align-items: center;
45
+ justify-content: center;
46
+ position: relative; /* HARDCODE: anchors the drag-over overlay below */
47
+ box-sizing: border-box;
48
+ width: 100%;
49
+ border-style: dashed; /* HARDCODE: see EXEMPTIONS above */
50
+ border-width: var(
51
+ --recursica_ui-kit_components_file-upload_properties_border-size
52
+ );
53
+ border-radius: var(
54
+ --recursica_ui-kit_components_file-upload_properties_border-radius
55
+ );
56
+ border-color: var(
57
+ --recursica_ui-kit_components_file-upload_properties_colors_border-color
58
+ );
59
+ background-color: var(
60
+ --recursica_ui-kit_components_file-upload_properties_colors_background-color
61
+ );
62
+ padding: var(--recursica_ui-kit_components_file-upload_properties_padding);
63
+ gap: var(
64
+ --recursica_ui-kit_components_file-upload_properties_vertical-element-gap
65
+ );
66
+ }
67
+
68
+ /* Dragging-over state: reuses the generic hover overlay recipe (see Button.module.css) for the
69
+ background, and the shared "selected" border bridge var FormControlWrapper already exposes
70
+ (see FormControlWrapper.module.css) for the border — file-upload has no color tokens of its own
71
+ for this state. See "Dragging-over visual state" in FILEUPLOAD_IMPLEMENTATION_NOTES.md. */
72
+ .dropzone > * {
73
+ position: relative;
74
+ z-index: 1;
75
+ }
76
+ .dropzone::after {
77
+ content: "";
78
+ position: absolute;
79
+ inset: 0;
80
+ border-radius: inherit;
81
+ z-index: 0;
82
+ pointer-events: none;
83
+ transition: opacity 150ms ease;
84
+ opacity: 0;
85
+ background-color: var(--recursica_brand_states_hover_color);
86
+ }
87
+ .dropzone[data-dragging="true"] {
88
+ border-color: var(--form-field-border-selected);
89
+ }
90
+ .dropzone[data-dragging="true"]::after {
91
+ opacity: var(--recursica_brand_states_hover_opacity);
92
+ }
93
+
94
+ .uploadIcon {
95
+ display: flex;
96
+ width: 2rem; /* HARDCODE: see EXEMPTIONS above */
97
+ height: 2rem; /* HARDCODE: see EXEMPTIONS above */
98
+ color: var(
99
+ --recursica_ui-kit_components_file-upload_properties_colors_upload-icon
100
+ );
101
+ }
102
+
103
+ .uploadIcon svg {
104
+ width: 100%;
105
+ height: 100%;
106
+ }
107
+
108
+ .dropzoneText {
109
+ font-family: var(
110
+ --recursica_ui-kit_components_file-upload_properties_text_font-family
111
+ );
112
+ font-size: var(
113
+ --recursica_ui-kit_components_file-upload_properties_text_font-size
114
+ );
115
+ font-style: var(
116
+ --recursica_ui-kit_components_file-upload_properties_text_font-style
117
+ );
118
+ font-weight: var(
119
+ --recursica_ui-kit_components_file-upload_properties_text_font-weight
120
+ );
121
+ letter-spacing: var(
122
+ --recursica_ui-kit_components_file-upload_properties_text_letter-spacing
123
+ );
124
+ line-height: var(
125
+ --recursica_ui-kit_components_file-upload_properties_text_line-height
126
+ );
127
+ text-decoration: var(
128
+ --recursica_ui-kit_components_file-upload_properties_text_text-decoration
129
+ );
130
+ text-transform: var(
131
+ --recursica_ui-kit_components_file-upload_properties_text_text-transform
132
+ );
133
+ color: var(
134
+ --recursica_ui-kit_components_file-upload_properties_colors_text-color
135
+ );
136
+ text-align: center;
137
+ }
138
+
139
+ .fileList {
140
+ display: flex;
141
+ flex-wrap: wrap;
142
+ align-items: center;
143
+ gap: var(--recursica_ui-kit_components_file-upload_properties_item-gap);
144
+ }
145
+
146
+ /* -------------------------------------
147
+ STATE CASCADE ARCHITECTURE
148
+ -------------------------------------- */
149
+
150
+ /* Error State Mapping (Propagated strictly down from the wrapper DOM context) */
151
+ .root[data-error="true"] .dropzone {
152
+ border-width: var(
153
+ --recursica_ui-kit_components_file-upload_variants_states_error_properties_border-size
154
+ );
155
+ border-color: var(
156
+ --recursica_ui-kit_components_file-upload_variants_states_error_properties_colors_border-color
157
+ );
158
+ background-color: var(
159
+ --recursica_ui-kit_components_file-upload_variants_states_error_properties_colors_background-color
160
+ );
161
+ }
162
+
163
+ .root[data-error="true"] .dropzoneText {
164
+ color: var(
165
+ --recursica_ui-kit_components_file-upload_variants_states_error_properties_colors_text-color
166
+ );
167
+ }
168
+
169
+ .root[data-error="true"] .uploadIcon {
170
+ color: var(
171
+ --recursica_ui-kit_components_file-upload_variants_states_error_properties_colors_upload-icon
172
+ );
173
+ }
174
+
175
+ /* Disabled State Mapping (Propagated strictly down from the wrapper DOM context) */
176
+ .root[data-disabled="true"] .dropzone {
177
+ border-width: var(
178
+ --recursica_ui-kit_components_file-upload_variants_states_disabled_properties_border-size
179
+ );
180
+ border-color: var(
181
+ --recursica_ui-kit_components_file-upload_variants_states_disabled_properties_colors_border-color
182
+ );
183
+ background-color: var(
184
+ --recursica_ui-kit_components_file-upload_variants_states_disabled_properties_colors_background-color
185
+ );
186
+ }
187
+
188
+ .root[data-disabled="true"] .dropzoneText {
189
+ color: var(
190
+ --recursica_ui-kit_components_file-upload_variants_states_disabled_properties_colors_text-color
191
+ );
192
+ }
193
+
194
+ .root[data-disabled="true"] .uploadIcon {
195
+ color: var(
196
+ --recursica_ui-kit_components_file-upload_variants_states_disabled_properties_colors_upload-icon
197
+ );
198
+ }
199
+
200
+ .root[data-disabled="true"] {
201
+ opacity: var(
202
+ --recursica_ui-kit_components_file-upload_variants_states_disabled_properties_opacity
203
+ );
204
+ cursor: not-allowed;
205
+ }