Skip to content

Commit

Permalink
Add scroll options to permanently toggle on scrollbar (#6266)
Browse files Browse the repository at this point in the history
  • Loading branch information
ahuang11 authored Feb 5, 2024
1 parent 4689f9f commit ed34b1c
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 23 deletions.
12 changes: 12 additions & 0 deletions panel/dist/css/listpanel.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@
overflow-x: auto;
}

:host(.scroll) {
overflow: scroll;
}

:host(.scroll-vertical) {
overflow-y: scroll;
}

:host(.scroll-horizontal) {
overflow-x: scroll;
}

.scroll-button {
/* For location */
position: sticky;
Expand Down
71 changes: 49 additions & 22 deletions panel/layout/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@

from ..viewable import Viewable

_SCROLL_MAPPING = {
'both-auto': 'scrollable',
'x-auto': 'scrollable-horizontal',
'y-auto': 'scrollable-vertical',
'both': 'scroll',
'x': 'scroll-horizontal',
'y': 'scroll-vertical',
}

_row = namedtuple("row", ["children"]) # type: ignore
_col = namedtuple("col", ["children"]) # type: ignore

Expand Down Expand Up @@ -787,9 +796,18 @@ class ListPanel(ListLike, Panel):
An abstract baseclass for Panel objects with list-like children.
"""

scroll = param.Boolean(default=False, doc="""
Whether to add scrollbars if the content overflows the size
of the container.""")
scroll = param.Selector(
default=False,
objects=[False, True, "both-auto", "y-auto", "x-auto", "both", "x", "y"],
doc="""Whether to add scrollbars if the content overflows the size
of the container. If "both-auto", will only add scrollbars if
the content overflows in either directions. If "x-auto" or "y-auto",
will only add scrollbars if the content overflows in the
respective direction. If "both", will always add scrollbars.
If "x" or "y", will always add scrollbars in the respective
direction. If False, overflowing content will be clipped.
If True, will only add scrollbars in the direction of the container,
(e.g. Column: vertical, Row: horizontal).""")

_rename: ClassVar[Mapping[str, str | None]] = {'scroll': None}

Expand Down Expand Up @@ -819,15 +837,15 @@ def _linked_properties(self):
)

def _process_param_change(self, params: Dict[str, Any]) -> Dict[str, Any]:
if 'scroll' in params:
scroll = params['scroll']
if (scroll := params.get('scroll')):
css_classes = params.get('css_classes', self.css_classes)
if scroll:
if self._direction is not None:
css_classes += [f'scrollable-{self._direction}']
else:
css_classes += ['scrollable']
params['css_classes'] = css_classes
if scroll in _SCROLL_MAPPING:
scroll_class = _SCROLL_MAPPING[scroll]
elif self._direction:
scroll_class = f'scrollable-{self._direction}'
else:
scroll_class = 'scrollable'
params['css_classes'] = css_classes + [scroll_class]
return super()._process_param_change(params)

def _cleanup(self, root: Model | None = None) -> None:
Expand All @@ -843,9 +861,18 @@ class NamedListPanel(NamedListLike, Panel):
active = param.Integer(default=0, bounds=(0, None), doc="""
Index of the currently displayed objects.""")

scroll = param.Boolean(default=False, doc="""
Whether to add scrollbars if the content overflows the size
of the container.""")
scroll = param.ObjectSelector(
default=False,
objects=[False, True, "both-auto", "y-auto", "x-auto", "both", "x", "y"],
doc="""Whether to add scrollbars if the content overflows the size
of the container. If "both-auto", will only add scrollbars if
the content overflows in either directions. If "x-auto" or "y-auto",
will only add scrollbars if the content overflows in the
respective direction. If "both", will always add scrollbars.
If "x" or "y", will always add scrollbars in the respective
direction. If False, overflowing content will be clipped.
If True, will only add scrollbars in the direction of the container,
(e.g. Column: vertical, Row: horizontal).""")

_rename: ClassVar[Mapping[str, str | None]] = {'scroll': None}

Expand All @@ -854,15 +881,15 @@ class NamedListPanel(NamedListLike, Panel):
__abstract = True

def _process_param_change(self, params: Dict[str, Any]) -> Dict[str, Any]:
if 'scroll' in params:
scroll = params['scroll']
if (scroll := params.get('scroll')):
css_classes = params.get('css_classes', self.css_classes)
if scroll:
if self._direction is not None:
css_classes += [f'scrollable-{self._direction}']
else:
css_classes += ['scrollable']
params['css_classes'] = css_classes
if scroll in _SCROLL_MAPPING:
scroll_class = _SCROLL_MAPPING[scroll]
elif self._direction:
scroll_class = f'scrollable-{self._direction}'
else:
scroll_class = 'scrollable'
params['css_classes'] = css_classes + [scroll_class]
return super()._process_param_change(params)

def _cleanup(self, root: Model | None = None) -> None:
Expand Down
21 changes: 20 additions & 1 deletion panel/tests/ui/layout/test_column.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

from playwright.sync_api import expect

from panel import Column, Spacer
from panel.layout.base import _SCROLL_MAPPING, Column
from panel.layout.spacer import Spacer
from panel.tests.util import serve_component, wait_until

pytestmark = pytest.mark.ui
Expand All @@ -27,6 +28,24 @@ def test_column_scroll(page):
expect(col_el).to_have_class('bk-panel-models-layout-Column scrollable-vertical')


@pytest.mark.parametrize('scroll', _SCROLL_MAPPING.keys())
def test_column_scroll_string(page, scroll):
col = Column(
Spacer(styles=dict(background='red'), width=200, height=200),
Spacer(styles=dict(background='green'), width=200, height=200),
Spacer(styles=dict(background='blue'), width=200, height=200),
scroll=scroll, height=420
)
serve_component(page, col)

col_el = page.locator(".bk-panel-models-layout-Column")
bbox = col_el.bounding_box()

assert bbox['width'] in (200, 215) # Ignore if browser hides empty scrollbar
assert bbox['height'] == 420
expect(col_el).to_have_class(f'bk-panel-models-layout-Column {_SCROLL_MAPPING[scroll]}')


def test_column_auto_scroll_limit(page):
col = Column(
Spacer(styles=dict(background='red'), width=200, height=200),
Expand Down

0 comments on commit ed34b1c

Please sign in to comment.