reflex 0.5.10a3__py3-none-any.whl → 0.6.0a1__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 (237) hide show
  1. reflex/.templates/jinja/web/pages/utils.js.jinja2 +4 -4
  2. reflex/.templates/jinja/web/utils/context.js.jinja2 +1 -1
  3. reflex/.templates/jinja/web/utils/theme.js.jinja2 +1 -1
  4. reflex/__init__.py +3 -2
  5. reflex/__init__.pyi +2 -2
  6. reflex/app.py +43 -9
  7. reflex/base.py +3 -2
  8. reflex/compiler/compiler.py +6 -6
  9. reflex/compiler/utils.py +5 -3
  10. reflex/components/base/app_wrap.py +2 -4
  11. reflex/components/base/app_wrap.pyi +17 -17
  12. reflex/components/base/bare.py +7 -4
  13. reflex/components/base/body.pyi +17 -17
  14. reflex/components/base/document.pyi +81 -81
  15. reflex/components/base/error_boundary.py +10 -8
  16. reflex/components/base/error_boundary.pyi +20 -19
  17. reflex/components/base/fragment.pyi +17 -17
  18. reflex/components/base/head.pyi +33 -33
  19. reflex/components/base/link.pyi +34 -33
  20. reflex/components/base/meta.pyi +65 -65
  21. reflex/components/base/script.py +2 -1
  22. reflex/components/base/script.pyi +21 -20
  23. reflex/components/component.py +116 -145
  24. reflex/components/core/banner.py +59 -60
  25. reflex/components/core/banner.pyi +86 -150
  26. reflex/components/core/client_side_routing.py +2 -1
  27. reflex/components/core/client_side_routing.pyi +34 -33
  28. reflex/components/core/clipboard.py +2 -2
  29. reflex/components/core/clipboard.pyi +19 -18
  30. reflex/components/core/cond.py +21 -44
  31. reflex/components/core/debounce.py +6 -8
  32. reflex/components/core/debounce.pyi +19 -18
  33. reflex/components/core/foreach.py +5 -14
  34. reflex/components/core/html.pyi +18 -17
  35. reflex/components/core/match.py +36 -43
  36. reflex/components/core/upload.py +32 -25
  37. reflex/components/core/upload.pyi +84 -73
  38. reflex/components/datadisplay/code.py +55 -28
  39. reflex/components/datadisplay/code.pyi +20 -17
  40. reflex/components/datadisplay/dataeditor.py +17 -11
  41. reflex/components/datadisplay/dataeditor.pyi +34 -33
  42. reflex/components/el/__init__.py +0 -1
  43. reflex/components/el/__init__.pyi +0 -11
  44. reflex/components/el/element.pyi +17 -17
  45. reflex/components/el/elements/__init__.py +1 -7
  46. reflex/components/el/elements/__init__.pyi +1 -15
  47. reflex/components/el/elements/base.pyi +18 -17
  48. reflex/components/el/elements/forms.py +24 -31
  49. reflex/components/el/elements/forms.pyi +237 -236
  50. reflex/components/el/elements/inline.pyi +450 -449
  51. reflex/components/el/elements/media.py +0 -21
  52. reflex/components/el/elements/media.pyi +338 -337
  53. reflex/components/el/elements/metadata.py +3 -2
  54. reflex/components/el/elements/metadata.pyi +98 -97
  55. reflex/components/el/elements/other.pyi +114 -113
  56. reflex/components/el/elements/scripts.pyi +50 -49
  57. reflex/components/el/elements/sectioning.pyi +242 -241
  58. reflex/components/el/elements/tables.pyi +162 -161
  59. reflex/components/el/elements/typography.pyi +242 -241
  60. reflex/components/gridjs/datatable.py +13 -14
  61. reflex/components/gridjs/datatable.pyi +34 -33
  62. reflex/components/lucide/icon.py +2 -126
  63. reflex/components/lucide/icon.pyi +34 -142
  64. reflex/components/markdown/markdown.py +30 -35
  65. reflex/components/markdown/markdown.pyi +29 -32
  66. reflex/components/moment/moment.pyi +19 -18
  67. reflex/components/next/base.pyi +17 -17
  68. reflex/components/next/image.py +0 -4
  69. reflex/components/next/image.pyi +20 -19
  70. reflex/components/next/link.pyi +18 -17
  71. reflex/components/next/video.pyi +18 -17
  72. reflex/components/plotly/plotly.py +16 -28
  73. reflex/components/plotly/plotly.pyi +36 -35
  74. reflex/components/props.py +21 -10
  75. reflex/components/radix/__init__.pyi +1 -1
  76. reflex/components/radix/primitives/__init__.pyi +0 -1
  77. reflex/components/radix/primitives/accordion.py +7 -8
  78. reflex/components/radix/primitives/accordion.pyi +117 -116
  79. reflex/components/radix/primitives/base.pyi +34 -33
  80. reflex/components/radix/primitives/drawer.pyi +169 -168
  81. reflex/components/radix/primitives/form.pyi +168 -167
  82. reflex/components/radix/primitives/progress.pyi +82 -81
  83. reflex/components/radix/primitives/slider.pyi +84 -83
  84. reflex/components/radix/themes/base.py +8 -4
  85. reflex/components/radix/themes/base.pyi +114 -113
  86. reflex/components/radix/themes/color_mode.py +12 -21
  87. reflex/components/radix/themes/color_mode.pyi +67 -67
  88. reflex/components/radix/themes/components/__init__.pyi +1 -0
  89. reflex/components/radix/themes/components/alert_dialog.pyi +118 -117
  90. reflex/components/radix/themes/components/aspect_ratio.pyi +18 -17
  91. reflex/components/radix/themes/components/avatar.pyi +18 -17
  92. reflex/components/radix/themes/components/badge.pyi +18 -17
  93. reflex/components/radix/themes/components/button.pyi +18 -17
  94. reflex/components/radix/themes/components/callout.pyi +82 -81
  95. reflex/components/radix/themes/components/card.pyi +18 -17
  96. reflex/components/radix/themes/components/checkbox.py +2 -3
  97. reflex/components/radix/themes/components/checkbox.pyi +53 -52
  98. reflex/components/radix/themes/components/checkbox_cards.pyi +34 -33
  99. reflex/components/radix/themes/components/checkbox_group.pyi +34 -33
  100. reflex/components/radix/themes/components/context_menu.pyi +140 -139
  101. reflex/components/radix/themes/components/data_list.py +5 -0
  102. reflex/components/radix/themes/components/data_list.pyi +71 -65
  103. reflex/components/radix/themes/components/dialog.pyi +121 -120
  104. reflex/components/radix/themes/components/dropdown_menu.pyi +142 -141
  105. reflex/components/radix/themes/components/hover_card.pyi +68 -67
  106. reflex/components/radix/themes/components/icon_button.py +2 -1
  107. reflex/components/radix/themes/components/icon_button.pyi +18 -17
  108. reflex/components/radix/themes/components/inset.pyi +18 -17
  109. reflex/components/radix/themes/components/popover.pyi +73 -72
  110. reflex/components/radix/themes/components/progress.pyi +18 -17
  111. reflex/components/radix/themes/components/radio.pyi +18 -17
  112. reflex/components/radix/themes/components/radio_cards.pyi +35 -34
  113. reflex/components/radix/themes/components/radio_group.py +35 -31
  114. reflex/components/radix/themes/components/radio_group.pyi +73 -66
  115. reflex/components/radix/themes/components/scroll_area.pyi +18 -17
  116. reflex/components/radix/themes/components/segmented_control.pyi +35 -34
  117. reflex/components/radix/themes/components/select.py +2 -1
  118. reflex/components/radix/themes/components/select.pyi +155 -154
  119. reflex/components/radix/themes/components/separator.py +2 -3
  120. reflex/components/radix/themes/components/separator.pyi +18 -17
  121. reflex/components/radix/themes/components/skeleton.pyi +18 -17
  122. reflex/components/radix/themes/components/slider.py +2 -1
  123. reflex/components/radix/themes/components/slider.pyi +20 -19
  124. reflex/components/radix/themes/components/spinner.pyi +18 -17
  125. reflex/components/radix/themes/components/switch.pyi +19 -18
  126. reflex/components/radix/themes/components/table.pyi +114 -113
  127. reflex/components/radix/themes/components/tabs.pyi +84 -83
  128. reflex/components/radix/themes/components/text_area.pyi +21 -20
  129. reflex/components/radix/themes/components/text_field.py +0 -79
  130. reflex/components/radix/themes/components/text_field.pyi +57 -63
  131. reflex/components/radix/themes/components/tooltip.pyi +21 -20
  132. reflex/components/radix/themes/layout/base.pyi +18 -17
  133. reflex/components/radix/themes/layout/box.pyi +18 -17
  134. reflex/components/radix/themes/layout/center.pyi +18 -17
  135. reflex/components/radix/themes/layout/container.py +2 -3
  136. reflex/components/radix/themes/layout/container.pyi +18 -17
  137. reflex/components/radix/themes/layout/flex.pyi +18 -17
  138. reflex/components/radix/themes/layout/grid.pyi +18 -17
  139. reflex/components/radix/themes/layout/list.py +5 -4
  140. reflex/components/radix/themes/layout/list.pyi +86 -85
  141. reflex/components/radix/themes/layout/section.py +2 -3
  142. reflex/components/radix/themes/layout/section.pyi +18 -17
  143. reflex/components/radix/themes/layout/spacer.pyi +18 -17
  144. reflex/components/radix/themes/layout/stack.pyi +50 -49
  145. reflex/components/radix/themes/typography/blockquote.pyi +18 -17
  146. reflex/components/radix/themes/typography/code.pyi +18 -17
  147. reflex/components/radix/themes/typography/heading.pyi +18 -17
  148. reflex/components/radix/themes/typography/link.pyi +18 -17
  149. reflex/components/radix/themes/typography/text.pyi +114 -113
  150. reflex/components/react_player/audio.pyi +34 -33
  151. reflex/components/react_player/react_player.pyi +34 -33
  152. reflex/components/react_player/video.pyi +34 -33
  153. reflex/components/recharts/cartesian.py +23 -19
  154. reflex/components/recharts/cartesian.pyi +297 -296
  155. reflex/components/recharts/charts.py +6 -5
  156. reflex/components/recharts/charts.pyi +179 -178
  157. reflex/components/recharts/general.py +8 -7
  158. reflex/components/recharts/general.pyi +82 -81
  159. reflex/components/recharts/polar.py +14 -13
  160. reflex/components/recharts/polar.pyi +76 -75
  161. reflex/components/recharts/recharts.pyi +33 -33
  162. reflex/components/sonner/toast.py +30 -33
  163. reflex/components/sonner/toast.pyi +27 -25
  164. reflex/components/suneditor/editor.py +2 -1
  165. reflex/components/suneditor/editor.pyi +27 -26
  166. reflex/components/tags/iter_tag.py +16 -16
  167. reflex/components/tags/tag.py +8 -10
  168. reflex/constants/base.py +3 -1
  169. reflex/constants/event.py +1 -0
  170. reflex/event.py +89 -79
  171. reflex/experimental/__init__.py +25 -6
  172. reflex/experimental/client_state.py +34 -58
  173. reflex/experimental/hooks.py +13 -18
  174. reflex/experimental/layout.py +5 -5
  175. reflex/experimental/layout.pyi +84 -83
  176. reflex/{experimental/vars → ivars}/__init__.py +0 -1
  177. reflex/ivars/base.py +2180 -0
  178. reflex/ivars/function.py +200 -0
  179. reflex/ivars/number.py +1137 -0
  180. reflex/ivars/object.py +564 -0
  181. reflex/ivars/sequence.py +1601 -0
  182. reflex/model.py +22 -0
  183. reflex/reflex.py +4 -0
  184. reflex/state.py +388 -73
  185. reflex/style.py +52 -34
  186. reflex/testing.py +8 -3
  187. reflex/utils/exceptions.py +12 -0
  188. reflex/utils/exec.py +0 -14
  189. reflex/utils/format.py +74 -223
  190. reflex/utils/net.py +43 -0
  191. reflex/utils/path_ops.py +13 -1
  192. reflex/utils/prerequisites.py +46 -26
  193. reflex/utils/pyi_generator.py +5 -4
  194. reflex/utils/serializers.py +13 -31
  195. reflex/utils/types.py +44 -9
  196. reflex/vars.py +127 -2230
  197. {reflex-0.5.10a3.dist-info → reflex-0.6.0a1.dist-info}/METADATA +4 -6
  198. reflex-0.6.0a1.dist-info/RECORD +384 -0
  199. reflex/.templates/apps/demo/.gitignore +0 -4
  200. reflex/.templates/apps/demo/assets/favicon.ico +0 -0
  201. reflex/.templates/apps/demo/assets/github.svg +0 -10
  202. reflex/.templates/apps/demo/assets/icon.svg +0 -37
  203. reflex/.templates/apps/demo/assets/logo.svg +0 -68
  204. reflex/.templates/apps/demo/assets/paneleft.svg +0 -13
  205. reflex/.templates/apps/demo/code/__init__.py +0 -1
  206. reflex/.templates/apps/demo/code/demo.py +0 -127
  207. reflex/.templates/apps/demo/code/pages/__init__.py +0 -7
  208. reflex/.templates/apps/demo/code/pages/chatapp.py +0 -31
  209. reflex/.templates/apps/demo/code/pages/datatable.py +0 -360
  210. reflex/.templates/apps/demo/code/pages/forms.py +0 -257
  211. reflex/.templates/apps/demo/code/pages/graphing.py +0 -253
  212. reflex/.templates/apps/demo/code/pages/home.py +0 -56
  213. reflex/.templates/apps/demo/code/sidebar.py +0 -178
  214. reflex/.templates/apps/demo/code/state.py +0 -22
  215. reflex/.templates/apps/demo/code/states/form_state.py +0 -40
  216. reflex/.templates/apps/demo/code/states/pie_state.py +0 -47
  217. reflex/.templates/apps/demo/code/styles.py +0 -68
  218. reflex/.templates/apps/demo/code/webui/__init__.py +0 -0
  219. reflex/.templates/apps/demo/code/webui/components/__init__.py +0 -4
  220. reflex/.templates/apps/demo/code/webui/components/chat.py +0 -118
  221. reflex/.templates/apps/demo/code/webui/components/loading_icon.py +0 -19
  222. reflex/.templates/apps/demo/code/webui/components/modal.py +0 -56
  223. reflex/.templates/apps/demo/code/webui/components/navbar.py +0 -70
  224. reflex/.templates/apps/demo/code/webui/components/sidebar.py +0 -66
  225. reflex/.templates/apps/demo/code/webui/state.py +0 -146
  226. reflex/.templates/apps/demo/code/webui/styles.py +0 -88
  227. reflex/experimental/vars/base.py +0 -583
  228. reflex/experimental/vars/function.py +0 -290
  229. reflex/experimental/vars/number.py +0 -1458
  230. reflex/experimental/vars/object.py +0 -804
  231. reflex/experimental/vars/sequence.py +0 -1764
  232. reflex/utils/watch.py +0 -96
  233. reflex/vars.pyi +0 -218
  234. reflex-0.5.10a3.dist-info/RECORD +0 -413
  235. {reflex-0.5.10a3.dist-info → reflex-0.6.0a1.dist-info}/LICENSE +0 -0
  236. {reflex-0.5.10a3.dist-info → reflex-0.6.0a1.dist-info}/WHEEL +0 -0
  237. {reflex-0.5.10a3.dist-info → reflex-0.6.0a1.dist-info}/entry_points.txt +0 -0
