@@ -337,6 +337,41 @@ def format_output_html(entry):
337
337
"""
338
338
339
339
340
+ @solara .component
341
+ def ConsoleInput (on_submit ):
342
+ """A solara component for handling console input."""
343
+ input_text , set_input_text = solara .use_state ("" )
344
+
345
+ def handle_submit (* ignore_args ):
346
+ on_submit (input_text )
347
+ set_input_text ("" )
348
+
349
+ input_elem = solara .v .TextField (
350
+ v_model = input_text ,
351
+ on_v_model = set_input_text ,
352
+ flat = True ,
353
+ hide_details = True ,
354
+ dense = True ,
355
+ height = "auto" ,
356
+ background_color = "transparent" ,
357
+ style_ = "font-family: monospace; border: none; box-shadow: none; padding: 0; margin: 0; background-color: transparent; color: #000; flex-grow: 1;" ,
358
+ placeholder = "" ,
359
+ solo = False ,
360
+ filled = False ,
361
+ outlined = False ,
362
+ id = "console-input" ,
363
+ attributes = {
364
+ "spellcheck" : "false" ,
365
+ "autocomplete" : "off" ,
366
+ },
367
+ )
368
+
369
+ # Handle Enter key press
370
+ use_change (input_elem , handle_submit , update_events = ["keyup.enter" ])
371
+
372
+ return input_elem
373
+
374
+
340
375
@solara .component
341
376
def CommandConsole (model = None , additional_imports = None ):
342
377
"""A solara component for executing Python code interactively in the browser."""
@@ -347,10 +382,14 @@ def CommandConsole(model=None, additional_imports=None):
347
382
model = model , additional_imports = additional_imports
348
383
)
349
384
350
- input_text , set_input_text = solara . use_state ( "" )
351
- _ , set_refresh = solara .use_state (0 )
385
+ # State to trigger re-renders
386
+ refresh , set_refresh = solara .use_state (0 )
352
387
353
- with solara .lab .ChatBox (
388
+ def handle_code_execution (code ):
389
+ console_ref .current .execute_code (code , lambda _ : None )
390
+ set_refresh (refresh + 1 )
391
+
392
+ with solara .Column (
354
393
style = {
355
394
"height" : "300px" ,
356
395
"overflow-y" : "auto" ,
@@ -361,30 +400,24 @@ def CommandConsole(model=None, additional_imports=None):
361
400
"padding" : "8px" ,
362
401
}
363
402
):
364
- for entry in console_ref .current .get_entries ():
365
- command_html = format_command_html (entry )
366
- output_html = format_output_html (entry )
367
- solara .Markdown (command_html + output_html )
403
+ console_entries = console_ref .current .get_entries ()
404
+
405
+ # Display history entries with auto-scrolling
406
+ with solara .v .ScrollYTransition (group = True ):
407
+ for entry in console_entries :
408
+ with solara .Div ():
409
+ command_html = format_command_html (entry )
410
+ output_html = format_output_html (entry )
411
+ solara .Markdown (command_html + output_html )
412
+
413
+ # Input row that adapts to content above it
414
+ with solara .Row (
415
+ style = {"align-items" : "center" , "margin" : "0" , "width" : "94.5%" }
416
+ ):
417
+ solara .Text (">>> " , style = {"color" : "#0066cc" })
418
+ ConsoleInput (on_submit = handle_code_execution )
368
419
369
420
solara .Markdown (
370
421
"*Type 'tips' for usage instructions.*" ,
371
422
style = "font-size: 0.8em; color: #666;" ,
372
423
)
373
-
374
- input_elem = solara .v .TextField (
375
- v_model = input_text ,
376
- on_v_model = set_input_text ,
377
- flat = True ,
378
- style_ = "font-family: monospace;" ,
379
- label = ">>>" ,
380
- outlined = True ,
381
- placeholder = "Enter Python code..." ,
382
- attributes = {"spellcheck" : "false" },
383
- )
384
-
385
- def on_enter (* ignore_args ):
386
- console_ref .current .execute_code (input_text , set_input_text )
387
- set_refresh (lambda x : x + 1 )
388
-
389
- # Bind the enter key to execute the code
390
- use_change (input_elem , on_enter , update_events = ["keyup.enter" ])
0 commit comments