reflex 0.3.7a1__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 (324) 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/config.py +1 -1
  283. reflex/constants/installer.py +1 -0
  284. reflex/constants/style.py +1 -1
  285. reflex/event.py +1 -1
  286. reflex/reflex.py +14 -12
  287. reflex/state.py +14 -0
  288. reflex/style.py +1 -1
  289. reflex/testing.py +59 -9
  290. reflex/utils/build.py +7 -1
  291. reflex/utils/exceptions.py +6 -0
  292. reflex/utils/exec.py +2 -2
  293. reflex/utils/export.py +1 -1
  294. reflex/utils/format.py +41 -4
  295. reflex/utils/prerequisites.py +56 -11
  296. reflex/utils/processes.py +8 -1
  297. reflex/utils/types.py +2 -2
  298. reflex/vars.py +25 -1
  299. {reflex-0.3.7a1.dist-info → reflex-0.3.8.dist-info}/METADATA +8 -2
  300. reflex-0.3.8.dist-info/RECORD +492 -0
  301. reflex/components/graphing/__init__.py +0 -5
  302. reflex/components/libs/__init__.py +0 -31
  303. reflex/components/media/audio.py +0 -8
  304. reflex/components/media/image.pyi +0 -123
  305. reflex/components/media/video.py +0 -8
  306. reflex-0.3.7a1.dist-info/RECORD +0 -470
  307. /reflex/components/{layout → base}/fragment.py +0 -0
  308. /reflex/components/{libs/chakra.py → chakra/base.py} +0 -0
  309. /reflex/components/{disclosure → chakra/disclosure}/__init__.py +0 -0
  310. /reflex/components/{feedback → chakra/feedback}/__init__.py +0 -0
  311. /reflex/components/{forms → chakra/forms}/multiselect.py +0 -0
  312. /reflex/components/{datadisplay → gridjs}/datatable.py +0 -0
  313. /reflex/components/{datadisplay → moment}/moment.py +0 -0
  314. /reflex/components/{navigation/nextlink.py → next/link.py} +0 -0
  315. /reflex/components/{graphing → plotly}/plotly.py +0 -0
  316. /reflex/components/{graphing/recharts → recharts}/__init__.py +0 -0
  317. /reflex/components/{graphing/recharts → recharts}/cartesian.py +0 -0
  318. /reflex/components/{graphing/recharts → recharts}/general.py +0 -0
  319. /reflex/components/{graphing/recharts → recharts}/polar.py +0 -0
  320. /reflex/components/{graphing/recharts → recharts}/recharts.py +0 -0
  321. /reflex/components/{forms → suneditor}/editor.py +0 -0
  322. {reflex-0.3.7a1.dist-info → reflex-0.3.8.dist-info}/LICENSE +0 -0
  323. {reflex-0.3.7a1.dist-info → reflex-0.3.8.dist-info}/WHEEL +0 -0
  324. {reflex-0.3.7a1.dist-info → reflex-0.3.8.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,4 @@
1
- """Stub file for reflex/components/libs/react_player.py"""
1
+ """Stub file for reflex/components/react_player/react_player.py"""
2
2
  # ------------------- DO NOT EDIT ----------------------
3
3
  # This file was generated by `scripts/pyi_generator.py`!
4
4
  # ------------------------------------------------------
@@ -10,7 +10,7 @@ from reflex.style import Style
10
10
  from reflex.components.component import NoSSRComponent
11
11
  from reflex.vars import Var
12
12
 
13
- class ReactPlayerComponent(NoSSRComponent):
13
+ class ReactPlayer(NoSSRComponent):
14
14
  @overload
15
15
  @classmethod
16
16
  def create( # type: ignore
@@ -77,7 +77,7 @@ class ReactPlayerComponent(NoSSRComponent):
77
77
  Union[EventHandler, EventSpec, list, function, BaseVar]
78
78
  ] = None,
79
79
  **props
80
- ) -> "ReactPlayerComponent":
80
+ ) -> "ReactPlayer":
81
81
  """Create the component.
82
82
 
83
83
  Args:
@@ -0,0 +1,8 @@
1
+ """A video component."""
2
+ from reflex.components.react_player.react_player import ReactPlayer
3
+
4
+
5
+ class Video(ReactPlayer):
6
+ """Video component share with audio component."""
7
+
8
+ pass
@@ -1,4 +1,4 @@
1
- """Stub file for reflex/components/media/video.py"""
1
+ """Stub file for reflex/components/react_player/video.py"""
2
2
  # ------------------- DO NOT EDIT ----------------------
3
3
  # This file was generated by `scripts/pyi_generator.py`!
4
4
  # ------------------------------------------------------
@@ -7,9 +7,9 @@ from typing import Any, Dict, Literal, Optional, Union, overload
7
7
  from reflex.vars import Var, BaseVar, ComputedVar
8
8
  from reflex.event import EventChain, EventHandler, EventSpec
9
9
  from reflex.style import Style
10
- from reflex.components.libs.react_player import ReactPlayerComponent
10
+ from reflex.components.react_player.react_player import ReactPlayer
11
11
 
12
- class Video(ReactPlayerComponent):
12
+ class Video(ReactPlayer):
13
13
  pass
14
14
 
15
15
  @overload
@@ -1,4 +1,4 @@
1
- """Stub file for reflex/components/graphing/recharts/cartesian.py"""
1
+ """Stub file for reflex/components/recharts/cartesian.py"""
2
2
  # ------------------- DO NOT EDIT ----------------------
3
3
  # This file was generated by `scripts/pyi_generator.py`!
4
4
  # ------------------------------------------------------
@@ -4,7 +4,7 @@ from __future__ import annotations
4
4
  from typing import Any, Dict, List, Union
5
5
 
6
6
  from reflex.components.component import Component
7
- from reflex.components.graphing.recharts.general import ResponsiveContainer
7
+ from reflex.components.recharts.general import ResponsiveContainer
8
8
  from reflex.constants import EventTriggers
9
9
  from reflex.vars import Var
10
10
 
@@ -1,4 +1,4 @@
1
- """Stub file for reflex/components/graphing/recharts/charts.py"""
1
+ """Stub file for reflex/components/recharts/charts.py"""
2
2
  # ------------------- DO NOT EDIT ----------------------
3
3
  # This file was generated by `scripts/pyi_generator.py`!
4
4
  # ------------------------------------------------------
@@ -9,7 +9,7 @@ from reflex.event import EventChain, EventHandler, EventSpec
9
9
  from reflex.style import Style
10
10
  from typing import Any, Dict, List, Union
11
11
  from reflex.components.component import Component
12
- from reflex.components.graphing.recharts.general import ResponsiveContainer
12
+ from reflex.components.recharts.general import ResponsiveContainer
13
13
  from reflex.constants import EventTriggers
14
14
  from reflex.vars import Var
15
15
  from .recharts import (
@@ -1,4 +1,4 @@
1
- """Stub file for reflex/components/graphing/recharts/general.py"""
1
+ """Stub file for reflex/components/recharts/general.py"""
2
2
  # ------------------- DO NOT EDIT ----------------------
3
3
  # This file was generated by `scripts/pyi_generator.py`!
4
4
  # ------------------------------------------------------
@@ -1,4 +1,4 @@
1
- """Stub file for reflex/components/graphing/recharts/polar.py"""
1
+ """Stub file for reflex/components/recharts/polar.py"""
2
2
  # ------------------- DO NOT EDIT ----------------------
3
3
  # This file was generated by `scripts/pyi_generator.py`!
4
4
  # ------------------------------------------------------
@@ -1,4 +1,4 @@
1
- """Stub file for reflex/components/graphing/recharts/recharts.py"""
1
+ """Stub file for reflex/components/recharts/recharts.py"""
2
2
  # ------------------- DO NOT EDIT ----------------------
3
3
  # This file was generated by `scripts/pyi_generator.py`!
4
4
  # ------------------------------------------------------
@@ -0,0 +1,5 @@
1
+ """Editor component."""
2
+
3
+ from .editor import Editor, EditorButtonList, EditorOptions
4
+
5
+ editor = Editor.create
@@ -1,4 +1,4 @@
1
- """Stub file for reflex/components/forms/editor.py"""
1
+ """Stub file for reflex/components/suneditor/editor.py"""
2
2
  # ------------------- DO NOT EDIT ----------------------
3
3
  # This file was generated by `scripts/pyi_generator.py`!
4
4
  # ------------------------------------------------------
@@ -2,4 +2,5 @@
2
2
 
3
3
  from .cond_tag import CondTag
4
4
  from .iter_tag import IterTag
5
+ from .match_tag import MatchTag
5
6
  from .tag import Tag
@@ -102,9 +102,9 @@ class IterTag(Tag):
102
102
  The rendered component.
103
103
  """
