352 lines
7.8 KiB
Python
352 lines
7.8 KiB
Python
"""Import all classes and functions the end user will need to make an app.
|
|
|
|
Anything imported here will be available in the default Reflex import as `rx.*`.
|
|
To signal to typecheckers that something should be reexported,
|
|
we use the Flask "import name as name" syntax.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import importlib
|
|
from typing import Type
|
|
|
|
from reflex.page import page as page
|
|
from reflex.utils import console
|
|
from reflex.utils.format import to_snake_case
|
|
|
|
_ALL_COMPONENTS = [
|
|
"Accordion",
|
|
"AccordionButton",
|
|
"AccordionIcon",
|
|
"AccordionItem",
|
|
"AccordionPanel",
|
|
"Alert",
|
|
"AlertDescription",
|
|
"AlertDialog",
|
|
"AlertDialogBody",
|
|
"AlertDialogContent",
|
|
"AlertDialogFooter",
|
|
"AlertDialogHeader",
|
|
"AlertDialogOverlay",
|
|
"AlertIcon",
|
|
"AlertTitle",
|
|
"AspectRatio",
|
|
"Audio",
|
|
"Avatar",
|
|
"AvatarBadge",
|
|
"AvatarGroup",
|
|
"Badge",
|
|
"Box",
|
|
"Breadcrumb",
|
|
"BreadcrumbItem",
|
|
"BreadcrumbLink",
|
|
"BreadcrumbSeparator",
|
|
"Button",
|
|
"ButtonGroup",
|
|
"Card",
|
|
"CardBody",
|
|
"CardFooter",
|
|
"CardHeader",
|
|
"Center",
|
|
"Checkbox",
|
|
"CheckboxGroup",
|
|
"CircularProgress",
|
|
"CircularProgressLabel",
|
|
"Circle",
|
|
"Code",
|
|
"CodeBlock",
|
|
"Collapse",
|
|
"ColorModeButton",
|
|
"ColorModeIcon",
|
|
"ColorModeSwitch",
|
|
"Component",
|
|
"Cond",
|
|
"ConnectionBanner",
|
|
"ConnectionModal",
|
|
"Container",
|
|
"DataTable",
|
|
"DataEditor",
|
|
"DataEditorTheme",
|
|
"DatePicker",
|
|
"DateTimePicker",
|
|
"DebounceInput",
|
|
"Divider",
|
|
"Drawer",
|
|
"DrawerBody",
|
|
"DrawerCloseButton",
|
|
"DrawerContent",
|
|
"DrawerFooter",
|
|
"DrawerHeader",
|
|
"DrawerOverlay",
|
|
"Editable",
|
|
"EditableInput",
|
|
"EditablePreview",
|
|
"EditableTextarea",
|
|
"Editor",
|
|
"Email",
|
|
"Fade",
|
|
"Flex",
|
|
"Foreach",
|
|
"Form",
|
|
"FormControl",
|
|
"FormErrorMessage",
|
|
"FormHelperText",
|
|
"FormLabel",
|
|
"Fragment",
|
|
"Grid",
|
|
"GridItem",
|
|
"Heading",
|
|
"Highlight",
|
|
"Hstack",
|
|
"Html",
|
|
"Icon",
|
|
"IconButton",
|
|
"Image",
|
|
"Input",
|
|
"InputGroup",
|
|
"InputLeftAddon",
|
|
"InputLeftElement",
|
|
"InputRightAddon",
|
|
"InputRightElement",
|
|
"Kbd",
|
|
"Link",
|
|
"LinkBox",
|
|
"LinkOverlay",
|
|
"List",
|
|
"ListItem",
|
|
"Markdown",
|
|
"Menu",
|
|
"MenuButton",
|
|
"MenuDivider",
|
|
"MenuGroup",
|
|
"MenuItem",
|
|
"MenuItemOption",
|
|
"MenuList",
|
|
"MenuOptionGroup",
|
|
"Modal",
|
|
"ModalBody",
|
|
"ModalCloseButton",
|
|
"ModalContent",
|
|
"ModalFooter",
|
|
"ModalHeader",
|
|
"ModalOverlay",
|
|
"Moment",
|
|
"MultiSelect",
|
|
"MultiSelectOption",
|
|
"NextLink",
|
|
"NumberDecrementStepper",
|
|
"NumberIncrementStepper",
|
|
"NumberInput",
|
|
"NumberInputField",
|
|
"NumberInputStepper",
|
|
"Option",
|
|
"OrderedList",
|
|
"Password",
|
|
"PinInput",
|
|
"PinInputField",
|
|
"Plotly",
|
|
"Popover",
|
|
"PopoverAnchor",
|
|
"PopoverArrow",
|
|
"PopoverBody",
|
|
"PopoverCloseButton",
|
|
"PopoverContent",
|
|
"PopoverFooter",
|
|
"PopoverHeader",
|
|
"PopoverTrigger",
|
|
"Progress",
|
|
"Radio",
|
|
"RadioGroup",
|
|
"RangeSlider",
|
|
"RangeSliderFilledTrack",
|
|
"RangeSliderThumb",
|
|
"RangeSliderTrack",
|
|
"ResponsiveGrid",
|
|
"ScaleFade",
|
|
"Script",
|
|
"Select",
|
|
"Skeleton",
|
|
"SkeletonCircle",
|
|
"SkeletonText",
|
|
"Slide",
|
|
"SlideFade",
|
|
"Slider",
|
|
"SliderFilledTrack",
|
|
"SliderMark",
|
|
"SliderThumb",
|
|
"SliderTrack",
|
|
"Spacer",
|
|
"Span",
|
|
"Spinner",
|
|
"Square",
|
|
"Stack",
|
|
"Stat",
|
|
"StatArrow",
|
|
"StatGroup",
|
|
"StatHelpText",
|
|
"StatLabel",
|
|
"StatNumber",
|
|
"Step",
|
|
"StepDescription",
|
|
"StepIcon",
|
|
"StepIndicator",
|
|
"StepNumber",
|
|
"StepSeparator",
|
|
"StepStatus",
|
|
"StepTitle",
|
|
"Stepper",
|
|
"Switch",
|
|
"Tab",
|
|
"TabList",
|
|
"TabPanel",
|
|
"TabPanels",
|
|
"Table",
|
|
"TableCaption",
|
|
"TableContainer",
|
|
"Tabs",
|
|
"Tag",
|
|
"TagCloseButton",
|
|
"TagLabel",
|
|
"TagLeftIcon",
|
|
"TagRightIcon",
|
|
"Tbody",
|
|
"Td",
|
|
"Text",
|
|
"TextArea",
|
|
"Tfoot",
|
|
"Th",
|
|
"Thead",
|
|
"TimePicker",
|
|
"Tooltip",
|
|
"Tr",
|
|
"UnorderedList",
|
|
"Upload",
|
|
"Video",
|
|
"VisuallyHidden",
|
|
"Vstack",
|
|
"Wrap",
|
|
"WrapItem",
|
|
]
|
|
|
|
_ALL_COMPONENTS += [to_snake_case(component) for component in _ALL_COMPONENTS]
|
|
_ALL_COMPONENTS += [
|
|
"cancel_upload",
|
|
"components",
|
|
"color_mode_cond",
|
|
"desktop_only",
|
|
"mobile_only",
|
|
"tablet_only",
|
|
"mobile_and_tablet",
|
|
"tablet_and_desktop",
|
|
"selected_files",
|
|
"clear_selected_files",
|
|
"EditorButtonList",
|
|
"EditorOptions",
|
|
"NoSSRComponent",
|
|
]
|
|
|
|
_MAPPING = {
|
|
"reflex.admin": ["admin", "AdminDash"],
|
|
"reflex.app": ["app", "App", "UploadFile"],
|
|
"reflex.base": ["base", "Base"],
|
|
"reflex.compiler": ["compiler"],
|
|
"reflex.compiler.utils": ["get_asset_path"],
|
|
"reflex.components": _ALL_COMPONENTS + ["chakra", "next"],
|
|
"reflex.components.component": ["memo"],
|
|
"reflex.components.recharts": ["recharts"],
|
|
"reflex.components.moment.moment": ["MomentDelta"],
|
|
"reflex.config": ["config", "Config", "DBConfig"],
|
|
"reflex.constants": ["constants", "Env"],
|
|
"reflex.components.el": ["el"],
|
|
"reflex.event": [
|
|
"event",
|
|
"EventChain",
|
|
"background",
|
|
"call_script",
|
|
"clear_local_storage",
|
|
"console_log",
|
|
"download",
|
|
"prevent_default",
|
|
"redirect",
|
|
"remove_cookie",
|
|
"remove_local_storage",
|
|
"set_clipboard",
|
|
"set_focus",
|
|
"set_value",
|
|
"stop_propagation",
|
|
"upload_files",
|
|
"window_alert",
|
|
],
|
|
"reflex.middleware": ["middleware", "Middleware"],
|
|
"reflex.model": ["model", "session", "Model"],
|
|
"reflex.page": ["page"],
|
|
"reflex.route": ["route"],
|
|
"reflex.state": ["state", "var", "Cookie", "LocalStorage", "State"],
|
|
"reflex.style": ["style", "color_mode", "toggle_color_mode"],
|
|
"reflex.testing": ["testing"],
|
|
"reflex.utils": ["utils"],
|
|
"reflex.vars": ["vars", "cached_var", "Var"],
|
|
}
|
|
|
|
|
|
def _reverse_mapping(mapping: dict[str, list]) -> dict[str, str]:
|
|
"""Reverse the mapping used to lazy loading, and check for conflicting name.
|
|
|
|
Args:
|
|
mapping: The mapping to reverse.
|
|
|
|
Returns:
|
|
The reversed mapping.
|
|
"""
|
|
reversed_mapping = {}
|
|
for key, values in mapping.items():
|
|
for value in values:
|
|
if value not in reversed_mapping:
|
|
reversed_mapping[value] = key
|
|
else:
|
|
console.warn(
|
|
f"Key {value} is present multiple times in the imports _MAPPING: {key} / {reversed_mapping[value]}"
|
|
)
|
|
return reversed_mapping
|
|
|
|
|
|
# _MAPPING = {value: key for key, values in _MAPPING.items() for value in values}
|
|
_MAPPING = _reverse_mapping(_MAPPING)
|
|
|
|
|
|
def _removeprefix(text, prefix):
|
|
return text[text.startswith(prefix) and len(prefix) :]
|
|
|
|
|
|
__all__ = [_removeprefix(mod, "reflex.") for mod in _MAPPING]
|
|
|
|
|
|
def __getattr__(name: str) -> Type:
|
|
"""Lazy load all modules.
|
|
|
|
Args:
|
|
name: name of the module to load.
|
|
|
|
Returns:
|
|
The module or the attribute of the module.
|
|
|
|
Raises:
|
|
AttributeError: If the module or the attribute does not exist.
|
|
"""
|
|
try:
|
|
# Check for import of a module that is not in the mapping.
|
|
if name not in _MAPPING:
|
|
# If the name does not start with reflex, add it.
|
|
if not name.startswith("reflex") and name != "__all__":
|
|
name = f"reflex.{name}"
|
|
return importlib.import_module(name)
|
|
|
|
# Import the module.
|
|
module = importlib.import_module(_MAPPING[name])
|
|
|
|
# Get the attribute from the module if the name is not the module itself.
|
|
return (
|
|
getattr(module, name) if name != _MAPPING[name].rsplit(".")[-1] else module
|
|
)
|
|
except ModuleNotFoundError:
|
|
raise AttributeError(f"module 'reflex' has no attribute {name}") from None
|