123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- """Compiler variables."""
- import dataclasses
- import enum
- from enum import Enum
- from types import SimpleNamespace
- from reflex.constants import Dirs
- from reflex.utils.imports import ImportVar
- # The prefix used to create setters for state vars.
- SETTER_PREFIX = "set_"
- # The file used to specify no compilation.
- NOCOMPILE_FILE = "nocompile"
- class Ext(SimpleNamespace):
- """Extension used in Reflex."""
- # The extension for JS files.
- JS = ".js"
- # The extension for python files.
- PY = ".py"
- # The extension for css files.
- CSS = ".css"
- # The extension for zip files.
- ZIP = ".zip"
- # The extension for executable files on Windows.
- EXE = ".exe"
- # The extension for markdown files.
- MD = ".md"
- class CompileVars(SimpleNamespace):
- """The variables used during compilation."""
- # The expected variable name where the rx.App is stored.
- APP = "app"
- # The expected variable name where the API object is stored for deployment.
- API = "api"
- # The name of the router variable.
- ROUTER = "router"
- # The name of the socket variable.
- SOCKET = "socket"
- # The name of the variable to hold API results.
- RESULT = "result"
- # The name of the final variable.
- FINAL = "final"
- # The name of the process variable.
- PROCESSING = "processing"
- # The name of the state variable.
- STATE = "state"
- # The name of the events variable.
- EVENTS = "events"
- # The name of the initial hydrate event.
- HYDRATE = "hydrate"
- # The name of the is_hydrated variable.
- IS_HYDRATED = "is_hydrated"
- # The name of the function to add events to the queue.
- ADD_EVENTS = "addEvents"
- # The name of the var storing any connection error.
- CONNECT_ERROR = "connectErrors"
- # The name of the function for converting a dict to an event.
- TO_EVENT = "Event"
- # The name of the internal on_load event.
- ON_LOAD_INTERNAL = "reflex___state____on_load_internal_state.on_load_internal"
- # The name of the internal event to update generic state vars.
- UPDATE_VARS_INTERNAL = (
- "reflex___state____update_vars_internal_state.update_vars_internal"
- )
- # The name of the frontend event exception state
- FRONTEND_EXCEPTION_STATE = "reflex___state____frontend_event_exception_state"
- # The full name of the frontend exception state
- FRONTEND_EXCEPTION_STATE_FULL = (
- f"reflex___state____state.{FRONTEND_EXCEPTION_STATE}"
- )
- class PageNames(SimpleNamespace):
- """The name of basic pages deployed in NextJS."""
- # The name of the index page.
- INDEX_ROUTE = "index"
- # The name of the app root page.
- APP_ROOT = "_app"
- # The root stylesheet filename.
- STYLESHEET_ROOT = "__reflex_global_styles"
- # The name of the document root page.
- DOCUMENT_ROOT = "_document"
- # The name of the theme page.
- THEME = "theme"
- # The module containing components.
- COMPONENTS = "components"
- # The module containing shared stateful components
- STATEFUL_COMPONENTS = "stateful_components"
- class ComponentName(Enum):
- """Component names."""
- BACKEND = "Backend"
- FRONTEND = "Frontend"
- def zip(self):
- """Give the zip filename for the component.
- Returns:
- The lower-case filename with zip extension.
- """
- return self.value.lower() + Ext.ZIP
- class CompileContext(str, Enum):
- """The context in which the compiler is running."""
- RUN = "run"
- EXPORT = "export"
- DEPLOY = "deploy"
- UNDEFINED = "undefined"
- class Imports(SimpleNamespace):
- """Common sets of import vars."""
- EVENTS = {
- "react": [ImportVar(tag="useContext")],
- f"$/{Dirs.CONTEXTS_PATH}": [ImportVar(tag="EventLoopContext")],
- f"$/{Dirs.STATE_PATH}": [ImportVar(tag=CompileVars.TO_EVENT)],
- }
- class Hooks(SimpleNamespace):
- """Common sets of hook declarations."""
- EVENTS = f"const [{CompileVars.ADD_EVENTS}, {CompileVars.CONNECT_ERROR}] = useContext(EventLoopContext);"
- AUTOFOCUS = """
- // Set focus to the specified element.
- const focusRef = useRef(null)
- useEffect(() => {
- if (focusRef.current) {
- focusRef.current.focus();
- }
- })"""
- class HookPosition(enum.Enum):
- """The position of the hook in the component."""
- INTERNAL = "internal"
- PRE_TRIGGER = "pre_trigger"
- POST_TRIGGER = "post_trigger"
- class MemoizationDisposition(enum.Enum):
- """The conditions under which a component should be memoized."""
- # If the component uses state or events, it should be memoized.
- STATEFUL = "stateful"
- ALWAYS = "always"
- NEVER = "never"
- @dataclasses.dataclass(frozen=True)
- class MemoizationMode:
- """The mode for memoizing a Component."""
- # The conditions under which the component should be memoized.
- disposition: MemoizationDisposition = MemoizationDisposition.STATEFUL
- # Whether children of this component should be memoized first.
- recursive: bool = True
- class SpecialAttributes(enum.Enum):
- """Special attributes for components.
- These are placed in custom_attrs and rendered as-is rather than converting
- to a style prop.
- """
- DATA_UNDERSCORE = "data_"
- DATA_DASH = "data-"
- ARIA_UNDERSCORE = "aria_"
- ARIA_DASH = "aria-"
- @classmethod
- def is_special(cls, attr: str) -> bool:
- """Check if the attribute is special.
- Args:
- attr: the attribute to check
- Returns:
- True if the attribute is special.
- """
- return any(attr.startswith(value.value) for value in cls)
|