104
104
  # Import here to avoid circular imports.
105
- from reflex.components.layout.cond import Cond
106
- from reflex.components.layout.foreach import Foreach
107
- from reflex.components.layout.fragment import Fragment
105
+ from reflex.components.base.fragment import Fragment
106
+ from reflex.components.core.cond import Cond
107
+ from reflex.components.core.foreach import Foreach
108
108
 
109
109
  # Get the render function arguments.
110
110
  args = inspect.getfullargspec(self.render_fn).args
@@ -0,0 +1,19 @@
1
+ """Tag to conditionally match cases."""
2
+
3
+ from typing import Any, List
4
+
5
+ from reflex.components.tags.tag import Tag
6
+ from reflex.vars import Var
7
+
8
+
9
+ class MatchTag(Tag):
10
+ """A match tag."""
11
+
12
+ # The condition to determine which case to match.
13
+ cond: Var[Any]
14
+
15
+ # The list of match cases to be matched.
16
+ match_cases: List[Any]
17
+
18
+ # The catchall case to match.
19
+ default: Any
reflex/constants/base.py CHANGED
@@ -43,6 +43,8 @@ class Dirs(SimpleNamespace):
43
43
  ENV_JSON = os.path.join(WEB, "env.json")
44
44
  # The reflex json file.
