|
@@ -5,11 +5,17 @@ from __future__ import annotations
|
|
from pathlib import Path
|
|
from pathlib import Path
|
|
from typing import Any, Callable, ClassVar, Dict, List, Optional, Tuple
|
|
from typing import Any, Callable, ClassVar, Dict, List, Optional, Tuple
|
|
|
|
|
|
-from reflex.components.component import Component, ComponentNamespace, MemoizationLeaf
|
|
|
|
|
|
+from reflex.components.component import (
|
|
|
|
+ Component,
|
|
|
|
+ ComponentNamespace,
|
|
|
|
+ MemoizationLeaf,
|
|
|
|
+ StatefulComponent,
|
|
|
|
+)
|
|
from reflex.components.el.elements.forms import Input
|
|
from reflex.components.el.elements.forms import Input
|
|
from reflex.components.radix.themes.layout.box import Box
|
|
from reflex.components.radix.themes.layout.box import Box
|
|
from reflex.config import environment
|
|
from reflex.config import environment
|
|
from reflex.constants import Dirs
|
|
from reflex.constants import Dirs
|
|
|
|
+from reflex.constants.compiler import Imports
|
|
from reflex.event import (
|
|
from reflex.event import (
|
|
CallableEventSpec,
|
|
CallableEventSpec,
|
|
EventChain,
|
|
EventChain,
|
|
@@ -19,9 +25,10 @@ from reflex.event import (
|
|
call_script,
|
|
call_script,
|
|
parse_args_spec,
|
|
parse_args_spec,
|
|
)
|
|
)
|
|
|
|
+from reflex.utils import format
|
|
from reflex.utils.imports import ImportVar
|
|
from reflex.utils.imports import ImportVar
|
|
from reflex.vars import VarData
|
|
from reflex.vars import VarData
|
|
-from reflex.vars.base import CallableVar, LiteralVar, Var
|
|
|
|
|
|
+from reflex.vars.base import CallableVar, LiteralVar, Var, get_unique_variable_name
|
|
from reflex.vars.sequence import LiteralStringVar
|
|
from reflex.vars.sequence import LiteralStringVar
|
|
|
|
|
|
DEFAULT_UPLOAD_ID: str = "default"
|
|
DEFAULT_UPLOAD_ID: str = "default"
|
|
@@ -179,9 +186,7 @@ class Upload(MemoizationLeaf):
|
|
|
|
|
|
library = "react-dropzone@14.2.10"
|
|
library = "react-dropzone@14.2.10"
|
|
|
|
|
|
- tag = "ReactDropzone"
|
|
|
|
-
|
|
|
|
- is_default = True
|
|
|
|
|
|
+ tag = ""
|
|
|
|
|
|
# The list of accepted file types. This should be a dictionary of MIME types as keys and array of file formats as
|
|
# The list of accepted file types. This should be a dictionary of MIME types as keys and array of file formats as
|
|
# values.
|
|
# values.
|
|
@@ -201,7 +206,7 @@ class Upload(MemoizationLeaf):
|
|
min_size: Var[int]
|
|
min_size: Var[int]
|
|
|
|
|
|
# Whether to allow multiple files to be uploaded.
|
|
# Whether to allow multiple files to be uploaded.
|
|
- multiple: Var[bool] = True # type: ignore
|
|
|
|
|
|
+ multiple: Var[bool]
|
|
|
|
|
|
# Whether to disable click to upload.
|
|
# Whether to disable click to upload.
|
|
no_click: Var[bool]
|
|
no_click: Var[bool]
|
|
@@ -232,6 +237,8 @@ class Upload(MemoizationLeaf):
|
|
# Mark the Upload component as used in the app.
|
|
# Mark the Upload component as used in the app.
|
|
cls.is_used = True
|
|
cls.is_used = True
|
|
|
|
|
|
|
|
+ props.setdefault("multiple", True)
|
|
|
|
+
|
|
# Apply the default classname
|
|
# Apply the default classname
|
|
given_class_name = props.pop("class_name", [])
|
|
given_class_name = props.pop("class_name", [])
|
|
if isinstance(given_class_name, str):
|
|
if isinstance(given_class_name, str):
|
|
@@ -243,17 +250,6 @@ class Upload(MemoizationLeaf):
|
|
upload_props = {
|
|
upload_props = {
|
|
key: value for key, value in props.items() if key in supported_props
|
|
key: value for key, value in props.items() if key in supported_props
|
|
}
|
|
}
|
|
- # The file input to use.
|
|
|
|
- upload = Input.create(type="file")
|
|
|
|
- upload.special_props = [Var(_js_expr="{...getInputProps()}", _var_type=None)]
|
|
|
|
-
|
|
|
|
- # The dropzone to use.
|
|
|
|
- zone = Box.create(
|
|
|
|
- upload,
|
|
|
|
- *children,
|
|
|
|
- **{k: v for k, v in props.items() if k not in supported_props},
|
|
|
|
- )
|
|
|
|
- zone.special_props = [Var(_js_expr="{...getRootProps()}", _var_type=None)]
|
|
|
|
|
|
|
|
# Create the component.
|
|
# Create the component.
|
|
upload_props["id"] = props.get("id", DEFAULT_UPLOAD_ID)
|
|
upload_props["id"] = props.get("id", DEFAULT_UPLOAD_ID)
|
|
@@ -275,9 +271,74 @@ class Upload(MemoizationLeaf):
|
|
),
|
|
),
|
|
)
|
|
)
|
|
upload_props["on_drop"] = on_drop
|
|
upload_props["on_drop"] = on_drop
|
|
|
|
+
|
|
|
|
+ input_props_unique_name = get_unique_variable_name()
|
|
|
|
+ root_props_unique_name = get_unique_variable_name()
|
|
|
|
+
|
|
|
|
+ event_var, callback_str = StatefulComponent._get_memoized_event_triggers(
|
|
|
|
+ Box.create(on_click=upload_props["on_drop"]) # type: ignore
|
|
|
|
+ )["on_click"]
|
|
|
|
+
|
|
|
|
+ upload_props["on_drop"] = event_var
|
|
|
|
+
|
|
|
|
+ upload_props = {
|
|
|
|
+ format.to_camel_case(key): value for key, value in upload_props.items()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ use_dropzone_arguements = {
|
|
|
|
+ "onDrop": event_var,
|
|
|
|
+ **upload_props,
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ left_side = f"const {{getRootProps: {root_props_unique_name}, getInputProps: {input_props_unique_name}}} "
|
|
|
|
+ right_side = f"useDropzone({str(Var.create(use_dropzone_arguements))})"
|
|
|
|
+
|
|
|
|
+ var_data = VarData.merge(
|
|
|
|
+ VarData(
|
|
|
|
+ imports=Imports.EVENTS,
|
|
|
|
+ hooks={
|
|
|
|
+ "const [addEvents, connectError] = useContext(EventLoopContext);": None
|
|
|
|
+ },
|
|
|
|
+ ),
|
|
|
|
+ event_var._get_all_var_data(),
|
|
|
|
+ VarData(
|
|
|
|
+ hooks={
|
|
|
|
+ callback_str: None,
|
|
|
|
+ f"{left_side} = {right_side};": None,
|
|
|
|
+ },
|
|
|
|
+ imports={
|
|
|
|
+ "react-dropzone": "useDropzone",
|
|
|
|
+ **Imports.EVENTS,
|
|
|
|
+ },
|
|
|
|
+ ),
|
|
|
|
+ )
|
|
|
|
+
|
|
|
|
+ # The file input to use.
|
|
|
|
+ upload = Input.create(type="file")
|
|
|
|
+ upload.special_props = [
|
|
|
|
+ Var(
|
|
|
|
+ _js_expr=f"{{...{input_props_unique_name}()}}",
|
|
|
|
+ _var_type=None,
|
|
|
|
+ _var_data=var_data,
|
|
|
|
+ )
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ # The dropzone to use.
|
|
|
|
+ zone = Box.create(
|
|
|
|
+ upload,
|
|
|
|
+ *children,
|
|
|
|
+ **{k: v for k, v in props.items() if k not in supported_props},
|
|
|
|
+ )
|
|
|
|
+ zone.special_props = [
|
|
|
|
+ Var(
|
|
|
|
+ _js_expr=f"{{...{root_props_unique_name}()}}",
|
|
|
|
+ _var_type=None,
|
|
|
|
+ _var_data=var_data,
|
|
|
|
+ )
|
|
|
|
+ ]
|
|
|
|
+
|
|
return super().create(
|
|
return super().create(
|
|
zone,
|
|
zone,
|
|
- **upload_props,
|
|
|
|
)
|
|
)
|
|
|
|
|
|
@classmethod
|
|
@classmethod
|
|
@@ -295,11 +356,6 @@ class Upload(MemoizationLeaf):
|
|
return (arg_value[0], placeholder)
|
|
return (arg_value[0], placeholder)
|
|
return arg_value
|
|
return arg_value
|
|
|
|
|
|
- def _render(self):
|
|
|
|
- out = super()._render()
|
|
|
|
- out.args = ("getRootProps", "getInputProps")
|
|
|
|
- return out
|
|
|
|
-
|
|
|
|
@staticmethod
|
|
@staticmethod
|
|
def _get_app_wrap_components() -> dict[tuple[int, str], Component]:
|
|
def _get_app_wrap_components() -> dict[tuple[int, str], Component]:
|
|
return {
|
|
return {
|