@@ -43,11 +43,18 @@ from reflex.event import (
43
43
  call_event_handler,
44
44
  get_handler_args,
45
45
  )
46
+ from reflex.ivars.base import ImmutableVar, LiteralVar
46
47
  from reflex.style import Style, format_as_emotion
47
- from reflex.utils import console, format, imports, types
48
- from reflex.utils.imports import ImportDict, ImportVar, ParsedImportDict, parse_imports
48
+ from reflex.utils import format, imports, types
49
+ from reflex.utils.imports import (
50
+ ImmutableParsedImportDict,
51
+ ImportDict,
52
+ ImportVar,
53
+ ParsedImportDict,
54
+ parse_imports,
55
+ )
49
56
  from reflex.utils.serializers import serializer
50
- from reflex.vars import BaseVar, Var, VarData
57
+ from reflex.vars import Var, VarData
51
58
 
52
59
 
53
60
  class BaseComponent(Base, ABC):
@@ -170,7 +177,7 @@ class Component(BaseComponent, ABC):
170
177
  style: Style = Style()
171
178
 
172
179
  # A mapping from event triggers to event chains.
173
- event_triggers: Dict[str, Union[EventChain, Var]] = {}
180
+ event_triggers: Dict[str, Union[EventChain, ImmutableVar]] = {}
174
181
 
175
182
  # The alias for the tag.
176
183
  alias: Optional[str] = None
@@ -188,7 +195,7 @@ class Component(BaseComponent, ABC):
188
195
  class_name: Any = None
189
196
 
190
197
  # Special component props.
191
- special_props: Set[Var] = set()
198
+ special_props: Set[ImmutableVar] = set()
192
199
 
193
200
  # Whether the component should take the focus once the page is loaded
194
201
  autofocus: bool = False
@@ -206,7 +213,7 @@ class Component(BaseComponent, ABC):
206
213
  _rename_props: Dict[str, str] = {}
207
214
 
208
215
  # custom attribute
209
- custom_attrs: Dict[str, Union[Var, str]] = {}
216
+ custom_attrs: Dict[str, Union[ImmutableVar, str]] = {}
210
217
 
211
218
  # When to memoize this component and its children.
212
219
  _memoization_mode: MemoizationMode = MemoizationMode()
@@ -242,7 +249,7 @@ class Component(BaseComponent, ABC):
242
249
  """
243
250
  return {}
244
251
 
245
- def add_hooks(self) -> list[str | Var]:
252
+ def add_hooks(self) -> list[str | ImmutableVar]:
246
253
  """Add hooks inside the component function.
247
254
 
248
255
  Hooks are pieces of literal Javascript code that is inserted inside the
