This commit is contained in:
2025-09-20 09:48:06 +02:00
parent 2143074fde
commit fc9f982c96
13 changed files with 1943 additions and 17 deletions

View File

@@ -0,0 +1,72 @@
from typing import Optional
from nicegui import ui
class AutoScrollArea(ui.scroll_area):
"""A scroll area that automatically scrolls to bottom when new content is added
Features:
- Auto-scrolls to bottom when at bottom and new content arrives
- Stops auto-scroll when user scrolls up manually
- Resumes auto-scroll when user scrolls back to bottom
"""
_auto_scroll_enabled: bool = True
_auto_scroll_timer: Optional[ui.timer] = None
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Set up scroll monitoring
# self._handle_scroll
self.on_scroll(self._handle_scroll_event)
self.on('wheel', self._handle_wheel, ['deltaY'])
# Create timer for auto-scrolling
self._auto_scroll_timer = ui.timer(0.1, lambda: self.scroll_to(percent=1))
self._auto_scroll_timer.activate()
def _scroll_event_test(self, e):
print(e.vertical_percentage)
def _handle_scroll_event(self, event_data):
"""Handle scroll events to detect when user is at bottom"""
if not self._auto_scroll_timer:
print('no timer instantiated.')
return
# If scrolled to bottom (100%), enable auto-scroll
if event_data.vertical_percentage > 0.99: # Using 0.99 for some tolerance
if not self._auto_scroll_timer.active:
self._auto_scroll_timer.activate()
def _handle_wheel(self, event_data):
"""Handle mouse wheel events to detect manual scrolling"""
delta_y = event_data.args['deltaY']
if not self._auto_scroll_timer:
print('no timer instantiated.')
return
# If scrolling up (negative delta), disable auto-scroll
if delta_y < 0:
if self._auto_scroll_timer.active:
self._auto_scroll_timer.deactivate()
def enable_auto_scroll(self):
"""Manually enable auto-scrolling"""
if self._auto_scroll_timer:
if not self._auto_scroll_timer.active:
self._auto_scroll_timer.activate()
def disable_auto_scroll(self):
"""Manually disable auto-scrolling"""
if self._auto_scroll_timer:
if self._auto_scroll_timer.active:
self._auto_scroll_timer.deactivate()
def cleanup(self):
"""Clean up timer when component is destroyed"""
if self._auto_scroll_timer:
self._auto_scroll_timer.deactivate()
self._auto_scroll_timer = None