1313 MemoizationLeaf ,
1414 StatefulComponent ,
1515)
16+ from reflex .components .core .cond import cond
1617from reflex .components .el .elements .forms import Input
1718from reflex .components .radix .themes .layout .box import Box
1819from reflex .config import environment
2829 parse_args_spec ,
2930 run_script ,
3031)
32+ from reflex .style import Style
3133from reflex .utils import format
3234from reflex .utils .imports import ImportVar
3335from reflex .vars import VarData
@@ -231,6 +233,9 @@ class Upload(MemoizationLeaf):
231233 # Fired when files are dropped.
232234 on_drop : EventHandler [_on_drop_spec ]
233235
236+ # Style rules to apply when actively dragging.
237+ drag_active_style : Style | None = None
238+
234239 @classmethod
235240 def create (cls , * children , ** props ) -> Component :
236241 """Create an upload component.
@@ -266,25 +271,46 @@ def create(cls, *children, **props) -> Component:
266271 # If on_drop is not provided, save files to be uploaded later.
267272 upload_props ["on_drop" ] = upload_file (upload_props ["id" ])
268273 else :
269- on_drop = upload_props ["on_drop" ]
270- if isinstance (on_drop , (EventHandler , EventSpec )):
271- # Call the lambda to get the event chain.
272- on_drop = call_event_handler (on_drop , _on_drop_spec )
273- elif isinstance (on_drop , Callable ):
274- # Call the lambda to get the event chain.
275- on_drop = call_event_fn (on_drop , _on_drop_spec )
276- if isinstance (on_drop , EventSpec ):
277- # Update the provided args for direct use with on_drop.
278- on_drop = on_drop .with_args (
279- args = tuple (
280- cls ._update_arg_tuple_for_on_drop (arg_value )
281- for arg_value in on_drop .args
282- ),
283- )
274+ on_drop = (
275+ [on_drop_prop ]
276+ if not isinstance (on_drop_prop := upload_props ["on_drop" ], Sequence )
277+ else list (on_drop_prop )
278+ )
279+ for ix , event in enumerate (on_drop ):
280+ if isinstance (event , (EventHandler , EventSpec )):
281+ # Call the lambda to get the event chain.
282+ event = call_event_handler (event , _on_drop_spec )
283+ elif isinstance (event , Callable ):
284+ # Call the lambda to get the event chain.
285+ event = call_event_fn (event , _on_drop_spec )
286+ if isinstance (event , EventSpec ):
287+ # Update the provided args for direct use with on_drop.
288+ event = event .with_args (
289+ args = tuple (
290+ cls ._update_arg_tuple_for_on_drop (arg_value )
291+ for arg_value in event .args
292+ ),
293+ )
294+ on_drop [ix ] = event
284295 upload_props ["on_drop" ] = on_drop
285296
286297 input_props_unique_name = get_unique_variable_name ()
287298 root_props_unique_name = get_unique_variable_name ()
299+ is_drag_active_unique_name = get_unique_variable_name ()
300+ drag_active_css_class_unique_name = get_unique_variable_name () + "-drag-active"
301+
302+ # Handle special style when dragging over the drop zone.
303+ if "drag_active_style" in props :
304+ props .setdefault ("style" , Style ())[
305+ f"&:where(.{ drag_active_css_class_unique_name } )"
306+ ] = props .pop ("drag_active_style" )
307+ props ["class_name" ].append (
308+ cond (
309+ Var (is_drag_active_unique_name ),
310+ drag_active_css_class_unique_name ,
311+ "" ,
312+ ),
313+ )
288314
289315 event_var , callback_str = StatefulComponent ._get_memoized_event_triggers (
290316 GhostUpload .create (on_drop = upload_props ["on_drop" ])
@@ -303,7 +329,13 @@ def create(cls, *children, **props) -> Component:
303329 }
304330 )
305331
306- left_side = f"const {{getRootProps: { root_props_unique_name } , getInputProps: { input_props_unique_name } }} "
332+ left_side = (
333+ "const { "
334+ f"getRootProps: { root_props_unique_name } , "
335+ f"getInputProps: { input_props_unique_name } , "
336+ f"isDragActive: { is_drag_active_unique_name } "
337+ "}"
338+ )
307339 right_side = f"useDropzone({ use_dropzone_arguments !s} )"
308340
309341 var_data = VarData .merge (
0 commit comments