@@ -320,9 +327,8 @@ class Component(BaseComponent, ABC):
320
327
  # Set default values for any props.
321
328
  if types._issubclass(field.type_, Var):
322
329
  field.required = False
323
- field.default = Var.create(
324
- field.default, _var_is_string=isinstance(field.default, str)
325
- )
330
+ if field.default is not None:
331
+ field.default = LiteralVar.create(field.default)
326
332
  elif types._issubclass(field.type_, EventHandler):
327
333
  field.required = False
328
334
 
@@ -351,10 +357,7 @@ class Component(BaseComponent, ABC):
351
357
  "id": kwargs.get("id"),
352
358
  "children": children,
353
359
  **{
354
- prop: Var.create(
355
- kwargs[prop],
356
- _var_is_string=False if isinstance(kwargs[prop], str) else None,
357
- )
360
+ prop: LiteralVar.create(kwargs[prop])
358
361
  for prop in self.get_initial_props()
359
362
  if prop in kwargs
360
363
  },
@@ -401,10 +404,10 @@ class Component(BaseComponent, ABC):
401
404
  passed_types = None
402
405
  try:
403
406
  # Try to create a var from the value.
404
- kwargs[key] = Var.create(
405
- value,
406
- _var_is_string=False if isinstance(value, str) else None,
407
- )
407
+ if isinstance(value, ImmutableVar):
408
+ kwargs[key] = value
409
+ else:
410
+ kwargs[key] = LiteralVar.create(value)
408
411
 
409
412
  # Check that the var type is not None.
410
413
  if kwargs[key] is None:
@@ -444,11 +447,12 @@ class Component(BaseComponent, ABC):
444
447
  not passed_types
445
448
  and not types._issubclass(passed_type, expected_type, value)
446
449
  ):
447
- value_name = value._var_name if isinstance(value, Var) else value
450
+ value_name = (
451
+ value._var_name if isinstance(value, ImmutableVar) else value
452
+ )
448
453
  raise TypeError(
449
454
  f"Invalid var passed for prop {type(self).__name__}.{key}, expected type {expected_type}, got value {value_name} of type {passed_types or passed_type}."
450
455
  )
451
-
452
456
  # Check if the key is an event trigger.
453
457
  if key in component_specific_triggers:
454
458
  # Temporarily disable full control for event triggers.
@@ -497,7 +501,7 @@ class Component(BaseComponent, ABC):
497
501
  value: Union[
498
502
  Var, EventHandler, EventSpec, List[Union[EventHandler, EventSpec]], Callable
499
503
  ],
500
- ) -> Union[EventChain, Var]:
504
+ ) -> Union[EventChain, ImmutableVar]:
501
505
  """Create an event chain from a variety of input types.
502
506
 
503
507
  Args:
@@ -511,9 +515,11 @@ class Component(BaseComponent, ABC):
511
515
  ValueError: If the value is not a valid event chain.
512
516
  """
513
517
  # If it's an event chain var, return it.
514
- if isinstance(value, Var):
518
+ if isinstance(value, ImmutableVar):
515
519
  if value._var_type is not EventChain:
516
- raise ValueError(f"Invalid event chain: {value}")
520
+ raise ValueError(
521
+ f"Invalid event chain: {repr(value)} of type {type(value)}"
522
+ )
517
523
  return value
518
524
  elif isinstance(value, EventChain):
519
525
  # Trust that the caller knows what they're doing passing an EventChain directly
@@ -529,19 +535,11 @@ class Component(BaseComponent, ABC):
529
535
  for v in value:
530
536
  if isinstance(v, (EventHandler, EventSpec)):
531
537
  # Call the event handler to get the event.