45
45
  REFLEX_JSON = os.path.join(WEB, "reflex.json")
46
+ # The path to postcss.config.js
47
+ POSTCSS_JS = os.path.join(WEB, "postcss.config.js")
46
48
 
47
49
 
48
50
  class Reflex(SimpleNamespace):
@@ -47,7 +47,7 @@ class RequirementsTxt(SimpleNamespace):
47
47
  # The requirements.txt file.
48
48
  FILE = "requirements.txt"
49
49
  # The partial text used to form requirement that pins a reflex version
50
- DEFAULTS_STUB = f"{Reflex.MODULE_NAME}>="
50
+ DEFAULTS_STUB = f"{Reflex.MODULE_NAME}=="
51
51
 
52
52
 
53
53
  # The deployment URL.
@@ -102,6 +102,7 @@ class PackageJson(SimpleNamespace):
102
102
  PATH = os.path.join(Dirs.WEB, "package.json")
103
103
 
104
104
  DEPENDENCIES = {
105
+ "@emotion/react": "11.11.1",
105
106
  "axios": "1.4.0",
106
107
  "json5": "2.2.3",
107
108
  "next": "14.0.1",
reflex/constants/style.py CHANGED
@@ -17,6 +17,6 @@ class Tailwind(SimpleNamespace):
17
17
  # The Tailwind config.
18
18
  CONFIG = os.path.join(Dirs.WEB, "tailwind.config.js")
19
19
  # Default Tailwind content paths
20
- CONTENT = ["./pages/**/*.{js,ts,jsx,tsx}"]
20
+ CONTENT = ["./pages/**/*.{js,ts,jsx,tsx}", "./utils/**/*.{js,ts,jsx,tsx}"]
21
21
  # Relative tailwind style path to root stylesheet in STYLES_DIR.
22
22
  ROOT_STYLE_PATH = "./tailwind.css"
reflex/event.py CHANGED
@@ -329,7 +329,7 @@ class FileUpload(Base):
329
329
  Raises:
330
330
  ValueError: If the on_upload_progress is not a valid event handler.
331
331
  """
332
- from reflex.components.forms.upload import (
332
+ from reflex.components.core.upload import (
333
333
  DEFAULT_UPLOAD_ID,
334
334
  upload_files_context_var_data,
335
335
  )
reflex/reflex.py CHANGED
@@ -74,18 +74,12 @@ def _init(
74
74
  # Show system info
75
75
  exec.output_system_info()
76
76
 
77
- # Get the app name.
78
- app_name = prerequisites.get_default_app_name() if name is None else name
77
+ # Validate the app name.
78
+ app_name = prerequisites.validate_app_name(name)
79
79
  console.rule(f"[bold]Initializing {app_name}")
80
80
 
81
81
  prerequisites.check_latest_package_version(constants.Reflex.MODULE_NAME)
82
82
 
83
- # Set up the web project.
84
- prerequisites.initialize_frontend_dependencies()
85
-
86
- # Migrate Pynecone projects to Reflex.
87
- prerequisites.migrate_to_reflex()
88
-
89
83
  # Set up the app directory, only if the config doesn't exist.
90
84
  if not os.path.exists(constants.Config.FILE):
91
85
  if template is None:
@@ -96,6 +90,12 @@ def _init(
96
90
  else:
97
91
  telemetry.send("reinit")
98
92
 
93
+ # Set up the web project.
94
+ prerequisites.initialize_frontend_dependencies()
95
+
96
+ # Migrate Pynecone projects to Reflex.
97
+ prerequisites.migrate_to_reflex()
98
+
99
99
  # Initialize the .gitignore.
100
100
  prerequisites.initialize_gitignore()
101
101
 
@@ -178,7 +178,7 @@ def _run(
178
178
  if frontend:
179
179
  prerequisites.update_next_config()
180
180
  # Get the app module.
181
- prerequisites.get_app()
181
+ prerequisites.get_compiled_app()
182
182
 
183
183
  # Warn if schema is not up to date.
184
184
  prerequisites.check_schema_up_to_date()
@@ -362,7 +362,7 @@ def db_init():
362
362
 
363
363
  # Initialize the database.
364
364
  _skip_compile()
365
- prerequisites.get_app()
365
+ prerequisites.get_compiled_app()
366
366
  model.Model.alembic_init()
367
367
  model.Model.migrate(autogenerate=True)
368
368
 
@@ -373,8 +373,9 @@ def migrate():
373
373
  from reflex import model
374
374
  from reflex.utils import prerequisites
375
375
 
376
+ # TODO see if we can use `get_app()` instead (no compile). Would _skip_compile still be needed then?
376
377
  _skip_compile()
377
- prerequisites.get_app()
378
+ prerequisites.get_compiled_app()
378
379
  if not prerequisites.check_db_initialized():
379
380
  return
380
381
  model.Model.migrate()
@@ -393,8 +394,9 @@ def makemigrations(
393
394
  from reflex import model
394
395
  from reflex.utils import prerequisites
395
396
 
397
+ # TODO see if we can use `get_app()` instead (no compile). Would _skip_compile still be needed then?
396
398
  _skip_compile()
397
- prerequisites.get_app()
399
+ prerequisites.get_compiled_app()
398
400
  if not prerequisites.check_db_initialized():
399
401
  return
400
402
  with model.Model.get_db_engine().connect() as connection:
reflex/state.py CHANGED
@@ -1316,6 +1316,7 @@ class State(BaseState):
1316
1316
  Returns:
1317
1317
  The list of events to queue for on load handling.
1318
1318
  """
1319
+ # Do not app.compile_()! It should be already compiled by now.
1319
1320
  app = getattr(prerequisites.get_app(), constants.CompileVars.APP)
1320
1321
  load_events = app.get_load_events(self.router.page.path)
1321
1322
  if not load_events and self.is_hydrated:
@@ -1364,6 +1365,7 @@ class StateProxy(wrapt.ObjectProxy):
1364
1365
  state_instance: The state instance to proxy.
1365
1366
  """
1366
1367
  super().__init__(state_instance)
1368
+ # compile is not relevant to backend logic
1367
1369
  self._self_app = getattr(prerequisites.get_app(), constants.CompileVars.APP)
1368
1370
  self._self_substate_path = state_instance.get_full_name().split(".")
1369
1371
  self._self_actx = None
@@ -2179,3 +2181,15 @@ class ImmutableMutableProxy(MutableProxy):
2179
2181
  return super()._mark_dirty(
2180
2182
  wrapped=wrapped, instance=instance, args=args, kwargs=kwargs
2181
2183
  )
2184
+
2185
+
2186
+ def code_uses_state_contexts(javascript_code: str) -> bool:
2187
+ """Check if the rendered Javascript uses state contexts.
2188
+
2189
+ Args:
2190
+ javascript_code: The Javascript code to check.
2191
+
2192
+ Returns:
2193
+ True if the code attempts to access a member of StateContexts.
2194
+ """
2195
+ return bool("useContext(StateContexts" in javascript_code)
reflex/style.py CHANGED
@@ -108,7 +108,7 @@ def convert(style_dict):
108
108
  var_data = None # Track import/hook data from any Vars in the style dict.
109
109
  out = {}
110
110
  for key, value in style_dict.items():
111
- key = format.to_camel_case(key)
111
+ key = format.to_camel_case(key, allow_hyphens=True)
112
112
  if isinstance(value, dict):
113
113
  # Recursively format nested style dictionaries.
114
114
  out[key], new_var_data = convert(value)
reflex/testing.py CHANGED
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
  import asyncio
5
5
  import contextlib
6
6
  import dataclasses
7
+ import functools
7
8
  import inspect
8
9
  import os
9
10
  import pathlib
@@ -20,6 +21,7 @@ import types
20
21
  from http.server import SimpleHTTPRequestHandler
21
22
  from typing import (
22
23
  TYPE_CHECKING,
24
+ Any,
23
25
  AsyncIterator,
24
26
  Callable,
25
27
  Coroutine,
@@ -135,6 +137,8 @@ class AppHarness:
135
137
  if app_name is None:
136
138
  if app_source is None:
137
139
  app_name = root.name.lower()
140
+ elif isinstance(app_source, functools.partial):
141
+ app_name = app_source.func.__name__.lower()
138
142
  else:
139
143
  app_name = app_source.__name__.lower()
140
144
  return cls(
@@ -144,13 +148,54 @@ class AppHarness:
144
148
  app_module_path=root / app_name / f"{app_name}.py",
145
149
  )
146
150
 
151
+ def _get_globals_from_signature(self, func: Any) -> dict[str, Any]:
152
+ """Get the globals from a function or module object.
153
+
154
+ Args:
155
+ func: function or module object
156
+
157
+ Returns:
158
+ dict of globals
159
+ """
160
+ overrides = {}
161
+ glbs = {}
162
+ if not callable(func):
163
+ return glbs
164
+ if isinstance(func, functools.partial):
165
+ overrides = func.keywords
166
+ func = func.func
167
+ for param in inspect.signature(func).parameters.values():
168
+ if param.default is not inspect.Parameter.empty:
169
+ glbs[param.name] = param.default
170
+ glbs.update(overrides)
171
+ return glbs
172
+
173
+ def _get_source_from_func(self, func: Any) -> str:
174
+ """Get the source from a function or module object.
175
+
176
+ Args:
177
+ func: function or module object
178
+
179
+ Returns:
180
+ source code
181
+ """
182
+ source = inspect.getsource(func)
183
+ source = re.sub(r"^\s*def\s+\w+\s*\(.*?\):", "", source, flags=re.DOTALL)
184
+ return textwrap.dedent(source)
185
+
147
186
  def _initialize_app(self):
148
187
  os.environ["TELEMETRY_ENABLED"] = "" # disable telemetry reporting for tests
149
188
  self.app_path.mkdir(parents=True, exist_ok=True)
150
189
  if self.app_source is not None:
190
+ app_globals = self._get_globals_from_signature(self.app_source)
191
+ if isinstance(self.app_source, functools.partial):
192
+ self.app_source = self.app_source.func # type: ignore
151
193
  # get the source from a function or module object
152
- source_code = textwrap.dedent(
153
- "".join(inspect.getsource(self.app_source).splitlines(True)[1:]),
194
+ source_code = "\n".join(
195
+ [
196
+ "\n".join(f"{k} = {v!r}" for k, v in app_globals.items()),
197
+ self._get_source_from_func(self.app_source),
198
+ ]
154
199
  )
155
200
  with chdir(self.app_path):
156
201
  reflex.reflex._init(
@@ -164,14 +209,16 @@ class AppHarness:
164
209
  reflex.config.get_config(reload=True)
165
210
  # reset rx.State subclasses
166
211
  State.class_subclasses.clear()
212
+ # Ensure the AppHarness test does not skip State assignment due to running via pytest
213
+ os.environ.pop(reflex.constants.PYTEST_CURRENT_TEST, None)
167
214
  # self.app_module.app.
168
- self.app_module = reflex.utils.prerequisites.get_app(reload=True)
215
+ self.app_module = reflex.utils.prerequisites.get_compiled_app(reload=True)
169
216
  self.app_instance = self.app_module.app
170
- if isinstance(self.app_instance.state_manager, StateManagerRedis):
217
+ if isinstance(self.app_instance._state_manager, StateManagerRedis):
171
218
  # Create our own redis connection for testing.
172
219
  self.state_manager = StateManagerRedis.create(self.app_instance.state)
173
220
  else:
174
- self.state_manager = self.app_instance.state_manager
221
+ self.state_manager = self.app_instance._state_manager
175
222
 
176
223
  def _get_backend_shutdown_handler(self):
177
224
  if self.backend is None:
@@ -181,10 +228,13 @@ class AppHarness:
181
228
 
182
229
  async def _shutdown_redis(*args, **kwargs) -> None:
183
230
  # ensure redis is closed before event loop
184
- if self.app_instance is not None and isinstance(
185
- self.app_instance.state_manager, StateManagerRedis
186
- ):
187
- await self.app_instance.state_manager.close()
231
+ try:
232
+ if self.app_instance is not None and isinstance(
233
+ self.app_instance.state_manager, StateManagerRedis
234
+ ):
235
+ await self.app_instance.state_manager.close()
236
+ except ValueError:
237
+ pass
188
238
  await original_shutdown(*args, **kwargs)
189
239
 
190
240
  return _shutdown_redis
reflex/utils/build.py CHANGED
@@ -67,6 +67,7 @@ def _zip(
67
67
  upload_db_file: bool = False,
68
68
  dirs_to_exclude: set[str] | None = None,
69
69
  files_to_exclude: set[str] | None = None,
70
+ top_level_dirs_to_exclude: set[str] | None = None,
70
71
  ) -> None:
71
72
  """Zip utility function.
72
73
 
@@ -78,6 +79,7 @@ def _zip(
78
79
  upload_db_file: Whether to include local sqlite db files.
79
80
  dirs_to_exclude: The directories to exclude.
80
81
  files_to_exclude: The files to exclude.
82
+ top_level_dirs_to_exclude: The top level directory names immediately under root_dir to exclude. Do not exclude folders by these names further in the sub-directories.
81
83
 
82
84
  """
83
85
  dirs_to_exclude = dirs_to_exclude or set()
@@ -97,6 +99,9 @@ def _zip(
97
99
  not exclude_venv_dirs or not _looks_like_venv_dir(os.path.join(root, d))
98
100
  )
99
101
  ]
102
+ # If we are at the top level with root_dir, exclude the top level dirs.
103
+ if top_level_dirs_to_exclude and root == root_dir:
104
+ dirs[:] = [d for d in dirs if d not in top_level_dirs_to_exclude]
100
105
  # Modify the files in-place so the hidden files and db files are excluded.
101
106
  files[:] = [
102
107
  f
@@ -197,8 +202,9 @@ def export(
197
202
  zip_dest_dir, constants.ComponentName.BACKEND.zip()
198
203
  ),
199
204
  root_dir=".",
200
- dirs_to_exclude={"assets", "__pycache__"},
205
+ dirs_to_exclude={"__pycache__"},
201
206
  files_to_exclude=files_to_exclude,
207
+ top_level_dirs_to_exclude={"assets"},
202
208
  exclude_venv_dirs=True,
203
209
  upload_db_file=upload_db_file,
204
210
  )
@@ -13,3 +13,9 @@ class ImmutableStateError(AttributeError):
13
13
 
14
14
  class LockExpiredError(Exception):
15
15
  """Raised when the state lock expires while an event is being processed."""
16
+
17
+
18
+ class MatchTypeError(TypeError):
19
+ """Raised when the return types of match cases are different."""
20
+
21
+ pass
reflex/utils/exec.py CHANGED
@@ -160,7 +160,7 @@ def run_backend(
160
160
  import uvicorn
161
161
 
162
162
  config = get_config()
163
- app_module = f"{config.app_name}.{config.app_name}:{constants.CompileVars.APP}"
163
+ app_module = f"reflex.app_module_for_backend:{constants.CompileVars.APP}"
164
164
 
165
165
  # Create a .nocompile file to skip compile for backend.
166
166
  if os.path.exists(constants.Dirs.WEB):
@@ -196,7 +196,7 @@ def run_backend_prod(
196
196
  config = get_config()
197
197
  RUN_BACKEND_PROD = f"gunicorn --worker-class {config.gunicorn_worker_class} --preload --timeout {config.timeout} --log-level critical".split()
198
198
  RUN_BACKEND_PROD_WINDOWS = f"uvicorn --timeout-keep-alive {config.timeout}".split()
199
- app_module = f"{config.app_name}.{config.app_name}:{constants.CompileVars.APP}"
199
+ app_module = f"reflex.app_module_for_backend:{constants.CompileVars.APP}"
200
200
  command = (
201
201
  [
202
202
  *RUN_BACKEND_PROD_WINDOWS,
reflex/utils/export.py CHANGED
@@ -56,7 +56,7 @@ def export(
56
56
  # Update some parameters for export
57
57
  prerequisites.update_next_config(export=True)
58
58
  # Ensure module can be imported and app.compile() is called.
59
- prerequisites.get_app()
59
+ prerequisites.get_compiled_app()
60
60
  # Set up .web directory and install frontend dependencies.
61
61
  build.setup_frontend(Path.cwd())
62
62
 
reflex/utils/format.py CHANGED
@@ -7,7 +7,7 @@ import json
7
7
  import os
8
8
  import re
9
9
  import sys
10
- from typing import TYPE_CHECKING, Any, Union
10
+ from typing import TYPE_CHECKING, Any, List, Union
11
11
 
12
12
  from reflex import constants
13
13
  from reflex.utils import exceptions, serializers, types
@@ -125,7 +125,7 @@ def to_snake_case(text: str) -> str:
125
125
  return re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1).lower().replace("-", "_")
126
126
 
127
127
 
128
- def to_camel_case(text: str) -> str:
128
+ def to_camel_case(text: str, allow_hyphens: bool = False) -> str:
129
129
  """Convert a string to camel case.
130
130
 
131
131
  The first word in the text is converted to lowercase and
@@ -133,12 +133,14 @@ def to_camel_case(text: str) -> str:
133
133
 
134
134
  Args:
135
135
  text: The string to convert.
136
+ allow_hyphens: Whether to allow hyphens in the string.
136
137
 
137
138
  Returns:
138
139
  The camel case string.
139
140
  """
140
- words = re.split("[_-]", text.lstrip("-_"))
141
- leading_underscores_or_hyphens = "".join(re.findall(r"^[_-]+", text))
141
+ char = "_" if allow_hyphens else "-_"
142
+ words = re.split(f"[{char}]", text.lstrip(char))
143
+ leading_underscores_or_hyphens = "".join(re.findall(rf"^[{char}]+", text))
142
144
  # Capitalize the first letter of each word except the first one
143
145
  converted_word = words[0] + "".join(x.capitalize() for x in words[1:])
144
146
  return leading_underscores_or_hyphens + converted_word
@@ -270,6 +272,41 @@ def format_cond(
270
272
  return wrap(f"{cond} ? {true_value} : {false_value}", "{")
271
273
 
272
274
 
275
+ def format_match(cond: str | Var, match_cases: List[BaseVar], default: Var) -> str:
276
+ """Format a match expression whose return type is a Var.
277
+
278
+ Args:
279
+ cond: The condition.
280
+ match_cases: The list of cases to match.
281
+ default: The default case.
282
+
283
+ Returns:
284
+ The formatted match expression
285
+
286
+ """
287
+ switch_code = f"(() => {{ switch (JSON.stringify({cond})) {{"
288
+
289
+ for case in match_cases:
290
+ conditions = case[:-1]
291
+ return_value = case[-1]
292
+
293
+ case_conditions = " ".join(
294
+ [
295
+ f"case JSON.stringify({condition._var_name_unwrapped}):"
296
+ for condition in conditions
297
+ ]
298
+ )
299
+ case_code = (
300
+ f"{case_conditions} return ({return_value._var_name_unwrapped}); break;"
301
+ )
302
+ switch_code += case_code
303
+
304
+ switch_code += f"default: return ({default._var_name_unwrapped}); break;"
305
+ switch_code += "};})()"
306
+
307
+ return switch_code
308
+
309
+
273
310
  def format_prop(
274
311
  prop: Union[Var, EventChain, ComponentStyle, str],
275
312
  ) -> Union[int, float, str]: