1
0
Эх сурвалжийг харах

Merge pull request #1329 from zauberzeug/scroll-padding

Synchronize scroll padding with header height
Rodja Trappe 1 жил өмнө
parent
commit
55be1b403b

+ 17 - 1
nicegui/page_layout.py

@@ -3,6 +3,7 @@ from typing import Literal, Optional
 from . import globals
 from .element import Element
 from .elements.mixins.value_element import ValueElement
+from .functions.html import add_body_html
 
 DrawerSides = Literal['left', 'right']
 
@@ -24,7 +25,9 @@ class Header(ValueElement):
                  value: bool = True,
                  fixed: bool = True,
                  bordered: bool = False,
-                 elevated: bool = False) -> None:
+                 elevated: bool = False,
+                 add_scroll_padding: bool = False,  # DEPRECATED: will be True in v1.4
+                 ) -> None:
         '''Header
 
         Note: The header is automatically placed above other layout elements in the DOM to improve accessibility.
@@ -34,6 +37,7 @@ class Header(ValueElement):
         :param fixed: whether the header should be fixed to the top of the page (default: `True`)
         :param bordered: whether the header should have a border (default: `False`)
         :param elevated: whether the header should have a shadow (default: `False`)
+        :param add_scroll_padding: whether to automatically prevent link targets from being hidden behind the header (default: `False`, will be `True` in v1.4)
         '''
         with globals.get_client().layout:
             super().__init__(tag='q-header', value=value, on_value_change=None)
@@ -46,6 +50,18 @@ class Header(ValueElement):
 
         self.move(target_index=0)
 
+        if add_scroll_padding:
+            add_body_html(f'''
+                <script>
+                    window.onload = () => {{
+                        const header = getElement({self.id}).$el;
+                        new ResizeObserver(() => {{
+                            document.documentElement.style.scrollPaddingTop = `${{header.offsetHeight}}px`;
+                        }}).observe(header);
+                    }};
+                </script>
+            ''')
+
     def toggle(self):
         '''Toggle the header'''
         self.value = not self.value

+ 23 - 0
tests/test_header.py

@@ -0,0 +1,23 @@
+import pytest
+
+from nicegui import ui
+
+from .screen import Screen
+
+
+@pytest.mark.parametrize('add_scroll_padding', [True, False])
+def test_no_scroll_padding(screen: Screen, add_scroll_padding: bool):
+    ui.header(add_scroll_padding=add_scroll_padding).classes('h-[50px]')
+    for i in range(100):
+        with ui.link_target(f'line{i}'):
+            ui.link(f'Line {i}', f'#line{i}')
+
+    screen.open('/')
+    screen.should_contain('Line 0')
+    screen.click('Line 10')
+    screen.wait(0.5)
+    line_y = screen.selenium.execute_script("return arguments[0].getBoundingClientRect()['y'];", screen.find('Line 10'))
+    if add_scroll_padding:
+        assert line_y > 50
+    else:
+        assert line_y < 50