532
- try:
533
- event = call_event_handler(v, args_spec)
534
- except ValueError as err:
535
- raise ValueError(
536
- f" {err} defined in the `{type(self).__name__}` component"
537
- ) from err
538
-
539
- # Add the event to the chain.
540
- events.append(event)
538
+ events.append(call_event_handler(v, args_spec))
541
539
  elif isinstance(v, Callable):
542
540
  # Call the lambda to get the event chain.
543
541
  result = call_event_fn(v, args_spec)
544
- if isinstance(result, Var):
542
+ if isinstance(result, ImmutableVar):
545
543
  raise ValueError(
546
544
  f"Invalid event chain: {v}. Cannot use a Var-returning "
547
545
  "lambda inside an EventChain list."
@@ -553,7 +551,7 @@ class Component(BaseComponent, ABC):
553
551
  # If the input is a callable, create an event chain.
554
552
  elif isinstance(value, Callable):
555
553
  result = call_event_fn(value, args_spec)
556
- if isinstance(result, Var):
554
+ if isinstance(result, ImmutableVar):
557
555
  # Recursively call this function if the lambda returned an EventChain Var.
558
556
  return self._create_event_chain(args_spec, result)
559
557
  events = result
@@ -571,7 +569,7 @@ class Component(BaseComponent, ABC):
571
569
  event_actions.update(e.event_actions)
572
570
 
573
571
  # Return the event chain.
574
- if isinstance(args_spec, Var):
572
+ if isinstance(args_spec, ImmutableVar):
575
573
  return EventChain(
576
574
  events=events,
577
575
  args_spec=None,
@@ -638,27 +636,6 @@ class Component(BaseComponent, ABC):
638
636
 
639
637
  return _compile_component(self)
640
638
 
641
- def _apply_theme(self, theme: Optional[Component]):
642
- """Apply the theme to this component.
643
-
644
- Deprecated. Use add_style instead.
645
-
646
- Args:
647
- theme: The theme to apply.
648
- """
649
- pass
650
-
651
- def apply_theme(self, theme: Optional[Component]):
652
- """Apply a theme to the component and its children.
653
-
654
- Args:
655
- theme: The theme to apply.
656
- """
657
- self._apply_theme(theme)
658
- for child in self.children:
659
- if isinstance(child, Component):
660
- child.apply_theme(theme)
661
-
662
639
  def _exclude_props(self) -> list[str]:
663
640
  """Props to exclude when adding the component props to the Tag.
664
641
 
@@ -692,9 +669,7 @@ class Component(BaseComponent, ABC):
692
669
  # Add ref to element if `id` is not None.
693
670
  ref = self.get_ref()
694
671
  if ref is not None:
695
- props["ref"] = Var.create(
696
- ref, _var_is_local=False, _var_is_string=False
697
- )
672
+ props["ref"] = ImmutableVar.create(ref)
698
673
  else:
699
674
  props = props.copy()
700
675
 
@@ -768,22 +743,6 @@ class Component(BaseComponent, ABC):
768
743
  from reflex.components.base.fragment import Fragment
769
744
  from reflex.utils.exceptions import ComponentTypeError
770
745
 
771
- # Translate deprecated props to new names.
772
- new_prop_names = [
773
- prop for prop in cls.get_props() if prop in ["type", "min", "max"]
774
- ]
775
- for prop in new_prop_names:
776
- under_prop = f"{prop}_"
777
- if under_prop in props:
778
- console.deprecate(
779
- f"Underscore suffix for prop `{under_prop}`",
780
- reason=f"for consistency. Use `{prop}` instead.",
781
- deprecation_version="0.4.0",
782
- removal_version="0.6.0",
783
- dedupe=False,
784
- )
785
- props[prop] = props.pop(under_prop)
786
-
787
746
  # Filter out None props
788
747
  props = {key: value for key, value in props.items() if value is not None}
789
748
 
@@ -809,7 +768,7 @@ class Component(BaseComponent, ABC):
809
768
  else (
810
769
  Fragment.create(*child)
811
770
  if isinstance(child, tuple)
812
- else Bare.create(contents=Var.create(child, _var_is_string=True))
771
+ else Bare.create(contents=LiteralVar.create(child))
813
772
  )
814
773
  )
815
774
  for child in children
@@ -900,17 +859,6 @@ class Component(BaseComponent, ABC):
900
859
  new_style.update(component_style)
901
860
  style_vars.append(component_style._var_data)
902
861
 
903
- # 3. User-defined style from `Component.style`.
904
- # Apply theme for retro-compatibility with deprecated _apply_theme API
905
- if type(self)._apply_theme != Component._apply_theme:
906
- console.deprecate(
907
- f"{self.__class__.__name__}._apply_theme",
908
- reason="use add_style instead",
909
- deprecation_version="0.5.0",
910
- removal_version="0.6.0",
911
- )
912
- self._apply_theme(theme)
913
-
914
862
  # 4. style dict and css props passed to the component instance.
915
863
  new_style.update(self.style)
916
864
  style_vars.append(self.style._var_data)
@@ -934,9 +882,14 @@ class Component(BaseComponent, ABC):
934
882
  Returns:
935
883
  The dictionary of the component style as value and the style notation as key.
936
884
  """
937
- if isinstance(self.style, Var):
885
+ if isinstance(self.style, ImmutableVar):
938
886
  return {"css": self.style}
939
- return {"css": Var.create(format_as_emotion(self.style))}
887
+ emotion_style = format_as_emotion(self.style)
888
+ return (
889
+ {"css": LiteralVar.create(emotion_style)}
890
+ if emotion_style is not None
891
+ else {}
892
+ )
940
893
 
941
894
  def render(self) -> Dict:
942
895
  """Render the component.
@@ -1045,8 +998,8 @@ class Component(BaseComponent, ABC):
1045
998
 
1046
999
  @staticmethod
1047
1000
  def _get_vars_from_event_triggers(
1048
- event_triggers: dict[str, EventChain | Var],
1049
- ) -> Iterator[tuple[str, list[Var]]]:
1001
+ event_triggers: dict[str, EventChain | ImmutableVar],
1002
+ ) -> Iterator[tuple[str, list[ImmutableVar]]]:
1050
1003
  """Get the Vars associated with each event trigger.
1051
1004
 
1052
1005
  Args:
@@ -1056,7 +1009,7 @@ class Component(BaseComponent, ABC):
1056
1009
  tuple of (event_name, event_vars)
1057
1010
  """
1058
1011
  for event_trigger, event in event_triggers.items():
1059
- if isinstance(event, Var):
1012
+ if isinstance(event, ImmutableVar):
1060
1013
  yield event_trigger, [event]
1061
1014
  elif isinstance(event, EventChain):
1062
1015
  event_args = []
@@ -1065,7 +1018,7 @@ class Component(BaseComponent, ABC):
1065
1018
  event_args.extend(args)
1066
1019
  yield event_trigger, event_args
1067
1020
 
1068
- def _get_vars(self, include_children: bool = False) -> list[Var]:
1021
+ def _get_vars(self, include_children: bool = False) -> list[ImmutableVar]:
1069
1022
  """Walk all Vars used in this component.
1070
1023
 
1071
1024
  Args:
@@ -1085,16 +1038,20 @@ class Component(BaseComponent, ABC):
1085
1038
  # Get Vars associated with component props.
1086
1039
  for prop in self.get_props():
1087
1040
  prop_var = getattr(self, prop)
1088
- if isinstance(prop_var, Var):
1041
+ if isinstance(prop_var, ImmutableVar):
1089
1042
  vars.append(prop_var)
1090
1043
 
1091
1044
  # Style keeps track of its own VarData instance, so embed in a temp Var that is yielded.
1092
- if isinstance(self.style, dict) and self.style or isinstance(self.style, Var):
1045
+ if (
1046
+ isinstance(self.style, dict)
1047
+ and self.style
1048
+ or isinstance(self.style, ImmutableVar)
1049
+ ):
1093
1050
  vars.append(
1094
- BaseVar(
1051
+ ImmutableVar(
1095
1052
  _var_name="style",
1096
1053
  _var_type=str,
1097
- _var_data=self.style._var_data,
1054
+ _var_data=VarData.merge(self.style._var_data),
1098
1055
  )
1099
1056
  )
1100
1057
 
@@ -1109,14 +1066,12 @@ class Component(BaseComponent, ABC):
1109
1066
  self.autofocus,
1110
1067
  *self.custom_attrs.values(),
1111
1068
  ):
1112
- if isinstance(comp_prop, Var):
1069
+ if isinstance(comp_prop, ImmutableVar):
1113
1070
  vars.append(comp_prop)
1114
1071
  elif isinstance(comp_prop, str):
1115
1072
  # Collapse VarData encoded in f-strings.
1116
- var = Var.create_safe(
1117
- comp_prop, _var_is_string=isinstance(comp_prop, str)
1118
- )
1119
- if var._var_data is not None:
1073
+ var = LiteralVar.create(comp_prop)
1074
+ if var._get_all_var_data() is not None:
1120
1075
  vars.append(var)
1121
1076
 
1122
1077
  # Get Vars associated with children.
@@ -1124,7 +1079,8 @@ class Component(BaseComponent, ABC):
1124
1079
  for child in self.children:
1125
1080
  if not isinstance(child, Component):
1126
1081
  continue
1127
- vars.extend(child._get_vars(include_children=include_children))
1082
+ child_vars = child._get_vars(include_children=include_children)
1083
+ vars.extend(child_vars)
1128
1084
 
1129
1085
  return vars
1130
1086
 
@@ -1139,7 +1095,7 @@ class Component(BaseComponent, ABC):
1139
1095
  for event in trigger.events:
1140
1096
  if event.handler.state_full_name:
1141
1097
  return True
1142
- elif isinstance(trigger, Var) and trigger._var_state:
1098
+ elif isinstance(trigger, ImmutableVar) and trigger._var_state:
1143
1099
  return True
1144
1100
  return False
1145
1101
 
@@ -1329,13 +1285,13 @@ class Component(BaseComponent, ABC):
1329
1285
 
1330
1286
  other_imports = []
1331
1287
  user_hooks = self._get_hooks()
1332
- if (
1333
- user_hooks is not None
1334
- and isinstance(user_hooks, Var)
1335
- and user_hooks._var_data is not None
1336
- and user_hooks._var_data.imports
1337
- ):
1338
- other_imports.append(user_hooks._var_data.imports)
1288
+ user_hooks_data = (
1289
+ VarData.merge(user_hooks._get_all_var_data())
1290
+ if user_hooks is not None and isinstance(user_hooks, ImmutableVar)
1291
+ else None
1292
+ )
1293
+ if user_hooks_data is not None:
1294
+ other_imports.append(user_hooks_data.imports)
1339
1295
  other_imports.extend(
1340
1296
  hook_imports for hook_imports in self._get_added_hooks().values()
1341
1297
  )
@@ -1358,9 +1314,16 @@ class Component(BaseComponent, ABC):
1358
1314
  event_imports = Imports.EVENTS if self.event_triggers else {}
1359
1315
 
1360
1316
  # Collect imports from Vars used directly by this component.
1361
- var_imports = [
1362
- var._var_data.imports for var in self._get_vars() if var._var_data
1363
- ]
1317
+ var_datas = [var._get_all_var_data() for var in self._get_vars()]
1318
+ var_imports: List[ImmutableParsedImportDict] = list(
1319
+ map(
1320
+ lambda var_data: var_data.imports,
1321
+ filter(
1322
+ None,
1323
+ var_datas,
1324
+ ),
1325
+ )
1326
+ )
1364
1327
 
1365
1328
  added_import_dicts: list[ParsedImportDict] = []
1366
1329
  for clz in self._iter_parent_classes_with_method("add_imports"):
@@ -1407,9 +1370,9 @@ class Component(BaseComponent, ABC):
1407
1370
  on_mount = self.event_triggers.get(EventTriggers.ON_MOUNT, None)
1408
1371
  on_unmount = self.event_triggers.get(EventTriggers.ON_UNMOUNT, None)
1409
1372
  if on_mount is not None:
1410
- on_mount = format.format_event_chain(on_mount)
1373
+ on_mount = str(LiteralVar.create(on_mount)) + "()"
1411
1374
  if on_unmount is not None:
1412
- on_unmount = format.format_event_chain(on_unmount)
1375
+ on_unmount = str(LiteralVar.create(on_unmount)) + "()"
1413
1376
  if on_mount is not None or on_unmount is not None:
1414
1377
  return f"""
1415
1378
  useEffect(() => {{
@@ -1427,7 +1390,7 @@ class Component(BaseComponent, ABC):
1427
1390
  """
1428
1391
  ref = self.get_ref()
1429
1392
  if ref is not None:
1430
- return f"const {ref} = useRef(null); {str(Var.create_safe(ref, _var_is_string=False).as_ref())} = {ref};"
1393
+ return f"const {ref} = useRef(null); {str(ImmutableVar.create_safe(ref).as_ref())} = {ref};"
1431
1394
 
1432
1395
  def _get_vars_hooks(self) -> dict[str, None]:
1433
1396
  """Get the hooks required by vars referenced in this component.
@@ -1437,8 +1400,13 @@ class Component(BaseComponent, ABC):
1437
1400
  """
1438
1401
  vars_hooks = {}
1439
1402
  for var in self._get_vars():
1440
- if var._var_data:
1441
- vars_hooks.update(var._var_data.hooks)
1403
+ var_data = var._get_all_var_data()
1404
+ if var_data is not None:
1405
+ vars_hooks.update(
1406
+ var_data.hooks
1407
+ if isinstance(var_data.hooks, dict)
1408
+ else {k: None for k in var_data.hooks}
1409
+ )
1442
1410
  return vars_hooks
1443
1411
 
1444
1412
  def _get_events_hooks(self) -> dict[str, None]:
@@ -1485,13 +1453,14 @@ class Component(BaseComponent, ABC):
1485
1453
  """
1486
1454
  code = {}
1487
1455
 
1488
- def extract_var_hooks(hook: Var):
1456
+ def extract_var_hooks(hook: ImmutableVar):
1489
1457
  _imports = {}
1490
- if hook._var_data is not None:
1491
- for sub_hook in hook._var_data.hooks:
1458
+ var_data = VarData.merge(hook._get_all_var_data())
1459
+ if var_data is not None:
1460
+ for sub_hook in var_data.hooks:
1492
1461
  code[sub_hook] = {}
1493
- if hook._var_data.imports:
1494
- _imports = hook._var_data.imports
1462
+ if var_data.imports:
1463
+ _imports = var_data.imports
1495
1464
  if str(hook) in code:
1496
1465
  code[str(hook)] = imports.merge_imports(code[str(hook)], _imports)
1497
1466
  else:
@@ -1501,10 +1470,11 @@ class Component(BaseComponent, ABC):
1501
1470
  # the order of the hooks in the final output)
1502
1471
  for clz in reversed(tuple(self._iter_parent_classes_with_method("add_hooks"))):
1503
1472
  for hook in clz.add_hooks(self):
1504
- if isinstance(hook, Var):
1473
+ if isinstance(hook, ImmutableVar):
1505
1474
  extract_var_hooks(hook)
1506
1475
  else:
1507
1476
  code[hook] = {}
1477
+
1508
1478
  return code
1509
1479
 
1510
1480
  def _get_hooks(self) -> str | None:
@@ -1561,7 +1531,7 @@ class Component(BaseComponent, ABC):
1561
1531
  The ref name.
1562
1532
  """
1563
1533
  # do not create a ref if the id is dynamic or unspecified
1564
- if self.id is None or isinstance(self.id, BaseVar):
1534
+ if self.id is None or isinstance(self.id, ImmutableVar):
1565
1535
  return None
1566
1536
  return format.format_ref(self.id)
1567
1537
 
@@ -1707,7 +1677,7 @@ class CustomComponent(Component):
1707
1677
 
1708
1678
  # Handle subclasses of Base.
1709
1679
  if isinstance(value, Base):
1710
- base_value = Var.create(value)
1680
+ base_value = LiteralVar.create(value)
1711
1681
 
1712
1682
  # Track hooks and imports associated with Component instances.
1713
1683
  if base_value is not None and isinstance(value, Component):
@@ -1721,7 +1691,7 @@ class CustomComponent(Component):
1721
1691
  else:
1722
1692
  value = base_value
1723
1693
  else:
1724
- value = Var.create(value, _var_is_string=isinstance(value, str))
1694
+ value = LiteralVar.create(value)
1725
1695
 
1726
1696
  # Set the prop.
1727
1697
  self.props[format.to_camel_case(key)] = value
@@ -1800,23 +1770,23 @@ class CustomComponent(Component):
1800
1770
  """
1801
1771
  return super()._render(props=self.props)
1802
1772
 
1803
- def get_prop_vars(self) -> List[BaseVar]:
1773
+ def get_prop_vars(self) -> List[ImmutableVar]:
1804
1774
  """Get the prop vars.
1805
1775
 
1806
1776
  Returns:
1807
1777
  The prop vars.
1808
1778
  """
1809
1779
  return [
1810
- BaseVar(
1780
+ ImmutableVar(
1811
1781
  _var_name=name,
1812
1782
  _var_type=(
1813
1783
  prop._var_type if types._isinstance(prop, Var) else type(prop)
1814
1784
  ),
1815
- )
1785
+ ).guess_type()
1816
1786
  for name, prop in self.props.items()
1817
1787
  ]
1818
1788
 
1819
- def _get_vars(self, include_children: bool = False) -> list[Var]:
1789
+ def _get_vars(self, include_children: bool = False) -> list[ImmutableVar]:
1820
1790
  """Walk all Vars used in this component.
1821
1791
 
1822
1792
  Args:
@@ -1825,9 +1795,11 @@ class CustomComponent(Component):
1825
1795
  Returns:
1826
1796
  Each var referenced by the component (props, styles, event handlers).
1827
1797
  """
1828
- return super()._get_vars(include_children=include_children) + [
1829
- prop for prop in self.props.values() if isinstance(prop, Var)
1830
- ]
1798
+ return (
1799
+ super()._get_vars(include_children=include_children)
1800
+ + [prop for prop in self.props.values() if isinstance(prop, ImmutableVar)]
1801
+ + self.get_component(self)._get_vars(include_children=include_children)
1802
+ )
1831
1803
 
1832
1804
  @lru_cache(maxsize=None) # noqa
1833
1805
  def get_component(self) -> Component:
@@ -1981,7 +1953,7 @@ class StatefulComponent(BaseComponent):
1981
1953
  if not should_memoize:
1982
1954
  # Determine if any Vars have associated data.
1983
1955
  for prop_var in component._get_vars():
1984
- if prop_var._var_data:
1956
+ if prop_var._get_all_var_data():
1985
1957
  should_memoize = True
1986
1958
  break
1987
1959
 
@@ -1996,7 +1968,7 @@ class StatefulComponent(BaseComponent):
1996
1968
  should_memoize = True
1997
1969
  break
1998
1970
  child = cls._child_var(child)
1999
- if isinstance(child, Var) and child._var_data:
1971
+ if isinstance(child, ImmutableVar) and child._get_all_var_data():
2000
1972
  should_memoize = True
2001
1973
  break
2002
1974
 
@@ -2152,7 +2124,7 @@ class StatefulComponent(BaseComponent):
2152
2124
  def _get_memoized_event_triggers(
2153
2125
  cls,
2154
2126
  component: Component,
2155
- ) -> dict[str, tuple[Var, str]]:
2127
+ ) -> dict[str, tuple[ImmutableVar, str]]:
2156
2128
  """Memoize event handler functions with useCallback to avoid unnecessary re-renders.
2157
2129
 
2158
2130
  Args:
@@ -2176,9 +2148,7 @@ class StatefulComponent(BaseComponent):
2176
2148
 
2177
2149
  # Get the actual EventSpec and render it.
2178
2150
  event = component.event_triggers[event_trigger]
2179
- rendered_chain = format.format_prop(event)
2180
- if isinstance(rendered_chain, str):
2181
- rendered_chain = rendered_chain.strip("{}")
2151
+ rendered_chain = str(LiteralVar.create(event))
2182
2152
 
2183
2153
  # Hash the rendered EventChain to get a deterministic function name.
2184
2154
  chain_hash = md5(str(rendered_chain).encode("utf-8")).hexdigest()
@@ -2187,12 +2157,13 @@ class StatefulComponent(BaseComponent):
2187
2157
  # Calculate Var dependencies accessed by the handler for useCallback dep array.
2188
2158
  var_deps = ["addEvents", "Event"]
2189
2159
  for arg in event_args:
2190
- if arg._var_data is None:
2160
+ var_data = arg._get_all_var_data()
2161
+ if var_data is None:
2191
2162
  continue
2192
- for hook in arg._var_data.hooks:
2163
+ for hook in var_data.hooks:
2193
2164
  var_deps.extend(cls._get_hook_deps(hook))
2194
2165
  memo_var_data = VarData.merge(
2195
- *[var._var_data for var in event_args],
2166
+ *[var._get_all_var_data() for var in event_args],
2196
2167
  VarData(
2197
2168
  imports={"react": [ImportVar(tag="useCallback")]},
2198
2169
  ),
@@ -2200,7 +2171,7 @@ class StatefulComponent(BaseComponent):
2200
2171
 
2201
2172
  # Store the memoized function name and hook code for this event trigger.
2202
2173
  trigger_memo[event_trigger] = (
2203
- Var.create_safe(memo_name, _var_is_string=False)._replace(
2174
+ ImmutableVar.create_safe(memo_name)._replace(
2204
2175
  _var_type=EventChain, merge_var_data=memo_var_data
2205
2176
  ),
2206
2177
  f"const {memo_name} = useCallback({rendered_chain}, [{', '.join(var_deps)}])",