5
5
from reflex .components .el .elements .typography import Div
6
6
from reflex .constants .compiler import MemoizationDisposition , MemoizationMode
7
7
from reflex .utils .imports import ImportDict
8
- from reflex .vars .base import Var
8
+ from reflex .vars .base import Var , get_unique_variable_name
9
9
10
10
11
11
class AutoScroll (Div ):
@@ -25,9 +25,8 @@ def create(cls, *children, **props):
25
25
An AutoScroll component.
26
26
"""
27
27
props .setdefault ("overflow" , "auto" )
28
- custom_attrs = props .pop ("custom_attrs" , {})
29
- custom_attrs ["ref" ] = Var ("containerRef" )
30
- return super ().create (* children , ** props , custom_attrs = custom_attrs )
28
+ props .setdefault ("id" , get_unique_variable_name ())
29
+ return super ().create (* children , ** props )
31
30
32
31
def add_imports (self ) -> ImportDict | list [ImportDict ]:
33
32
"""Add imports required for the component.
@@ -43,15 +42,16 @@ def add_hooks(self) -> list[str | Var]:
43
42
Returns:
44
43
The hooks required for the component.
45
44
"""
45
+ ref_name = self .get_ref ()
46
46
return [
47
47
"const containerRef = useRef(null);" ,
48
48
"const wasNearBottom = useRef(false);" ,
49
49
"const hadScrollbar = useRef(false);" ,
50
- """
51
- const checkIfNearBottom = () => {
52
- if (!containerRef .current) return;
50
+ f """
51
+ const checkIfNearBottom = () => {{
52
+ if (!{ ref_name } .current) return;
53
53
54
- const container = containerRef .current;
54
+ const container = { ref_name } .current;
55
55
const nearBottomThreshold = 50; // pixels from bottom to trigger auto-scroll
56
56
57
57
const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
@@ -60,34 +60,35 @@ def add_hooks(self) -> list[str | Var]:
60
60
61
61
// Track if container had a scrollbar
62
62
hadScrollbar.current = container.scrollHeight > container.clientHeight;
63
- };
63
+ }} ;
64
64
""" ,
65
- """
66
- const scrollToBottomIfNeeded = () => {
67
- if (!containerRef .current) return;
65
+ f """
66
+ const scrollToBottomIfNeeded = () => {{
67
+ if (!{ ref_name } .current) return;
68
68
69
- const container = containerRef .current;
69
+ const container = { ref_name } .current;
70
70
const hasScrollbarNow = container.scrollHeight > container.clientHeight;
71
71
72
72
// Scroll if:
73
73
// 1. User was near bottom, OR
74
74
// 2. Container didn't have scrollbar before but does now
75
- if (wasNearBottom.current || (!hadScrollbar.current && hasScrollbarNow)) {
75
+ if (wasNearBottom.current || (!hadScrollbar.current && hasScrollbarNow)) {{
76
76
container.scrollTop = container.scrollHeight;
77
- }
77
+ }}
78
78
79
79
// Update scrollbar state for next check
80
- hadScrollbar.current = hasScrollbarNow;};
80
+ hadScrollbar.current = hasScrollbarNow;
81
+ }};
81
82
""" ,
82
- """
83
- useEffect(() => {
84
- const container = containerRef .current;
83
+ f """
84
+ useEffect(() => { {
85
+ const container = { ref_name } .current;
85
86
if (!container) return;
86
87
87
88
// Create ResizeObserver to detect height changes
88
- const resizeObserver = new ResizeObserver(() => {
89
- scrollToBottomIfNeeded();
90
- });
89
+ const resizeObserver = new ResizeObserver(() => {{
90
+ scrollToBottomIfNeeded();
91
+ }} );
91
92
92
93
// Track scroll position before height changes
93
94
container.addEventListener('scroll', checkIfNearBottom);
@@ -98,11 +99,11 @@ def add_hooks(self) -> list[str | Var]:
98
99
// Observe container for size changes
99
100
resizeObserver.observe(container);
100
101
101
- return () => {
102
- container.removeEventListener('scroll', checkIfNearBottom);
103
- resizeObserver.disconnect();
104
- };
105
- });
102
+ return () => {{
103
+ container.removeEventListener('scroll', checkIfNearBottom);
104
+ resizeObserver.disconnect();
105
+ }} ;
106
+ } });
106
107
""" ,
107
108
]
108
109
0 commit comments