@@ -206,6 +206,10 @@ class directly. Instead, supply the :func:`~shiny.ui.sidebar` object to
206206 and right, and the third will be bottom.
207207 * If four, then the values will be interpreted as top, right, bottom, and left
208208 respectively.
209+ fillable
210+ Whether or not the sidebar should be considered a fillable container.
211+ When `True`, the sidebar and its content can use `fill` to consume
212+ available vertical space.
209213
210214 Parameters
211215 ----------
@@ -283,6 +287,7 @@ def __init__(
283287 max_height_mobile : Optional [str | float ] = None ,
284288 gap : Optional [CssUnit ] = None ,
285289 padding : Optional [CssUnit | list [CssUnit ]] = None ,
290+ fillable : bool = False ,
286291 ):
287292 if isinstance (title , (str , int , float )):
288293 title = tags .header (str (title ), class_ = "sidebar-title" )
@@ -292,6 +297,7 @@ def __init__(
292297 self .class_ = class_
293298 self .gap = as_css_unit (gap )
294299 self .padding = as_css_padding (padding )
300+ self .fillable = fillable
295301 # User-provided initial open state
296302 self ._open : SidebarOpen | None = self ._as_open (open )
297303 # Shiny or consumer-provided default open state, change with `_set_default_open()`
@@ -403,29 +409,44 @@ def _sidebar_tag(self, id: str | None) -> Tag:
403409 self .open ().desktop == "closed" or self .open ().mobile == "closed"
404410 )
405411
406- return tags .aside (
412+ # Create the sidebar content div
413+ sidebar_content = div (
414+ {
415+ "class" : "sidebar-content bslib-gap-spacing" ,
416+ "style" : css (
417+ gap = self .gap ,
418+ padding = self .padding ,
419+ ),
420+ },
421+ self .title ,
422+ * self .children ,
423+ self .attrs ,
424+ )
425+
426+ # Apply fill_item to the content div if fillable
427+ if self .fillable :
428+ sidebar_content = as_fill_item (sidebar_content )
429+ sidebar_content = as_fillable_container (sidebar_content )
430+
431+ # Create the sidebar tag
432+ sidebar_tag = tags .aside (
407433 {
408434 "id" : id ,
409435 "class" : "sidebar" ,
410436 "hidden" : "true" if is_hidden_initially else None ,
411437 },
412438 # If the user provided an id, we make the sidebar an input to report state
413439 {"class" : "bslib-sidebar-input" } if self .id is not None else None ,
414- div (
415- {
416- "class" : "sidebar-content bslib-gap-spacing" ,
417- "style" : css (
418- gap = self .gap ,
419- padding = self .padding ,
420- ),
421- },
422- self .title ,
423- * self .children ,
424- self .attrs ,
425- ),
440+ sidebar_content ,
426441 class_ = self .class_ ,
427442 )
428443
444+ # Apply fillable container to the sidebar if needed
445+ if self .fillable :
446+ sidebar_tag = as_fillable_container (sidebar_tag )
447+
448+ return sidebar_tag
449+
429450 def tagify (self ) -> TagList :
430451 id = self ._get_sidebar_id ()
431452 taglist = TagList (self ._sidebar_tag (id ), self ._collapse_tag (id ))
@@ -446,6 +467,7 @@ def sidebar(
446467 max_height_mobile : Optional [str | float ] = None ,
447468 gap : Optional [CssUnit ] = None ,
448469 padding : Optional [CssUnit | list [CssUnit ]] = None ,
470+ fillable : bool = False ,
449471 ** kwargs : TagAttrValue ,
450472) -> Sidebar :
451473 # See [this article](https://rstudio.github.io/bslib/articles/sidebars.html)
@@ -521,6 +543,10 @@ def sidebar(
521543 and right, and the third will be bottom.
522544 * If four, then the values will be interpreted as top, right, bottom, and left
523545 respectively.
546+ fillable
547+ Whether or not the sidebar should be considered a fillable container.
548+ When `True`, the sidebar and its content can use `fill` to consume
549+ available vertical space.
524550 **kwargs
525551 Named attributes are supplied to the sidebar content container.
526552
@@ -567,6 +593,7 @@ def sidebar(
567593 max_height_mobile = max_height_mobile ,
568594 gap = gap ,
569595 padding = padding ,
596+ fillable = fillable ,
570597 )
571598
572599
0 commit comments