script.py 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. """Next.js script wrappers and inline script functionality.
  2. https://nextjs.org/docs/app/api-reference/components/script
  3. """
  4. from __future__ import annotations
  5. from typing import Any, Union
  6. from reflex.components.component import Component
  7. from reflex.event import EventChain
  8. from reflex.utils import console
  9. from reflex.vars import BaseVar, Var
  10. class Script(Component):
  11. """Next.js script component.
  12. Note that this component differs from reflex.components.base.document.NextScript
  13. in that it is intended for use with custom and user-defined scripts.
  14. It also differs from reflex.components.base.link.ScriptTag, which is the plain
  15. HTML <script> tag which does not work when rendering a component.
  16. """
  17. library = "next/script"
  18. tag = "Script"
  19. is_default = True
  20. # Required unless inline script is used
  21. src: Var[str]
  22. # When the script will execute: afterInteractive | beforeInteractive | lazyOnload
  23. strategy: Var[str] = "afterInteractive" # type: ignore
  24. @classmethod
  25. def create(cls, *children, **props) -> Component:
  26. """Create an inline or user-defined script.
  27. If a string is provided as the first child, it will be rendered as an inline script
  28. otherwise the `src` prop must be provided.
  29. The following event triggers are provided:
  30. on_load: Execute code after the script has finished loading.
  31. on_ready: Execute code after the script has finished loading and every
  32. time the component is mounted.
  33. on_error: Execute code if the script fails to load.
  34. Args:
  35. *children: The children of the component.
  36. **props: The props of the component.
  37. Returns:
  38. The component.
  39. Raises:
  40. ValueError: when neither children nor `src` are specified.
  41. """
  42. if not children and not props.get("src"):
  43. raise ValueError("Must provide inline script or `src` prop.")
  44. return super().create(*children, **props)
  45. def get_event_triggers(self) -> dict[str, Union[Var, Any]]:
  46. """Get the event triggers for the component.
  47. Returns:
  48. The event triggers.
  49. """
  50. return {
  51. **super().get_event_triggers(),
  52. "on_load": lambda: [],
  53. "on_ready": lambda: [],
  54. "on_error": lambda: [],
  55. }
  56. def client_side(javascript_code) -> Var[EventChain]:
  57. """Create an event handler that executes arbitrary javascript code.
  58. The provided code will have access to `args`, which come from the event itself.
  59. The code may call functions or reference variables defined in a previously
  60. included rx.script function.
  61. Args:
  62. javascript_code: The code to execute.
  63. Returns:
  64. An EventChain, passable to any component, that will execute the client side javascript
  65. when triggered.
  66. """
  67. console.deprecate(
  68. feature_name="rx.client_side",
  69. reason="and has been replaced by rx.call_script, which can be used from backend EventHandler too",
  70. deprecation_version="0.2.9",
  71. removal_version="0.3.0",
  72. )
  73. return BaseVar(name=f"...args => {{{javascript_code}}}", type_=EventChain)