reflex 0.3.7__py3-none-any.whl → 0.3.8__py3-none-any.whl

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.

Potentially problematic release.


This version of reflex might be problematic. Click here for more details.

Files changed (322) hide show
  1. reflex/.templates/apps/blank/code/blank.py +0 -1
  2. reflex/.templates/apps/demo/code/demo.py +0 -1
  3. reflex/.templates/apps/sidebar/code/sidebar.py +6 -2
  4. reflex/.templates/jinja/web/pages/_app.js.jinja2 +4 -1
  5. reflex/.templates/jinja/web/pages/base_page.js.jinja2 +4 -1
  6. reflex/.templates/jinja/web/pages/utils.js.jinja2 +24 -0
  7. reflex/.templates/jinja/web/tailwind.config.js.jinja2 +4 -1
  8. reflex/.templates/web/utils/helpers/dataeditor.js +56 -54
  9. reflex/__init__.py +4 -2
  10. reflex/__init__.pyi +6 -2
  11. reflex/app.py +43 -9
  12. reflex/app.pyi +2 -1
  13. reflex/app_module_for_backend.py +13 -0
  14. reflex/compiler/compiler.py +19 -0
  15. reflex/components/__init__.py +9 -232
  16. reflex/components/base/__init__.py +5 -1
  17. reflex/components/base/app_wrap.py +1 -1
  18. reflex/components/base/app_wrap.pyi +1 -1
  19. reflex/components/base/document.py +0 -8
  20. reflex/components/base/document.pyi +0 -80
  21. reflex/components/{layout → base}/fragment.pyi +1 -1
  22. reflex/components/chakra/__init__.py +202 -19
  23. reflex/components/{libs/chakra.pyi → chakra/base.pyi} +1 -1
  24. reflex/components/chakra/datadisplay/__init__.py +12 -0
  25. reflex/components/{datadisplay → chakra/datadisplay}/badge.py +1 -1
  26. reflex/components/{datadisplay → chakra/datadisplay}/badge.pyi +2 -2
  27. reflex/components/{datadisplay → chakra/datadisplay}/code.py +5 -5
  28. reflex/components/{datadisplay → chakra/datadisplay}/code.pyi +5 -5
  29. reflex/components/{datadisplay → chakra/datadisplay}/divider.py +4 -2
  30. reflex/components/{datadisplay → chakra/datadisplay}/divider.pyi +5 -3
  31. reflex/components/{datadisplay → chakra/datadisplay}/keyboard_key.py +1 -1
  32. reflex/components/{datadisplay → chakra/datadisplay}/keyboard_key.pyi +2 -2
  33. reflex/components/{datadisplay → chakra/datadisplay}/list.py +3 -3
  34. reflex/components/{datadisplay → chakra/datadisplay}/list.pyi +4 -4
  35. reflex/components/{datadisplay → chakra/datadisplay}/stat.py +1 -1
  36. reflex/components/{datadisplay → chakra/datadisplay}/stat.pyi +2 -2
  37. reflex/components/{datadisplay → chakra/datadisplay}/table.py +2 -2
  38. reflex/components/{datadisplay → chakra/datadisplay}/table.pyi +3 -3
  39. reflex/components/{datadisplay → chakra/datadisplay}/tag.py +2 -2
  40. reflex/components/{datadisplay → chakra/datadisplay}/tag.pyi +3 -3
  41. reflex/components/{disclosure → chakra/disclosure}/accordion.py +1 -1
  42. reflex/components/{disclosure → chakra/disclosure}/accordion.pyi +2 -2
  43. reflex/components/{disclosure → chakra/disclosure}/tabs.py +2 -2
  44. reflex/components/{disclosure → chakra/disclosure}/tabs.pyi +3 -3
  45. reflex/components/{disclosure → chakra/disclosure}/transition.py +1 -1
  46. reflex/components/{disclosure → chakra/disclosure}/transition.pyi +2 -2
  47. reflex/components/{disclosure → chakra/disclosure}/visuallyhidden.py +1 -1
  48. reflex/components/{disclosure → chakra/disclosure}/visuallyhidden.pyi +2 -2
  49. reflex/components/{feedback → chakra/feedback}/alert.py +2 -2
  50. reflex/components/{feedback → chakra/feedback}/alert.pyi +2 -6
  51. reflex/components/{feedback → chakra/feedback}/circularprogress.py +1 -1
  52. reflex/components/{feedback → chakra/feedback}/circularprogress.pyi +2 -2
  53. reflex/components/{feedback → chakra/feedback}/progress.py +1 -1
  54. reflex/components/{feedback → chakra/feedback}/progress.pyi +2 -2
  55. reflex/components/{feedback → chakra/feedback}/skeleton.py +1 -1
  56. reflex/components/{feedback → chakra/feedback}/skeleton.pyi +2 -2
  57. reflex/components/{feedback → chakra/feedback}/spinner.py +1 -1
  58. reflex/components/{feedback → chakra/feedback}/spinner.pyi +2 -2
  59. reflex/components/{forms → chakra/forms}/__init__.py +2 -11
  60. reflex/components/{forms → chakra/forms}/button.py +3 -1
  61. reflex/components/{forms → chakra/forms}/button.pyi +2 -2
  62. reflex/components/{forms → chakra/forms}/checkbox.py +1 -1
  63. reflex/components/{forms → chakra/forms}/checkbox.pyi +2 -6
  64. reflex/components/{forms → chakra/forms}/colormodeswitch.py +10 -2
  65. reflex/components/{forms → chakra/forms}/colormodeswitch.pyi +83 -3
  66. reflex/components/{forms → chakra/forms}/date_picker.py +1 -1
  67. reflex/components/{forms → chakra/forms}/date_picker.pyi +2 -2
  68. reflex/components/{forms → chakra/forms}/date_time_picker.py +1 -1
  69. reflex/components/{forms → chakra/forms}/date_time_picker.pyi +2 -2
  70. reflex/components/{forms → chakra/forms}/editable.py +1 -1
  71. reflex/components/{forms → chakra/forms}/editable.pyi +2 -2
  72. reflex/components/{forms → chakra/forms}/email.py +1 -1
  73. reflex/components/{forms → chakra/forms}/email.pyi +2 -2
  74. reflex/components/{forms → chakra/forms}/form.py +1 -1
  75. reflex/components/{forms → chakra/forms}/form.pyi +2 -2
  76. reflex/components/{forms → chakra/forms}/iconbutton.py +1 -1
  77. reflex/components/{forms → chakra/forms}/iconbutton.pyi +2 -2
  78. reflex/components/{forms → chakra/forms}/input.py +5 -4
  79. reflex/components/{forms → chakra/forms}/input.pyi +59 -5
  80. reflex/components/{forms → chakra/forms}/numberinput.py +6 -2
  81. reflex/components/{forms → chakra/forms}/numberinput.pyi +10 -2
  82. reflex/components/{forms → chakra/forms}/password.py +1 -1
  83. reflex/components/{forms → chakra/forms}/password.pyi +2 -2
  84. reflex/components/{forms → chakra/forms}/pininput.py +1 -1
  85. reflex/components/{forms → chakra/forms}/pininput.pyi +2 -2
  86. reflex/components/{forms → chakra/forms}/radio.py +3 -3
  87. reflex/components/{forms → chakra/forms}/radio.pyi +4 -4
  88. reflex/components/{forms → chakra/forms}/rangeslider.py +1 -1
  89. reflex/components/{forms → chakra/forms}/rangeslider.pyi +2 -2
  90. reflex/components/{forms → chakra/forms}/select.py +3 -3
  91. reflex/components/{forms → chakra/forms}/select.pyi +4 -4
  92. reflex/components/{forms → chakra/forms}/slider.py +4 -3
  93. reflex/components/{forms → chakra/forms}/slider.pyi +5 -4
  94. reflex/components/{forms → chakra/forms}/switch.py +1 -1
  95. reflex/components/{forms → chakra/forms}/switch.pyi +2 -2
  96. reflex/components/{forms → chakra/forms}/textarea.py +2 -2
  97. reflex/components/{forms → chakra/forms}/textarea.pyi +3 -3
  98. reflex/components/chakra/forms/time_picker.py +11 -0
  99. reflex/components/chakra/forms/time_picker.pyi +129 -0
  100. reflex/components/{layout → chakra/layout}/__init__.py +1 -20
  101. reflex/components/{layout → chakra/layout}/aspect_ratio.py +1 -1
  102. reflex/components/{layout → chakra/layout}/aspect_ratio.pyi +2 -2
  103. reflex/components/{layout → chakra/layout}/box.py +1 -1
  104. reflex/components/{layout → chakra/layout}/box.pyi +2 -2
  105. reflex/components/{layout → chakra/layout}/card.py +2 -2
  106. reflex/components/{layout → chakra/layout}/card.pyi +3 -3
  107. reflex/components/{layout → chakra/layout}/center.py +1 -1
  108. reflex/components/{layout → chakra/layout}/center.pyi +2 -2
  109. reflex/components/{layout → chakra/layout}/container.py +1 -1
  110. reflex/components/{layout → chakra/layout}/container.pyi +2 -2
  111. reflex/components/{layout → chakra/layout}/flex.py +1 -1
  112. reflex/components/{layout → chakra/layout}/flex.pyi +2 -2
  113. reflex/components/{layout → chakra/layout}/grid.py +1 -1
  114. reflex/components/{layout → chakra/layout}/grid.pyi +2 -2
  115. reflex/components/{layout → chakra/layout}/html.py +1 -1
  116. reflex/components/{layout → chakra/layout}/html.pyi +2 -2
  117. reflex/components/{layout → chakra/layout}/spacer.py +1 -1
  118. reflex/components/{layout → chakra/layout}/spacer.pyi +2 -2
  119. reflex/components/{layout → chakra/layout}/stack.py +1 -1
  120. reflex/components/{layout → chakra/layout}/stack.pyi +2 -2
  121. reflex/components/{layout → chakra/layout}/wrap.py +1 -1
  122. reflex/components/{layout → chakra/layout}/wrap.pyi +2 -2
  123. reflex/components/chakra/media/__init__.py +7 -0
  124. reflex/components/{media → chakra/media}/avatar.py +1 -1
  125. reflex/components/{media → chakra/media}/avatar.pyi +2 -2
  126. reflex/components/chakra/media/icon.py +110 -0
  127. reflex/components/{media → chakra/media}/icon.pyi +2 -2
  128. reflex/components/chakra/media/image.py +1 -1
  129. reflex/components/chakra/media/image.pyi +1 -1
  130. reflex/components/{navigation → chakra/navigation}/__init__.py +0 -1
  131. reflex/components/{navigation → chakra/navigation}/breadcrumb.py +3 -3
  132. reflex/components/{navigation → chakra/navigation}/breadcrumb.pyi +4 -4
  133. reflex/components/{navigation → chakra/navigation}/link.py +2 -2
  134. reflex/components/{navigation → chakra/navigation}/link.pyi +3 -3
  135. reflex/components/{navigation → chakra/navigation}/linkoverlay.py +1 -1
  136. reflex/components/{navigation → chakra/navigation}/linkoverlay.pyi +2 -2
  137. reflex/components/{navigation → chakra/navigation}/stepper.py +1 -1
  138. reflex/components/{navigation → chakra/navigation}/stepper.pyi +2 -2
  139. reflex/components/{overlay → chakra/overlay}/__init__.py +0 -1
  140. reflex/components/{overlay → chakra/overlay}/alertdialog.py +2 -2
  141. reflex/components/{overlay → chakra/overlay}/alertdialog.pyi +3 -3
  142. reflex/components/{overlay → chakra/overlay}/drawer.py +3 -3
  143. reflex/components/{overlay → chakra/overlay}/drawer.pyi +4 -4
  144. reflex/components/{overlay → chakra/overlay}/menu.py +4 -6
  145. reflex/components/{overlay → chakra/overlay}/menu.pyi +4 -4
  146. reflex/components/{overlay → chakra/overlay}/modal.py +2 -2
  147. reflex/components/{overlay → chakra/overlay}/modal.pyi +3 -3
  148. reflex/components/{overlay → chakra/overlay}/popover.py +2 -2
  149. reflex/components/{overlay → chakra/overlay}/popover.pyi +3 -3
  150. reflex/components/{overlay → chakra/overlay}/tooltip.py +1 -1
  151. reflex/components/{overlay → chakra/overlay}/tooltip.pyi +2 -2
  152. reflex/components/{typography → chakra/typography}/__init__.py +0 -1
  153. reflex/components/{typography → chakra/typography}/heading.py +1 -1
  154. reflex/components/{typography → chakra/typography}/heading.pyi +2 -2
  155. reflex/components/{typography → chakra/typography}/highlight.py +1 -1
  156. reflex/components/{typography → chakra/typography}/highlight.pyi +2 -2
  157. reflex/components/{typography → chakra/typography}/span.py +1 -1
  158. reflex/components/{typography → chakra/typography}/span.pyi +2 -2
  159. reflex/components/{typography → chakra/typography}/text.py +1 -1
  160. reflex/components/{typography → chakra/typography}/text.pyi +2 -2
  161. reflex/components/component.py +7 -8
  162. reflex/components/core/__init__.py +22 -0
  163. reflex/components/{overlay → core}/banner.py +4 -3
  164. reflex/components/{overlay → core}/banner.pyi +5 -4
  165. reflex/components/{navigation → core}/client_side_routing.py +1 -1
  166. reflex/components/{navigation → core}/client_side_routing.pyi +2 -2
  167. reflex/components/{layout → core}/cond.py +1 -1
  168. reflex/components/{forms → core}/debounce.py +1 -1
  169. reflex/components/{forms → core}/debounce.pyi +2 -2
  170. reflex/components/{layout → core}/foreach.py +18 -2
  171. reflex/components/core/match.py +257 -0
  172. reflex/components/{layout → core}/responsive.py +1 -1
  173. reflex/components/{forms → core}/upload.py +2 -2
  174. reflex/components/{forms → core}/upload.pyi +3 -3
  175. reflex/components/datadisplay/__init__.py +4 -13
  176. reflex/components/el/elements/inline.py +4 -0
  177. reflex/components/el/elements/inline.pyi +3 -0
  178. reflex/components/gridjs/__init__.py +5 -0
  179. reflex/components/{datadisplay → gridjs}/datatable.pyi +1 -1
  180. reflex/components/literals.py +27 -0
  181. reflex/components/markdown/__init__.py +5 -0
  182. reflex/components/{typography → markdown}/markdown.py +16 -6
  183. reflex/components/{typography → markdown}/markdown.pyi +10 -5
  184. reflex/components/media/__init__.py +1 -8
  185. reflex/components/media/icon.py +2 -110
  186. reflex/components/moment/__init__.py +5 -0
  187. reflex/components/{datadisplay → moment}/moment.pyi +1 -1
  188. reflex/components/next/__init__.py +2 -0
  189. reflex/components/{navigation/nextlink.pyi → next/link.pyi} +1 -1
  190. reflex/components/plotly/__init__.py +5 -0
  191. reflex/components/{graphing → plotly}/plotly.pyi +1 -1
  192. reflex/components/radix/primitives/__init__.py +12 -1
  193. reflex/components/radix/primitives/accordion.py +33 -68
  194. reflex/components/radix/primitives/accordion.pyi +6 -89
  195. reflex/components/radix/primitives/base.py +27 -0
  196. reflex/components/radix/primitives/base.pyi +95 -0
  197. reflex/components/radix/primitives/form.py +267 -0
  198. reflex/components/radix/primitives/form.pyi +740 -0
  199. reflex/components/radix/primitives/progress.py +84 -0
  200. reflex/components/radix/primitives/progress.pyi +268 -0
  201. reflex/components/radix/primitives/slider.py +179 -0
  202. reflex/components/radix/primitives/slider.pyi +452 -0
  203. reflex/components/radix/themes/base.py +43 -31
  204. reflex/components/radix/themes/base.pyi +223 -29
  205. reflex/components/radix/themes/components/__init__.py +18 -3
  206. reflex/components/radix/themes/components/alertdialog.py +27 -6
  207. reflex/components/radix/themes/components/alertdialog.pyi +713 -2
  208. reflex/components/radix/themes/components/aspectratio.py +1 -1
  209. reflex/components/radix/themes/components/aspectratio.pyi +67 -2
  210. reflex/components/radix/themes/components/avatar.py +0 -3
  211. reflex/components/radix/themes/components/avatar.pyi +13 -13
  212. reflex/components/radix/themes/components/badge.py +1 -4
  213. reflex/components/radix/themes/components/badge.pyi +11 -11
  214. reflex/components/radix/themes/components/button.py +1 -1
  215. reflex/components/radix/themes/components/button.pyi +15 -11
  216. reflex/components/radix/themes/components/callout.pyi +144 -12
  217. reflex/components/radix/themes/components/card.py +1 -1
  218. reflex/components/radix/themes/components/card.pyi +68 -1
  219. reflex/components/radix/themes/components/checkbox.pyi +14 -12
  220. reflex/components/radix/themes/components/contextmenu.pyi +402 -8
  221. reflex/components/radix/themes/components/dialog.py +6 -0
  222. reflex/components/radix/themes/components/dialog.pyi +518 -0
  223. reflex/components/radix/themes/components/dropdownmenu.pyi +337 -8
  224. reflex/components/radix/themes/components/hovercard.pyi +195 -0
  225. reflex/components/radix/themes/components/iconbutton.pyi +14 -12
  226. reflex/components/radix/themes/components/icons.py +2 -2
  227. reflex/components/radix/themes/components/inset.pyi +65 -0
  228. reflex/components/radix/themes/components/popover.pyi +260 -0
  229. reflex/components/radix/themes/components/radiogroup.py +1 -1
  230. reflex/components/radix/themes/components/radiogroup.pyi +78 -9
  231. reflex/components/radix/themes/components/scrollarea.pyi +65 -0
  232. reflex/components/radix/themes/components/select.pyi +342 -13
  233. reflex/components/radix/themes/components/separator.pyi +7 -5
  234. reflex/components/radix/themes/components/slider.py +4 -4
  235. reflex/components/radix/themes/components/slider.pyi +17 -13
  236. reflex/components/radix/themes/components/switch.pyi +20 -18
  237. reflex/components/radix/themes/components/table.py +1 -1
  238. reflex/components/radix/themes/components/table.pyi +458 -1
  239. reflex/components/radix/themes/components/tabs.py +4 -4
  240. reflex/components/radix/themes/components/tabs.pyi +263 -3
  241. reflex/components/radix/themes/components/textarea.py +1 -1
  242. reflex/components/radix/themes/components/textarea.pyi +1 -1
  243. reflex/components/radix/themes/components/textfield.py +1 -1
  244. reflex/components/radix/themes/components/textfield.pyi +18 -14
  245. reflex/components/radix/themes/components/tooltip.py +15 -0
  246. reflex/components/radix/themes/components/tooltip.pyi +205 -0
  247. reflex/components/radix/themes/layout/base.pyi +65 -0
  248. reflex/components/radix/themes/layout/box.pyi +65 -0
  249. reflex/components/radix/themes/layout/container.pyi +65 -0
  250. reflex/components/radix/themes/layout/flex.pyi +65 -0
  251. reflex/components/radix/themes/layout/grid.pyi +65 -0
  252. reflex/components/radix/themes/layout/section.pyi +65 -0
  253. reflex/components/radix/themes/typography/blockquote.pyi +16 -14
  254. reflex/components/radix/themes/typography/code.pyi +22 -20
  255. reflex/components/radix/themes/typography/em.pyi +65 -0
  256. reflex/components/radix/themes/typography/heading.pyi +30 -28
  257. reflex/components/radix/themes/typography/kbd.pyi +65 -0
  258. reflex/components/radix/themes/typography/link.py +2 -1
  259. reflex/components/radix/themes/typography/link.pyi +121 -28
  260. reflex/components/radix/themes/typography/quote.pyi +66 -0
  261. reflex/components/radix/themes/typography/strong.pyi +65 -0
  262. reflex/components/radix/themes/typography/text.pyi +30 -28
  263. reflex/components/react_player/__init__.py +7 -0
  264. reflex/components/react_player/audio.py +8 -0
  265. reflex/components/{media → react_player}/audio.pyi +3 -3
  266. reflex/components/{libs → react_player}/react_player.py +1 -1
  267. reflex/components/{libs → react_player}/react_player.pyi +3 -3
  268. reflex/components/react_player/video.py +8 -0
  269. reflex/components/{media → react_player}/video.pyi +3 -3
  270. reflex/components/{graphing/recharts → recharts}/cartesian.pyi +1 -1
  271. reflex/components/{graphing/recharts → recharts}/charts.py +1 -1
  272. reflex/components/{graphing/recharts → recharts}/charts.pyi +2 -2
  273. reflex/components/{graphing/recharts → recharts}/general.pyi +1 -1
  274. reflex/components/{graphing/recharts → recharts}/polar.pyi +1 -1
  275. reflex/components/{graphing/recharts → recharts}/recharts.pyi +1 -1
  276. reflex/components/suneditor/__init__.py +5 -0
  277. reflex/components/{forms → suneditor}/editor.pyi +1 -1
  278. reflex/components/tags/__init__.py +1 -0
  279. reflex/components/tags/iter_tag.py +3 -3
  280. reflex/components/tags/match_tag.py +19 -0
  281. reflex/constants/base.py +2 -0
  282. reflex/constants/installer.py +1 -0
  283. reflex/constants/style.py +1 -1
  284. reflex/event.py +1 -1
  285. reflex/reflex.py +14 -12
  286. reflex/state.py +14 -0
  287. reflex/style.py +1 -1
  288. reflex/testing.py +59 -9
  289. reflex/utils/build.py +7 -1
  290. reflex/utils/exceptions.py +6 -0
  291. reflex/utils/exec.py +2 -2
  292. reflex/utils/export.py +1 -1
  293. reflex/utils/format.py +41 -4
  294. reflex/utils/prerequisites.py +37 -6
  295. reflex/utils/types.py +2 -2
  296. reflex/vars.py +25 -1
  297. {reflex-0.3.7.dist-info → reflex-0.3.8.dist-info}/METADATA +7 -2
  298. reflex-0.3.8.dist-info/RECORD +492 -0
  299. reflex/components/graphing/__init__.py +0 -5
  300. reflex/components/libs/__init__.py +0 -31
  301. reflex/components/media/audio.py +0 -8
  302. reflex/components/media/image.pyi +0 -123
  303. reflex/components/media/video.py +0 -8
  304. reflex-0.3.7.dist-info/RECORD +0 -470
  305. /reflex/components/{layout → base}/fragment.py +0 -0
  306. /reflex/components/{libs/chakra.py → chakra/base.py} +0 -0
  307. /reflex/components/{disclosure → chakra/disclosure}/__init__.py +0 -0
  308. /reflex/components/{feedback → chakra/feedback}/__init__.py +0 -0
  309. /reflex/components/{forms → chakra/forms}/multiselect.py +0 -0
  310. /reflex/components/{datadisplay → gridjs}/datatable.py +0 -0
  311. /reflex/components/{datadisplay → moment}/moment.py +0 -0
  312. /reflex/components/{navigation/nextlink.py → next/link.py} +0 -0
  313. /reflex/components/{graphing → plotly}/plotly.py +0 -0
  314. /reflex/components/{graphing/recharts → recharts}/__init__.py +0 -0
  315. /reflex/components/{graphing/recharts → recharts}/cartesian.py +0 -0
  316. /reflex/components/{graphing/recharts → recharts}/general.py +0 -0
  317. /reflex/components/{graphing/recharts → recharts}/polar.py +0 -0
  318. /reflex/components/{graphing/recharts → recharts}/recharts.py +0 -0
  319. /reflex/components/{forms → suneditor}/editor.py +0 -0
  320. {reflex-0.3.7.dist-info → reflex-0.3.8.dist-info}/LICENSE +0 -0
  321. {reflex-0.3.7.dist-info → reflex-0.3.8.dist-info}/WHEEL +0 -0
  322. {reflex-0.3.7.dist-info → reflex-0.3.8.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,267 @@
1
+ """Radix form component."""
2
+
3
+ from hashlib import md5
4
+ from typing import Any, Dict, Iterator, Literal
5
+
6
+ from jinja2 import Environment
7
+
8
+ from reflex.components.component import Component
9
+ from reflex.components.tags.tag import Tag
10
+ from reflex.constants.base import Dirs
11
+ from reflex.constants.event import EventTriggers
12
+ from reflex.event import EventChain
13
+ from reflex.utils import imports
14
+ from reflex.utils.format import format_event_chain, to_camel_case
15
+ from reflex.vars import BaseVar, Var
16
+
17
+ from .base import RadixPrimitiveComponent
18
+
19
+ FORM_DATA = Var.create("form_data")
20
+ HANDLE_SUBMIT_JS_JINJA2 = Environment().from_string(
21
+ """
22
+ const handleSubmit_{{ handle_submit_unique_name }} = useCallback((ev) => {
23
+ const $form = ev.target
24
+ ev.preventDefault()
25
+ const {{ form_data }} = {...Object.fromEntries(new FormData($form).entries()), ...{{ field_ref_mapping }}}
26
+
27
+ {{ on_submit_event_chain }}
28
+
29
+ if ({{ reset_on_submit }}) {
30
+ $form.reset()
31
+ }
32
+ })
33
+ """
34
+ )
35
+
36
+
37
+ class FormComponent(RadixPrimitiveComponent):
38
+ """Base class for all @radix-ui/react-form components."""
39
+
40
+ library = "@radix-ui/react-form@^0.0.3"
41
+
42
+
43
+ class FormRoot(FormComponent):
44
+ """The root component of a radix form."""
45
+
46
+ tag = "Root"
47
+
48
+ alias = "RadixFormRoot"
49
+
50
+ # If true, the form will be cleared after submit.
51
+ reset_on_submit: Var[bool] = False # type: ignore
52
+
53
+ # The name used to make this form's submit handler function unique
54
+ handle_submit_unique_name: Var[str]
55
+
56
+ def get_event_triggers(self) -> Dict[str, Any]:
57
+ """Event triggers for radix form root.
58
+
59
+ Returns:
60
+ The triggers for event supported by Root.
61
+ """
62
+ return {
63
+ **super().get_event_triggers(),
64
+ EventTriggers.ON_SUBMIT: lambda e0: [FORM_DATA],
65
+ "on_clear_server_errors": lambda: [],
66
+ }
67
+
68
+ @classmethod
69
+ def create(cls, *children, **props):
70
+ """Create a form component.
71
+
72
+ Args:
73
+ *children: The children of the form.
74
+ **props: The properties of the form.
75
+
76
+ Returns:
77
+ The form component.
78
+ """
79
+ if "handle_submit_unique_name" in props:
80
+ return super().create(*children, **props)
81
+
82
+ # Render the form hooks and use the hash of the resulting code to create a unique name.
83
+ props["handle_submit_unique_name"] = ""
84
+ form = super().create(*children, **props)
85
+ form.handle_submit_unique_name = md5(
86
+ str(form.get_hooks()).encode("utf-8")
87
+ ).hexdigest()
88
+ return form
89
+
90
+ def _get_imports(self) -> imports.ImportDict:
91
+ return imports.merge_imports(
92
+ super()._get_imports(),
93
+ {
94
+ "react": {imports.ImportVar(tag="useCallback")},
95
+ f"/{Dirs.STATE_PATH}": {
96
+ imports.ImportVar(tag="getRefValue"),
97
+ imports.ImportVar(tag="getRefValues"),
98
+ },
99
+ },
100
+ )
101
+
102
+ def _get_hooks(self) -> str | None:
103
+ if EventTriggers.ON_SUBMIT not in self.event_triggers:
104
+ return
105
+ return HANDLE_SUBMIT_JS_JINJA2.render(
106
+ handle_submit_unique_name=self.handle_submit_unique_name,
107
+ form_data=FORM_DATA,
108
+ field_ref_mapping=str(Var.create_safe(self._get_form_refs())),
109
+ on_submit_event_chain=format_event_chain(
110
+ self.event_triggers[EventTriggers.ON_SUBMIT]
111
+ ),
112
+ reset_on_submit=self.reset_on_submit,
113
+ )
114
+
115
+ def _render(self) -> Tag:
116
+ render_tag = (
117
+ super()
118
+ ._render()
119
+ .remove_props(
120
+ "reset_on_submit",
121
+ "handle_submit_unique_name",
122
+ to_camel_case(EventTriggers.ON_SUBMIT),
123
+ )
124
+ )
125
+ if EventTriggers.ON_SUBMIT in self.event_triggers:
126
+ render_tag.add_props(
127
+ **{
128
+ EventTriggers.ON_SUBMIT: BaseVar(
129
+ _var_name=f"handleSubmit_{self.handle_submit_unique_name}",
130
+ _var_type=EventChain,
131
+ )
132
+ }
133
+ )
134
+ return render_tag
135
+
136
+ def _get_form_refs(self) -> Dict[str, Any]:
137
+ # Send all the input refs to the handler.
138
+ form_refs = {}
139
+ for ref in self.get_refs():
140
+ # when ref start with refs_ it's an array of refs, so we need different method
141
+ # to collect data
142
+ if ref.startswith("refs_"):
143
+ ref_var = Var.create_safe(ref[:-3]).as_ref()
144
+ form_refs[ref[5:-3]] = Var.create_safe(
145
+ f"getRefValues({str(ref_var)})", _var_is_local=False
146
+ )._replace(merge_var_data=ref_var._var_data)
147
+ else:
148
+ ref_var = Var.create_safe(ref).as_ref()
149
+ form_refs[ref[4:]] = Var.create_safe(
150
+ f"getRefValue({str(ref_var)})", _var_is_local=False
151
+ )._replace(merge_var_data=ref_var._var_data)
152
+ return form_refs
153
+
154
+ def _apply_theme(self, theme: Component | None):
155
+ return {
156
+ "width": "260px",
157
+ **self.style,
158
+ }
159
+
160
+ def _get_vars(self) -> Iterator[Var]:
161
+ yield from super()._get_vars()
162
+ yield from self._get_form_refs().values()
163
+
164
+
165
+ class FormField(FormComponent):
166
+ """A form field component."""
167
+
168
+ tag = "Field"
169
+
170
+ alias = "RadixFormField"
171
+
172
+ name: Var[str]
173
+
174
+ server_invalid: Var[bool]
175
+
176
+ def _apply_theme(self, theme: Component | None):
177
+ return {
178
+ "display": "grid",
179
+ "margin_bottom": "10px",
180
+ **self.style,
181
+ }
182
+
183
+
184
+ class FormLabel(FormComponent):
185
+ """A form label component."""
186
+
187
+ tag = "Label"
188
+
189
+ alias = "RadixFormLabel"
190
+
191
+ def _apply_theme(self, theme: Component | None):
192
+ return {
193
+ "font_size": "15px",
194
+ "font_weight": "500",
195
+ "line_height": "35px",
196
+ **self.style,
197
+ }
198
+
199
+
200
+ class FormControl(FormComponent):
201
+ """A form control component."""
202
+
203
+ tag = "Control"
204
+
205
+ alias = "RadixFormControl"
206
+
207
+
208
+ LiteralMatcher = Literal[
209
+ "badInput",
210
+ "patternMismatch",
211
+ "rangeOverflow",
212
+ "rangeUnderflow",
213
+ "stepMismatch",
214
+ "tooLong",
215
+ "tooShort",
216
+ "typeMismatch",
217
+ "valid",
218
+ "valueMissing",
219
+ ]
220
+
221
+
222
+ class FormMessage(FormComponent):
223
+ """A form message component."""
224
+
225
+ tag = "Message"
226
+
227
+ alias = "RadixFormMessage"
228
+
229
+ # Used to target a specific field by name when rendering outside of a Field part.
230
+ name: Var[str]
231
+
232
+ # Used to indicate on which condition the message should be visible.
233
+ match: Var[LiteralMatcher]
234
+
235
+ # Forces the message to be shown. This is useful when using server-side validation.
236
+ forceMatch: Var[bool]
237
+
238
+ def _apply_theme(self, theme: Component | None):
239
+ return {
240
+ "font_size": "13px",
241
+ "opacity": "0.8",
242
+ "color": "white",
243
+ **self.style,
244
+ }
245
+
246
+
247
+ class FormValidityState(FormComponent):
248
+ """A form validity state component."""
249
+
250
+ tag = "ValidityState"
251
+ alias = "RadixFormValidityState"
252
+
253
+
254
+ class FormSubmit(FormComponent):
255
+ """A form submit component."""
256
+
257
+ tag = "Submit"
258
+ alias = "RadixFormSubmit"
259
+
260
+
261
+ form_root = FormRoot.create
262
+ form_field = FormField.create
263
+ form_label = FormLabel.create
264
+ form_control = FormControl.create
265
+ form_message = FormMessage.create
266
+ form_validity_state = FormValidityState.create
267
+ form_submit = FormSubmit.create